命名约定 - C++ 中的下划线和 C# 变量
在类字段中经常会看到 _var
变量名。下划线是什么意思?所有这些特殊命名约定都有参考吗?
It's common to see a _var
variable name in a class field. What does the underscore mean? Is there a reference for all these special naming conventions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
下划线只是一种约定;而已。因此,每个人的使用总是有些不同。以下是我对这两种语言的理解:
在 C++ 中,下划线通常表示私有成员变量。
在 C# 中,我通常只在为公共属性定义底层私有成员变量时才使用它。其他私有成员变量不会有下划线。不过,随着自动属性的出现,这种用法基本上已经被抛弃了。
之前:
之后:
The underscore is simply a convention; nothing more. As such, its use is always somewhat different to each person. Here's how I understand them for the two languages in question:
In C++, an underscore usually indicates a private member variable.
In C#, I usually see it used only when defining the underlying private member variable for a public property. Other private member variables would not have an underscore. This usage has largely gone to the wayside with the advent of automatic properties though.
Before:
After:
最佳实践是在 C++ 中的任何变量名称或参数名称之前不要使用下划线
以下划线或双下划线开头的名称保留给 C++ 实现者。带下划线的名称保留供库使用。
如果您读过 C++ 编码标准,您会在第一页看到这样的内容:
更具体地说,ISO 工作草案规定了实际规则:
最好避免以下划线开头的符号,以防您意外陷入上述限制之一。
您可以亲自了解为什么在开发软件时使用下划线可能会造成灾难性的后果:
尝试编译一个简单的 helloWorld.cpp 程序,如下所示:
您将看到后台发生的所有情况。这是一个片段:
您可以看到有多少名称以双下划线开头!
另外,如果您查看虚拟成员函数,您会发现 *_vptr 是为虚拟表生成的指针,当您在类中使用一个或多个虚拟成员函数时,该指针会自动创建!但这是另一个故事了......
如果您使用下划线,您可能会遇到冲突问题,并且您将不知道是什么原因导致的,直到为时已晚。
It is best practice to NOT use UNDERSCORES before any variable name or parameter name in C++
Names beginning with an underscore or a double underscore are RESERVED for the C++ implementers. Names with an underscore are reserved for the library to work.
If you have a read at the C++ Coding Standard, you will see that in the very first page it says:
More specifically, the ISO working draft states the actual rules:
It is best practice to avoid starting a symbol with an underscore in case you accidentally wander into one of the above limitations.
You can see it for yourself why such use of underscores can be disastrous when developing a software:
Try compiling a simple helloWorld.cpp program like this:
You will see all that happens in the background. Here is a snippet:
You can see how many names begin with double underscore!
Also if you look at virtual member functions, you will see that *_vptr is the pointer generated for the virtual table which automatically gets created when you use one or more virtual member functions in your class! But that's another story...
If you use underscores you might get into conflict issues and you WILL HAVE NO IDEA what's causing it, until it's too late.
实际上,
_var
约定来自 VB,而不是 C# 或 C++(m_,... 是另一回事)。这是为了克服 VB 在声明属性时不区分大小写的问题。
例如,这样的代码在 VB 中是不可能的,因为它将
user
和User
视为相同的标识符。因此,为了克服这个问题,一些人使用了一种约定来添加“_”私有字段将像这样出现
由于许多约定都是针对 .Net 的,并且为了保持 C# 和 VB.NET 约定之间的一致性,因此它们使用相同的约定。
我找到了我所说的参考:
http://10rem.net/articles/net -命名约定和编程标准---最佳实践
Actually the
_var
convention comes from VB not C# or C++ (m_,... is another thing).This came to overcome the case insensitivity of VB when declaring Properties.
For example, such code isn't possible in VB because it considers
user
andUser
as the same identifierSo to overcome this, some used a convention to add '_' to the private field to come like this
Since many conventions are for .Net and to keep some uniformity between C# et VB.NET convention, they are using the same one.
I found the reference for what I was saying :
http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
_var
没有任何意义,只是为了更容易区分该变量是私有成员变量。在 C++ 中,使用
_var
约定是不好的形式,因为有一些规则管理标识符前面下划线的使用。_var
保留作为全局标识符,而_Var
(下划线+大写字母)随时保留。这就是为什么在 C++ 中,您会看到人们使用var_
约定。_var
has no meaning and only serves the purpose of making it easier to distinguish that the variable is a private member variable.In C++, using the
_var
convention is bad form, because there are rules governing the use of the underscore in front of an identifier._var
is reserved as a global identifier, while_Var
(underscore + capital letter) is reserved anytime. This is why in C++, you'll see people using thevar_
convention instead.第一个评论者(R Samuel Klatchko)引用:在 C++ 标识符中使用下划线的规则是什么? 回答了有关 C++ 中下划线的问题。一般来说,您不应该使用前导下划线,因为它是为编译器的实现者保留的。您在
_var
中看到的代码可能是遗留代码,或者是由使用旧命名系统长大的人编写的代码,该命名系统不支持前导下划线。正如其他答案所述,它曾经在 C++ 中用于识别类成员变量。然而,就装饰器或语法而言,它没有特殊含义。所以如果你想使用它,它就会编译。
我将把 C# 的讨论留给其他人。
The first commenter (R Samuel Klatchko) referenced: What are the rules about using an underscore in a C++ identifier? which answers the question about the underscore in C++. In general, you are not supposed to use a leading underscore, as it is reserved for the implementer of your compiler. The code you are seeing with
_var
is probably either legacy code, or code written by someone that grew up using the old naming system which didn't frown on leading underscores.As other answers state, it used to be used in C++ to identify class member variables. However, it has no special meaning as far as decorators or syntax goes. So if you want to use it, it will compile.
I'll leave the C# discussion to others.
老问题,新答案(C#)。
C# 下划线的另一个用途是 ASP NET Core 的 DI(依赖注入)。在构造过程中分配给注入接口的类的私有
readonly
变量应该以下划线开头。我想这是一个关于是否对类的每个私有成员使用下划线的争论(尽管微软本身遵循它),但这是肯定的。编辑:
Microsoft 对类的所有私有成员采用下划线已经有一段时间了。
Old question, new answer (C#).
Another use of underscores for C# is with ASP NET Core's DI (dependency injection). Private
readonly
variables of a class which got assigned to the injected interface during construction should start with an underscore. I guess it's a debate whether to use underscore for every private member of a class (although Microsoft itself follows it) but this one is certain.EDIT:
Microsoft adopted use of underscores for all private members of a class for a while now.
您可以创建自己的编码指南。只需为团队的其他成员编写一份清晰的文档即可。
使用 _field 可以帮助 Intelilsense 过滤所有仅键入 _ 的类变量。
我通常遵循 Brad Adams 准则,但建议不要使用下划线。
You can create your own coding guidelines. Just write a clear documentation for the rest of the team.
Using _field helps the Intelilsense to filter all class variables just typing _.
I usually follow the Brad Adams Guidelines, but it recommends to not use underscore.
对于 C#,Microsoft 框架设计指南 建议不要使用下划线字符来表示 公共成员。对于私有成员,可以使用下划线。事实上,Jeffrey Richter(经常在指南中引用)使用例如 m_,“s_”表示私有静态成员。
就我个人而言,我只使用 _ 来标记我的私人成员。 “m_”和“s_”接近匈牙利表示法,这不仅在.NET中令人不悦,而且可能非常冗长,我发现具有许多成员的类很难按字母顺序进行快速浏览(想象一下 10 个变量都以 m_ 开头) 。
With C#, Microsoft Framework Design Guidelines suggest not using the underscore character for public members. For private members, underscores are OK to use. In fact, Jeffrey Richter (often cited in the guidelines) uses an m_ for instance and a "s_" for private static memberss.
Personally, I use just _ to mark my private members. "m_" and "s_" verge on Hungarian notation which is not only frowned upon in .NET, but can be quite verbose and I find classes with many members difficult to do a quick eye scan alphabetically (imagine 10 variables all starting with m_).
Microsoft C# 命名标准规定变量和参数应使用小驼峰形式 IE:
paramName
。该标准还要求字段遵循相同的形式,但这可能会导致代码不清晰,因此许多团队要求使用下划线前缀来提高清晰度 IE:_fieldName
。The Microsoft naming standard for C# says variables and parameters should use the lower camel case form IE:
paramName
. The standard also calls for fields to follow the same form but this can lead to unclear code so many teams call for an underscore prefix to improve clarity IE:_fieldName
.我对类的成员变量使用 _var 命名。我这样做有两个主要原因:
1)它可以帮助我在稍后阅读代码时跟踪类变量和局部函数变量。
2)当我寻找类变量时,它对智能感知(或其他代码完成系统)有帮助。只需知道第一个字符就有助于过滤可用变量和方法的列表。
I use the _var naming for member variables of my classes. There are 2 main reasons I do:
1) It helps me keep track of class variables and local function variables when I'm reading my code later.
2) It helps in Intellisense (or other code-completion system) when I'm looking for a class variable. Just knowing the first character is helpful in filtering through the list of available variables and methods.
在 C# 中使用它有完全合法的理由: 如果代码也必须可从 VB.NET 扩展。
(否则,我不会。)
由于 VB.NET 不区分大小写,因此没有简单的方法来访问此代码中受保护的
field
成员:例如,这将访问属性 getter,而不是字段:
哎呀,我什至不能用小写写
field
- VS 2010 只是不断纠正它。为了使 VB.NET 中的派生类能够轻松访问它,必须提出另一种命名约定。前缀下划线可能是其中干扰性最小且最“历史上接受”的。
There is a fully legit reason to use it in C#: if the code must be extensible from VB.NET as well.
(Otherwise, I would not.)
Since VB.NET is is case insensitive, there is no simple way to access the protected
field
member in this code:E.g. this will access the property getter, not the field:
Heck, I cannot even write
field
in lowercase - VS 2010 just keeps correcting it.In order to make it easily accessible to derived classes in VB.NET, one has to come up with another naming convention. Prefixing an underscore is probably the least intrusive and most "historically accepted" of them.
就 C 和 C++ 语言而言,名称中的下划线(开头、中间或结尾)没有特殊含义。它只是一个有效的变量名称字符。 “约定”来自编码社区内的编码实践。
正如上面的各种示例已经表明的那样,开头的 _ 可能表示 C++ 中类的私有或受保护成员。
让我简单介绍一些可能很有趣的历史琐事。在 UNIX 中,如果您有一个核心 C 库函数和一个内核后端,并且您希望将内核函数公开给用户空间,则 _ 会被固定在直接调用内核函数而不执行任何其他操作的函数存根前面。最著名和最熟悉的例子是 BSD 和 SysV 类型内核下的 exit() 与 _exit() :其中, exit() 在调用内核的退出服务之前执行用户空间的操作,而 _exit 只是映射到内核的退出服务。
因此 _ 用于“本地”内容,在本例中本地是机器本地的。通常 _functions() 是不可移植的。因为您不应该期望在不同平台上有相同的行为。
现在对于变量名中的 _ ,如
int _foo;
从心理上来说,必须在开头输入 _ 是一件奇怪的事情。因此,如果您想创建一个与其他名称发生冲突的可能性较小的变量名,特别是在处理预处理器替换时,您需要考虑使用 _。
我的基本建议是始终遵循编码社区的惯例,以便您可以更有效地协作。
As far as the C and C++ languages are concerned there is no special meaning to an underscore in the name (beginning, middle or end). It's just a valid variable name character. The "conventions" come from coding practices within a coding community.
As already indicated by various examples above, _ in the beginning may mean private or protected members of a class in C++.
Let me just give some history that may be fun trivia. In UNIX if you have a core C library function and a kernel back-end where you want to expose the kernel function to user space as well the _ is stuck in front of the function stub that calls the kernel function directly without doing anything else. The most famous and familiar example of this is exit() vs _exit() under BSD and SysV type kernels: There, exit() does user-space stuff before calling the kernel's exit service, whereas _exit just maps to the kernel's exit service.
So _ was used for "local" stuff in this case local being machine-local. Typically _functions() were not portable. In that you should not expect same behaviour across various platforms.
Now as for _ in variable names, such as
int _foo;
Well psychologically, an _ is an odd thing to have to type in the beginning. So if you want to create a variable name that would have a lesser chance of a clash with something else, ESPECIALLY when dealing with pre-processor substitutions you want consider uses of _.
My basic advice would be to always follow the convention of your coding community, so that you can collaborate more effectively.
它只是意味着它是类中的成员字段。
It's simply means that it's a member field in the class.
没有特定的单一命名约定,但我见过私人成员的命名约定。
There's no particular single naming convention, but I've seen that for private members.
许多人喜欢在私有字段中添加下划线前缀。这只是一个命名约定。
C# 的“官方”命名约定为私有字段规定了简单的小写名称(无下划线)。
尽管下划线使用非常广泛,但我不知道 C++ 的标准约定。
Many people like to have private fields prefixed with an underscore. It is just a naming convention.
C#'s 'official' naming conventions prescribe simple lowercase names (no underscore) for private fields.
I'm not aware of standard conventions for C++, although underscores are very widely used.
这只是一些程序员在操作类成员或其他类型的变量(参数、函数的局部变量等)时用来明确说明的约定。成员变量也广泛使用的另一个约定是在名称前添加“m_”前缀。
无论如何,这些只是约定,您不会找到所有这些约定的单一来源。它们是一种风格问题,每个编程团队、项目或公司都有自己的风格(甚至没有)。
It's just a convention some programmers use to make it clear when you're manipulating a member of the class or some other kind of variable (parameters, local to the function, etc). Another convention that's also in wide use for member variables is prefixing the name with 'm_'.
Anyway, these are only conventions and you will not find a single source for all of them. They're a matter of style and each programming team, project or company has their own (or even don't have any).
现在,在 this.foobarbaz 中使用“this”的表示法对于 C# 类成员变量来说是可以接受的。它取代了旧的“m_”或“__”符号。它确实使代码更具可读性,因为毫无疑问正在引用什么。
Now the notation using "this" as in this.foobarbaz is acceptable for C# class member variables. It replaces the old "m_" or just "__" notation. It does make the code more readable because there is no doubt what is being reference.
根据我的经验(当然有限),下划线将表明它是一个私有成员变量。正如咕噜所说,但这取决于团队。
From my experience (certainly limited), an underscore will indicate that it is a private member variable. As Gollum said, this will depend on the team, though.
当您阅读代码时,尤其是不属于您自己的代码时,这样的命名约定非常有用。强大的命名约定有助于指示特定成员的定义位置、成员类型等。大多数开发团队采用简单的命名约定,并简单地在成员字段前添加下划线 (
_fieldName
)。过去,我对 C# 使用了以下命名约定(基于 Microsoft 的 .NET 框架代码约定,可以通过 Reflector 看到):实例字段: m_fieldName
静态字段: s_fieldName
公共/受保护/内部成员: PascalCasedName()
私有成员:camelCasedName()
这可以帮助人们在阅读不熟悉的代码时非常快速地理解成员的结构、使用、可访问性和位置。
A naming convention like this is useful when you are reading code, particularly code that is not your own. A strong naming convention helps indicate where a particular member is defined, what kind of member it is, etc. Most development teams adopt a simple naming convention, and simply prefix member fields with an underscore (
_fieldName
). In the past, I have used the following naming convention for C# (which is based on Microsofts conventions for the .NET framework code, which can be seen with Reflector):Instance Field: m_fieldName
Static Field: s_fieldName
Public/Protected/Internal Member: PascalCasedName()
Private Member: camelCasedName()
This helps people understand the structure, use, accessibility and location of members when reading unfamiliar code very rapidly.