命名约定 – C ++和C#variables中的下划线

在类字段中看到一个_varvariables名是很常见的。 下划线是什么意思? 有没有这些特殊的命名约定的参考?

下划线只是一个约定, 而已。 因此,每个人的使用总是有所不同。 下面是我对这两种语言的理解:

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

在C#中,我通常只会在为公共属性定义底层私有成员variables时才会看到它。 其他私有成员variables不会有下划线。 尽pipe如此,这种用法在很大程度上是自动化属性的出现。

之前:

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

后:

 public string Name { get; set; } 

请不要在C ++的任何variables名或参数名之前使用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; } 

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

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

如果你使用下划线,你可能会遇到冲突的问题,你会没有想法是什么原因导致它,直到为时已晚。

其实_var公约来自VB而不是C#或C ++(m _,…是另一回事)。

这是为了克服在声明特性时VB不区分大小写

例如这样的代码在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约定之间的一致性,他们使用相同的。

我find了我在说的内容: http : //10rem.net/articles/net-naming-conventions-and-programming-standards—best-practices

骆驼案件与领先的下划线。 在VB.NET中,总是指明“受保护”或“私人”,不要使用“昏暗”。 不鼓励使用“m_”,就像使用与属性不同的variables名一样,特别是对于受保护的variables,因为这违反了合规性,如果在VB.NET中进行编程,将会使您的生活变得很痛苦。将不得不命名您的成员与accessor / mutator属性不同。 在这里所有的项目中,主要的下划线是唯一有争议的。 我个人更喜欢直接使用下划线的驼峰大小来表示我的私有variables,所以我不必用“this”限定variables名。 以区别于构造函数或其他地方我可能会有命名冲突的参数。 由于VB.NET的不区分大小写,这是更重要的,因为除了下划线外,您的访问器属性通常与私有成员variables具有相同的名称。 就我而言,这实际上只是美学。 我(还有很多人)觉得很丑,因为看起来variables名中有一个漏洞。 这几乎是无礼的。 我以前一直在VB6中使用它,但那只是因为variables不能有一个前导下划线。 我不能高兴地看到它消失。 微软build议对付m_(和直_),即使他们都在他们的代码。 另外,用直线“m”作为前缀是正确的。 当然,因为他们主要是用C#编写的,所以他们可以拥有私有成员,这些私有成员在属性的情况下是不同的。 VB人必须做别的事情。 我不推荐使用各种语言的特殊情况,而是推荐所有支持它的语言的首字母下划线。 如果我希望我的类完全符合CLS,则可以在任何受C#保护的成员variables上留下前缀。 然而,在实践中,我从不担心这一点,因为我将所有可能受保护的成员variables保留为私有的,并提供受保护的访问器和修改器。 为什么:简而言之,这个约定很简单(一个字符),易于阅读(您的眼睛不会被其他主要字符分心),并成功地避免了与过程级variables和类级属性的命名冲突。 。

第一个评论者(R Samuel Klatchko)引用: 关于在C ++标识符中使用下划线的规则是什么? 它回答了关于C ++下划线的问题。 一般来说,不应该使用前导下划线,因为它是为编译器的实现者保留的。 您使用_var看到的代码可能是遗留代码,或者是由使用旧的命名系统而不是前导下划线的人长大的代码编写的代码。

正如其他答案所述,它曾经被用于C ++来识别类成员variables。 然而,就装饰器或语法而言,它没有特殊的含义。 所以如果你想使用它,它会编译。

我将把C#讨论留给其他人。

您可以创build自己的编码准则。 只要为团队的其他成员写一个明确的文档。

使用_field可以帮助Intelilsense只input_来过滤所有的类variables。

我通常遵循Brad Adams指南 ,但是build议不要使用下划线。

_var没有意义,只是为了更容易区分variables是私有成员variables。

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

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

使用C#,Microsoft 框架devise指南build议不要使用公共成员的下划线字符。 对于私人成员,下划线可以使用。 事实上, Jeffrey Richter (在指南中经常引用)使用m_和私人静态成员的“s_”。

就我个人而言,我只是用_来标记我的私人成员。 匈牙利语中的“m_”和“s_”边缘不仅在.NET中被皱起了眉毛,而且可能非常冗长,而且我发现许多类的成员难以按字母顺序进行快速眼睛扫描(想象10个variables都以m_开头) 。

就C和C ++语言而言,名称(开始,中间或结尾)中的下划线没有特殊含义。 这只是一个有效的variables名字符。 这些“约定”来自编码社区的编码实践。

正如上面的各种例子已经指出的那样,在开始的时候可能指的是C ++中的一个类的私有成员或保护成员。

让我只是给一些可能是有趣的琐事的历史。 在UNIX中,如果你有一个核心的C库函数和一个内核后端,你也想把内核函数暴露给用户空间,那么_就会停留在直接调用内核函数的函数存根之前,而不会做任何事情。 最着名和最熟悉的例子是在BSD和SysVtypes内核下的exit()vs _exit()。在那里,exit()在调用内核的退出服务之前做用户空间的东西,而_exit只是映射到内核的退出服务。

所以_在这种情况下被用于本地机器本地。 通常_functions()是不可移植的。 在这一点上,你不应该期望在各种平台上有相同的行为

现在至于_中的variables名,比如

int _foo;

从心理上来说,在开始时input_是一件奇怪的事情。 所以如果你想创build一个variables名称,与其他事物发生冲突的可能性较小,特别是在处理预处理器replace时,你要考虑使用_。

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

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

我使用_var作为我的类的成员variables的命名。 我有两个主要原因:

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

2)当我正在寻找类variables时,它在Intellisense(或其他代码完成系统)中有帮助。 只要知道第一个字符就有助于通过可用variables和方法的列表进行筛选。

许多人喜欢有一个下划线前缀的私人领域。 这只是一个命名约定。

C#的“官方”命名约定规定了私有字段的简单小写名称(不包含下划线)。

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

这只是一些程序员用来在你操作类的成员或其他types的variables(参数,函数本地等)时使用的惯例。 另一个也广泛用于成员variables的约定是用'm_'作为前缀。

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

在C#中使用它有一个完全合法的原因:如果代码也必须从VB.NET扩展。 (否则,我不会。)

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

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

例如,这将访问属性getter,而不是字段:

 Public Class VBClass Inherits CSharpClass Function Test() As Integer Return Field End Function End Class 

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

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

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

从我的经验(当然是有限的),下划线将表明它是一个私人成员variables。 正如Gollum所说,这将取决于球队。

这仅仅意味着它是class上的一员。

这样的命名约定在读取代码时非常有用,特别是不属于您自己的代码。 强大的命名约定有助于指明特定成员的定义,成员的types等等。大多数开发团队采用简单的命名约定,并且只用成员字段( _fieldName )作为前缀。 在过去,我已经使用了C#的下列命名约定(基于.NET框架代码的微软约定,这可以在Reflector中看到):

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

这可以帮助人们在快速阅读不熟悉的代码时了解会员的结构,使用,可访问性和位置。