命名约定 - 在C ++和C#变量中使用下划线

时间:2010-06-28 22:26:26

标签: c# c++ naming-conventions

在类字段中看到_var变量名称很常见。下划线是什么意思?是否有所有这些特殊命名约定的参考?

19 个答案:

答案 0 :(得分:101)

下划线只是一个惯例;而已。因此,它的使用总是与每个人有所不同。以下是我对这两种语言的理解:

在C ++中,下划线通常表示私有成员变量。

在C#中,我经常看到它仅在为公共属性定义底层私有成员变量时使用。其他私有成员变量没有下划线。然而,随着自动属性的出现,这种用法已基本消失。

在:

private string _name;
public string Name
{
    get { return this._name; }
    set { this._name = value; }
}

后:

public string Name { get; set; }

答案 1 :(得分:59)

请不要在C ++中的任何变量名称或参数名称之前使用UNDERSCORES !!!

对于C ++实现者,保留以下划线或双下划线开头的名称。带有下划线的名称保留供库使用。

如果您已阅读C ++编码标准,您会在第一页中看到它:

  

“不要过度分割命名,但要使用一致的命名约定:只有两个必须符合:a)从不使用”卑鄙的名称“,以下划线开头或包含双下划线的名称;” (p2,C ++编码标准,Herb Sutter和Andrei Alexandrescu)

另外,您可以自己查看为什么在开发软件时使用下划线会造成灾难性的后果。

尝试编译一个简单的helloWorld.cpp程序,如下所示:

g++ -E helloWorld.cpp

