_var
在类字段中看到变量名是很常见的。下划线是什么意思?所有这些特殊的命名约定都有参考吗?
_var
在类字段中看到变量名是很常见的。下划线是什么意思?所有这些特殊的命名约定都有参考吗?
Answers:
下划线只是一个约定;而已。因此,每个人的使用总是有些不同。以下是我对两种语言的理解:
在C ++中,下划线通常表示私有成员变量。
在C#中,我通常看到它仅在定义公共属性的基础私有成员变量时使用。其他私有成员变量将没有下划线。但是,随着自动属性的出现,这种用法在很大程度上已被淘汰。
之前:
private string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}
后:
public string Name { get; set; }
public string Name { get; private set; }
。是的,它不是完全不变的,但它在那里。
_var
不保留。
最佳实践是不要在C ++中的任何变量名称或参数名称之前使用UNDERSCORES
C ++实现者保留以下划线或双下划线开头的名称。带下划线的名称保留给库使用。
如果您阅读了C ++编码标准,您会在第一页看到它的内容:
“不要过分命名,但要使用一致的命名约定:必须做的只有两个:a)切勿使用“下划线名称”,即以下划线开头或包含双下划线的名称;” (p2,C ++编码标准,Herb Sutter和Andrei Alexandrescu)
更具体地说,ISO工作草案规定了实际规则:
另外,某些标识符保留供C ++实现使用,否则不得使用。无需诊断。(a)包含双下划线__或以下划线后跟大写字母开头的每个标识符都保留给实现以供任何使用。(b)每个以下划线开头的标识符都保留给实现,以用作全局命名空间中的名称。
最好避免在下划线开头的符号,以防您意外进入上述限制之一。
您可以亲眼看到为什么在开发软件时使用下划线会造成灾难性的后果:
尝试像这样编译一个简单的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是为虚拟表生成的指针,当您在类中使用一个或多个虚拟成员函数时,该表会自动创建!但这是另一个故事...
如果使用下划线,则可能会遇到冲突问题,并且根本不会导致问题的发生,直到为时已晚。
实际上,_var
约定来自VB,而不是C#或C ++(m _,...是另一回事)。
这就克服了在声明属性时VB不区分大小写的问题。
例如,这样的代码在VB中是不可能的,因为它会将user
和User
视为相同的标识符
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
驼色表壳带下划线 在VB.NET中,始终指示“受保护”或“私有”,请勿使用“昏暗”。不鼓励使用“ m_”,也不鼓励使用仅与大小写不同的变量名,特别是对于受保护的变量,因为它违反了法规遵从性,如果您在VB.NET中进行编程,将会使您的生活痛苦必须为您的成员命名不同于accessor / mutator属性的名称。在这里所有项目中,领先的下划线确实是唯一有争议的项目。对于我的私有变量,我个人更喜欢使用不带下划线的驼峰样式,这样我就不必用“ this”来限定变量名。区别于构造函数或其他可能发生命名冲突的地方的参数。使用VB.NET不区分大小写,这尤其重要,因为除下划线外,访问器属性通常与私有成员变量具有相同的名称。就m_而言,它实际上只是关于美学。我(和许多其他人)发现m_丑陋,因为看起来变量名中有一个洞。这几乎是令人反感的。我曾经在VB6中一直使用它,但这仅仅是因为变量不能有前导下划线。我很高兴看到它消失了。Microsoft建议不要使用m_(和直线_),即使它们在代码中都使用了。同样,以直线“ m”作为前缀也是正确的。当然,由于它们主要使用C#进行编码,因此它们可以具有仅在属性上有所区别的私有成员。VB人员必须做其他事情。我建议不要尝试提出每种语言的特殊情况,而建议使用所有支持该语言的下划线。如果我希望我的类完全兼容CLS,则可以在所有受C#保护的成员变量上都省略前缀。但是,实际上,我永远不必担心这一点,因为我将所有可能受保护的成员变量保持私有状态,而是提供受保护的访问器和变量。原因:简而言之,此约定很简单(一个字符),易于阅读(您的眼睛不会被其他前导字符分散注意力),并且成功避免了与过程级变量和类级属性的命名冲突。 。对于所有支持它的语言,我都建议使用下划线。如果我希望我的类完全兼容CLS,则可以在所有受C#保护的成员变量上都省略前缀。但是,实际上,我永远不必担心这一点,因为我将所有可能受保护的成员变量保持私有状态,而是提供受保护的访问器和变量。原因:简而言之,此约定很简单(一个字符),易于阅读(您的眼睛不会被其他前导字符分散注意力),并且成功避免了与过程级变量和类级属性的命名冲突。 。对于所有支持它的语言,我都建议使用下划线。如果我希望我的类完全兼容CLS,则可以在所有受C#保护的成员变量上都省略前缀。但是,实际上,我永远不必担心这一点,因为我将所有可能受保护的成员变量保持私有状态,而是提供受保护的访问器和变量。原因:简而言之,此约定很简单(一个字符),易于阅读(您的眼睛不会被其他前导字符分散注意力),并且成功避免了与过程级变量和类级属性的命名冲突。 。我从不担心此问题,因为我将所有可能受保护的成员变量设为私有,而是提供受保护的访问器和变量。原因:简而言之,此约定很简单(一个字符),易于阅读(您的眼睛不会被其他前导字符分散注意力),并且成功避免了与过程级变量和类级属性的命名冲突。 。我从不担心此问题,因为我将所有可能受保护的成员变量设为私有,而是提供受保护的访问器和变量。原因:简而言之,此约定很简单(一个字符),易于阅读(您的眼睛不会被其他前导字符分散注意力),并且成功避免了与过程级变量和类级属性的命名冲突。 。
第一个评论者(R Samuel Klatchko)提到:在C ++标识符中使用下划线的规则是什么?它回答了有关C ++下划线的问题。通常,您不应该使用前划线,因为它是为编译器的实现者保留的。您看到的代码_var
可能是遗留代码,或者是使用旧命名系统长大的人编写的代码,而该命名系统并没有引起人们的注意。
正如其他答案所指出的那样,它曾经在C ++中用于标识类成员变量。但是,就装饰器或语法而言,它没有特殊含义。因此,如果要使用它,它将进行编译。
我将把C#讨论留给其他人。
对于C#,Microsoft Framework设计指南建议不要对公共成员使用下划线字符。对于私人成员,可以使用下划线。实际上,Jeffrey Richter(在指南中经常被引用)例如使用m_来表示私有静态成员,并使用“ s_”。
就个人而言,我仅使用_标记我的私人成员。“ m_”和“ s_”紧靠匈牙利表示法,不仅在.NET中被皱眉,而且可能很冗长,我发现很多成员的类很难按字母顺序进行快速眼动扫描(想象10个变量都以m_开头) 。
就C和C ++语言而言,名称中的下划线(开头,中间或结尾)没有特殊含义。这只是一个有效的变量名字符。“惯例”来自编码社区内的编码实践。
如上面的各种示例所示,_开头可能表示C ++中某个类的私有或受保护成员。
让我仅提供一些可能有趣的琐事的历史。在UNIX中,如果您具有核心C库函数和内核后端,并且您想在其中将内核函数公开给用户空间,则_会停留在直接调用内核函数而无需执行其他任何操作的函数存根前面。最著名和熟悉的示例是BSD和SysV类型内核下的exit()与_exit():在那里,exit()在调用内核的退出服务之前执行用户空间操作,而_exit仅映射到内核的退出服务。
因此,_用于“本地”内容,在这种情况下,本地是机器本地的。通常,_functions()不可移植。这样一来,您不应期望跨各种平台具有相同的行为。
现在关于变量名中的_,例如
int _foo;
从心理上讲,必须在开始时输入_是很奇怪的事情。因此,如果要创建一个变量名,使其与其他事物发生冲突的可能性较小,尤其是在处理预处理程序替换时,请考虑使用_。
我的基本建议是始终遵循编码社区的惯例,以便您可以更有效地进行协作。
没有特别的单一命名约定,但是我已经看到了私有成员的命名约定。
有充分合法的理由在C#中使用它:如果代码也必须可以从VB.NET扩展。(否则,我不会。)
由于VB.NET不区分大小写,因此没有简单的方法来访问field
此代码中的受保护成员:
public class CSharpClass
{
protected int field;
public int Field { get { return field; } }
}
例如,这将访问属性获取器,而不是字段:
Public Class VBClass
Inherits CSharpClass
Function Test() As Integer
Return Field
End Function
End Class
哎呀,我什至不能写field
小写-VS 2010一直在纠正它。
为了使它易于访问VB.NET中的派生类,必须提出另一种命名约定。给下划线加上前缀可能是它们中插入最少且最“历史上接受的”。
旧问题,新答案(C#)。
C#下划线的另一种用法是使用ASP NET Core的DI(依赖注入)。readonly
在构造期间分配给注入接口的类的私有变量应以下划线开头。我想是否对课程的每个私人成员都使用下划线是一个辩论(尽管Microsoft本身也遵循),但这是肯定的。
private readonly ILogger<MyDependency> _logger;
public MyDependency(ILogger<MyDependency> logger)
{
_logger = logger;
}
这样的命名约定在您阅读代码(尤其是非您自己的代码)时非常有用。强大的命名约定有助于指示特定成员的定义位置,成员的种类等。大多数开发团队采用简单的命名约定,并简单地用下划线(_fieldName
)前缀成员字段。过去,我为C#使用以下命名约定(基于Microsoft的.NET Framework代码约定,可以在Reflector上看到):
实例字段: m_fieldName
静态字段: s_fieldName
公共/受保护/内部成员: PascalCasedName()
私有成员: camelCasedName()
这有助于人们在快速阅读不熟悉的代码时了解成员的结构,使用,可访问性和位置。