你会看到后台发生的一切。这是一个片段:

   ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
   try
     {
       __streambuf_type* __sb = this->rdbuf();
       if (__sb)
  {
    if (__sb->pubsync() == -1)
      __err |= ios_base::badbit;
    else
      __ret = 0;
  }

你可以看到有多少名字以双下划线开头!

另外,如果查看虚拟成员函数,您将看到* _vptr是为虚拟表生成的指针,当您在类中使用一个或多个虚拟成员函数时,该指针会自动生成!但那是另一个故事......

如果您使用下划线,您可能会遇到冲突问题而且您将不会知道导致它的原因,直到为时已晚。

答案 2 :(得分:40)

实际上_var约定来自VB而不是C#或C ++(m _,......是另一回事)。

这是为了克服VB在声明Proprieties时的不区分性

例如,这样的代码在VB中是不可能的,因为它将userUser视为相同的标识符

Private user As String

Public Property User As String
  Get
    Return user
  End Get
  Set(ByVal Value As String)
    user = value
  End Set
End Property

所以为了克服这个问题,一些人使用了一个约定来将'_'添加到私有字段中,就像这样

Private _user As String

Public Property User As String
  Get
    Return _user
  End Get
  Set(ByVal Value As String)
    _user = value
  End Set
End Property

由于许多约定适用于.Net并且在C#和VB.NET约定之间保持一致,因此它们使用相同的。

我找到了我所说的参考资料: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

  

Camel Case与领先的下划线。在   VB.NET,总是表示“受保护”或   “私人”,不要使用“昏暗”。用于   不鼓励“m_”,因为使用a   变量名称不同于   只有案件的财产,特别是与   受保护的变量违反了   遵守,并将使你的生活   如果你在VB.NET中编程就像你一样痛苦   必须为你的会员命名   与...不同的东西   accessor / mutator属性。其中   这里的项目,领先的下划线   真的是唯一有争议的一个。   我个人比较喜欢它   对我而言,无下划线的骆驼案例   私有变量,所以我没有   使用“this”限定变量名称。   区分参数   建设者或其他地方我   可能会发生命名冲突。   对于VB.NET的不区分大小写,这个   更重要的是你的   访问者属性通常会有   与您的私人会员同名   变量除了下划线。   就m_而言,它确实是公正的   关于美学。我(以及其他许多人)   找到丑陋的,因为它看起来像那里   是变量名中的一个洞。它的   几乎令人反感。我以前用它   VB6一直都是,但那只是   因为变量不能有   领先的下划线。我不可能   看到它消失就更高兴了。微软   建议反对m_(和   直_)即使他们两个都做了   在他们的代码中。另外,前缀为   直“m”就出来了。当然,   因为他们主要用C#编码,所以他们可以   私人会员只有不同   如果是属性。 VB伙计们   必须做点别的事。而不是   试着想出来   语言特殊情况,我   推荐领先的下划线   所有支持它的语言。如果   我希望我的班级充分   符合CLS,我可以放弃   任何受C#保护的成员的前缀   变量。然而,在实践中,我   从不担心这一点,因为我保留了所有   可能受保护的成员变量   私人,供应受到保护   访问者和变异者。为什么:   简而言之,这个惯例是   简单(一个字符),易于阅读   (你的眼睛不会被其他人分心   领先的人物),并成功   避免命名冲突   程序级变量和   class-level properties.class-level properties。

答案 3 :(得分:5)

第一位评论者(R Samuel Klatchko)引用了What are the rules about using an underscore in a C++ identifier?来回答有关C ++中下划线的问题。通常,您不应该使用前导下划线,因为它是为编译器的实现者保留的。您使用_var看到的代码可能是遗留代码,也可能是由使用旧命名系统长大的人编写的代码,该系统在前导下划线上没有皱眉。

正如其他答案所述,它曾经在C ++中用于识别类成员变量。但是,就装饰器或语法而言,它没有特殊含义。因此,如果你想使用它,它将编译。

我会把C#讨论留给别人。

答案 4 :(得分:4)

_var没有任何意义,只是为了更容易区分变量是私有成员变量。

在C ++中,使用_var约定是不好的形式,因为有一些规则管理在标识符前面使用下划线。 _var保留为全局标识符,而_Var(下划线+大写字母)随时保留。这就是为什么在C ++中,你会看到人们使用var_约。

答案 5 :(得分:4)

您可以创建自己的编码指南。只需为团队的其他成员写一份清晰的文档。

使用_field帮助Intelilsense过滤所有类变量,只需输入_。

我通常关注Brad Adams Guidelines,但建议不要使用下划线。

答案 6 :(得分:2)

C#的Microsoft命名标准表示变量和参数应使用较低的驼峰形式 IE: paramName。该标准还要求字段遵循相同的形式,但这可能导致代码不清晰,因此许多团队要求使用下划线前缀来提高清晰度 IE: _fieldName

答案 7 :(得分:2)

使用C#,Microsoft Framework Design Guidelines建议不要对 public 成员使用下划线字符。对于私有成员,可以使用下划线。实际上,Jeffrey Richter(通常在指南中引用)例如使用m_和私有静态成员使用“s_”。

就个人而言,我只使用_来标记我的私人成员。 “m_”和“s_”接近匈牙利符号,这不仅在.NET中不受欢迎,而且可能非常冗长,而且我发现很多成员的类很难按字母顺序进行快速眼动扫描(想象10个变量都以m_开头)

答案 8 :(得分:1)

我将_var命名用于我的类的成员变量。我有两个主要原因:

1)当我稍后阅读我的代码时,它可以帮助我跟踪类变量和本地函数变量。

2)当我在寻找一个类变量时,它在Intellisense(或其他代码完成系统)中有所帮助。只知道第一个字符有助于过滤可用变量和方法列表。

答案 9 :(得分:1)

就C和C ++语言而言,名称中的下划线(开头,中间或结尾)没有特殊含义。它只是一个有效的变量名字符。 “惯例”来自编码社区内的编码实践。

正如上面各种例子所示,开头的_可能是指C ++中某个类的私有或受保护成员。

让我给出一些可能是有趣的琐事的历史。在UNIX中,如果您有一个核心C库函数和一个内核后端,您希望将内核函数暴露给用户空间,那么_会停留在函数存根之前,该函数存根直接调用内核函数而不执行任何其他操作。最着名和熟悉的例子是BSD和SysV类型内核下的exit()vs _exit():在那里,exit()在调用内核的退出服务之前做了用户空间的事情,而_exit只是映射到内核的退出服务。

所以_用于“本地”的东西,在这种情况下本地是机器本地的。通常_functions()不可移植。因此,您不应期望在各种平台上采用相同的行为。

现在_和变量名中的_,例如

int _foo;

在心理上,一个_是一个奇怪的事情,必须在开头输入。因此,如果你想创建一个与其他东西冲突的可能性较小的变量名,特别是在处理预处理器替换时,你需要考虑使用_。

我的基本建议是始终遵循编码社区的惯例,以便您可以更有效地进行协作。

答案 10 :(得分:0)

旧问题,新答案(C#)。

C#的下划线的另一种用法是与ASP NET Core的DI(依赖注入)一起使用。在构造期间分配给注入接口的类的私有readonly变量应以下划线开头。我想是否对课程的每个私有成员都使用下划线是一个辩论(尽管Microsoft本身也遵循),但这是肯定的。

private readonly ILogger<MyDependency> _logger;

public MyDependency(ILogger<MyDependency> logger)
{
    _logger = logger;
}

答案 11 :(得分:0)

现在,在this.foobarbaz中使用“this”的符号对于C#类成员变量是可接受的。它取代了旧的“m_”或只是“__”符号。它确实使代码更具可读性,因为毫无疑问正在引用什么。

答案 12 :(得分:0)

如果代码必须也可以从VB.NET扩展,那么

There is a fully legit reason to use it in C#:。 (否则,我不会。)

由于VB.NET不区分大小写,因此在此代码中没有简单的方法来访问受保护的field成员:

public class CSharpClass
{
    protected int field;
    public int Field { get { return field; } }
}

E.g。这将访问属性getter,而不是字段:

Public Class VBClass
    Inherits CSharpClass

    Function Test() As Integer
        Return Field
    End Function

End Class

哎呀,我甚至不能用小写字母写field - VS 2010只是不断纠正它。

为了使VB.NET中的派生类易于访问,必须提出另一种命名约定。前缀下划线可能是最不具侵入性和最“历史性接受”的。

答案 13 :(得分:0)

这只是一些程序员在操作类的成员或其他类型的变量(参数,函数的本地等)时使用的惯例。另一个广泛用于成员变量的约定是在名称前加上'm _'。

无论如何,这些只是约定,你不会找到所有这些的单一来源。他们是一个风格问题,每个编程团队,项目或公司都有自己的(甚至没有)。

答案 14 :(得分:0)

许多人喜欢私人字段以下划线为前缀。这只是一个命名惯例。

C#的'官方'命名约定规定了私有字段的简单小写名称(无下划线)。

我不知道C ++的标准约定,尽管下划线使用得非常广泛。

答案 15 :(得分:0)

根据我的经验(肯定是有限的),下划线将表明它是一个私有成员变量。正如Gollum所说,这将取决于球队。

答案 16 :(得分:0)

没有特别的单一命名约定,但我已经看到私人成员。

答案 17 :(得分:-1)

这只是意味着它是班上的成员字段。

答案 18 :(得分:-2)

这样的命名约定在您阅读代码时非常有用,特别是您自己的代码。强大的命名约定有助于指明特定成员的定义位置,成员类型等。大多数开发团队采用简单的命名约定,只需在成员字段前加下划线(_fieldName)。在过去,我使用了以下C#命名约定(它基于.NET框架代码的微软约定,可以在Reflector中看到):

实例字段: m_fieldName
静态字段: s_fieldName
公共/受保护/内部成员: PascalCasedName()
私人会员: camelCasedName()

这有助于人们在非常快速地阅读不熟悉的代码时理解成员的结构,使用,可访问性和位置。