为了强调或不强调,这就是问题所在
如果二进制版本将被其他框架语言使用,那么在C#中用下划线为私有字段添加前缀是否存在任何问题? 例如,因为C#是区分大小写的,你可以调用一个字段“foo”和公共属性“Foo”,它工作正常。
这会对VB.NET等不区分大小写的语言产生什么影响,如果名称只能通过大小写区分,是否会遇到CLS兼容(或其他)问题?
这将不起作用。
部分编写符合CLS的库的build议是不要有两个公开/受保护的实体,只有大小写不同,例如,你不应该有
public void foo() {...}
和
public void Foo() {...}
你所描述的不是一个问题,因为私人物品对图书馆用户是不可用的
重要更新(2016年4月12日):
引起我们注意的是,.NET CoreFX团队的内部标准坚持使用下划线符号而没有提供任何有关为什么的见解。 但是,如果我们仔细看第3条规则,就会发现有一个系统的_
, t_
, s_
前缀表明为什么_
被选中。
- 我们使用
_camelCase
作为内部和专用字段,并尽可能使用readonly。 带有_
前缀实例字段,带有s_
静态字段和带有t_
线程静态字段。 当在静态字段上使用时,readonly
应该在static
之后(即static readonly
而非readonly static
)。- 我们避免
this.
除非绝对必要。
所以,如果你像.NET CoreFX团队一样工作在一些性能关键的multithreading系统级代码上,那么强烈build议你:
- 坚持他们的编码标准和
- 使用下划线符号和
- 不要再阅读这个答案
否则,请继续阅读…
原来的回答:
我们先来谈谈我们正在谈论的内容。 问题是,如果可见性修饰符允许的话,我们如何从非静态方法和类/子类的构造函数中访问实例成员。
下划线符号
- build议您在专用字段的名称中使用“_”前缀
- 它还说,除非绝对必要,否则绝不能使用“这个”
这种表示法
- build议你总是使用“这个”。 访问任何实例成员
为什么这个符号存在?
因为这是你的方式
- 当他们共享相同的名字时,从字段中分离出一个参数
- 确保您正在当前实例的上下文中工作
例
public class Demo { private String name; public Demo(String name) { this.name = name; } }
为什么下划线符号存在?
有些人不喜欢打字“这个”,但是他们仍然需要区分一个字段和一个参数的方法,所以他们同意在字段前使用“_”
例
public class Demo { private String _name; public Demo(String name) { _name = name; } }
人们可能会认为这只是个人品味的问题,两种方式同样好/坏。 然而,在某些方面,这个符号打败了下划线符号:
明晰
- 下划线符号混乱的名字
- 这个符号保持名称完好无损
认知负荷
-
下划线符号是不一致的,它使你以特殊的方式对待字段,但是你不能和其他成员一起使用它,每次你需要问自己你是否需要一个属性或者一个字段
-
这个符号是一致的,你不必去想,你总是用“this”来引用任何成员
保养
-
下划线符号要求你在重构的时候要注意
_
,把一个字段变成属性(remove_
)或者相反(add_
) -
这个符号不存在这样的问题
自动完成
当您需要查看实例成员的列表时:
- 下划线符号并没有太大的帮助,因为当你input“_”时,自动完成popup菜单显示了私有字段和链接程序集中可用的所有types以及其他实例成员
- 这个符号给你一个明确的答案,通过input“this”,你所看到的只是成员的列表,没有别的
歧义
有时你必须在没有Intellisense的帮助下处理代码。 例如,当你做代码评论或在线浏览源代码。
-
下划线符号含糊不清:当你看到Something.SomethingElse时,你不能分辨Something是一个类,SomethingElse是它的静态属性…或者Something是一个当前的实例属性,它有自己的属性SomethingElse
-
这个符号是明确的:当你看到Something.SomethingElse它只能意味着一个静态属性的类,当你看到this.Something.SomethingElse你知道Something是一个成员,SomethingElse是它的属性
扩展方法
如果不使用“this”,则不能在实例本身上使用扩展方法。
- 下划线表示法要求您不要使用“this”,但是必须使用扩展方法
- 这个符号可以让你免于犹豫,你总是使用“this”这个句号。
Visual Studio支持
- 下划线符号在Visual Studio中没有内置的支持
-
这个符号是由Visual Studio自然支持的:
- http://www.screenr.com/zDCH
- “这个。” 资格 : 优先使用非静态方法中使用的所有非静态字段
this.
在C#
官方build议
有很多官方的指南,特别是在C#中明确地说“不要使用下划线”
-
下划线标记来自C ++,这是一种有助于避免命名冲突的常规做法,也推荐用于VisualBasic.Net,以解决字段“值”和属性“值”实际上具有相同名称的问题,因为VisualBasic是不区分大小写的
- 在Visual Basic中声明的元素名称
- 在VisualBasic.NET中备份字段
-
这个符号被推荐用于C#,而“_”被明确禁止:
- 这个关键字在C#
- 字段用法指南 : 不要将字首应用于字段名称或静态字段名称。
- 名称准则:types成员名称 : 不要为字段名称使用前缀。
- 一般命名约定 : X请勿使用下划线,连字符或任何其他非字母数字字符
- 质量断言规则CA1707 : 标识符不应包含下划线
- 使用下划线不符合CLS (对于公共和受保护的标识符)
- .NET Framework开发人员的内部命名约定 : 不要为成员variables使用前缀。 如果你想区分本地和成员variables,你应该使用“这个”。 在C#和“我”。 在VB.NET中。
取自Microsoft StyleCop帮助文件:
TypeName: FieldNamesMustNotBeginWithUnderscore
CheckId: SA1309
原因: C#中的字段名称以下划线开头。
规则说明:
当字段名称以下划线开始时,会发生违反此规则的情况。
默认情况下,StyleCop不允许使用下划线m_等来标记本地类字段,以支持“this”。 字首。 使用“这个”的好处。 是它同样适用于所有的元素types,包括方法,属性等,而不仅仅是字段,不pipe使用哪个编辑器来查看代码,都可以立即识别对类成员的所有调用。 另一个优点是,它在实例成员和静态成员之间创build了一个快速的,可识别的区别,这些成员不会被添加到前缀中。
如果字段或variables名称旨在匹配与Win32或COM关联的项目的名称,因此需要以下划线开头,请将该字段或variables放在特定的NativeMethods类中。 NativeMethods类是包含以NativeMethods结尾的名称的任何类,用作Win32或COM包装的占位符。 如果项目放置在NativeMethods类中,StyleCop将忽略此违规。
一个不同的规则描述表明,除上述之外,首选的做法是以小写字母开始私人字段,以大写字母开始。
编辑:作为后续,StyleCop的项目页面位于: http : //code.msdn.microsoft.com/sourceanalysis 。 通过帮助文件的阅读给出了很多洞察,为什么他们build议各种文体规则。
既然我们正在谈论一个私人领域,它不会影响你的class级的用户。
但是我build议使用私人字段的下划线,因为它可以使代码更容易理解,例如:
private int foo; public void SetFoo(int foo) { // you have to prefix the private field with "this." this.foo = foo; // imagine there's lots of code here, // so you can't see the method signature // when reading the following code, you can't be sure what foo is // is it a private field, or a method-argument (or a local variable)?? if (foo == x) { .. } }
在我们的团队中,我们总是使用私人字段的下划线前缀。 因此,当阅读一些代码时,我可以很容易地识别私人领域,并从当地人和争论中区分开来。 在某种程度上,下划线可以被看作是“这个”的简写forms。
我喜欢下划线,因为那样我可以使用小写的名字作为方法参数,如下所示:
public class Person { string _firstName; public MyClass(string firstName) { _firstName = firstName; } public string FirstName { get { return _firstName; } } }
从那时起,在一个非常具体和非常没有意义的风格规则的环境中工作之后,我继续创作自己的风格。 这是我翻转过来的一种types。 我终于决定私人领域将永远是_field,局部variables将永远不会_和将是小写字母,控制的variables名将松散地遵循匈牙利符号,参数一般是camelCase。
我讨厌this.
关键字只是在我看来增加了太多的代码噪音。 我爱Resharper的删除多余的这一点。 关键词。
6年更新:我正在分析Dictionary<TKey,T>
的内部结构Dictionary<TKey,T>
指出并发访问的具体用法,并将一个私有字段误读为局部variables。 私有字段绝对不应该和局部variables是一样的命名约定。 如果有一个下划线,这将是非常明显的。
由于马丁提到的原因,我仍然非常喜欢在私人领域使用下划线,也因为私人领域将在IntelliSense中一起sorting。 这是尽pipe匈牙利前缀符号一般的邪恶。
然而,最近我发现,使用私人成员的下划线前缀是不屑一顾的,尽pipe我不太清楚为什么。 也许别人知道? 这只是前缀原则吗? 还是有一些涉及到在编译的程序集中获得下划线的genericstypes的名称修改?
Style Copbuild议与否,挖掘到.NET Framework显示了大量的“_”成员variables的用法。 无论Style Cop的创作者如何推荐,MS员工大部分都不会使用。 :)所以我会坚持下划线。 因为我个人使用下划线减less了很多错误,所以这(例如:使用varName = varName而不是this.varName = varName,它真的困在我身上)
我认为大部分的课程级别的领域在语言的devise上是一个错误。 如果C#的属性有自己的局部范围,我会更喜欢它:
public int Foo { private int foo; get { return foo; } set { foo = value; } }
这将有可能完全停止使用字段。
我唯一的时间前缀私人领域与下划线是当一个属性需要一个单独的支持领域。 这也是我唯一一次使用私人领域。 (因为我从来没有使用受保护的,内部的或公共的字段,这是我唯一使用字段句点的时间。)就我而言,如果一个variables需要具有类作用域,它就是类的一个属性。
当您希望程序集符合CLS时,可以在assemblyinfo文件中使用CLSCompliant属性。 当你的代码包含不符合cls的东西时,编译器会发出抱怨。
然后,当你有两个只有大小写不同的属性时,编译器会发出一个错误。 另一方面,当你在同一个class级有一个私人领域和一个公共财产时,就没有问题了。
(但是,我也总是给我的私人成员添加一个下划线,当我阅读我的代码时,我也清楚地知道某个variables是成员字段)。
我喜欢在我的私人领域使用下划线有两个原因。 其中一个已经被提到,这些领域从代码和Intellisense中的相关属性中脱颖而出。 第二个原因是我可以使用相同的命名约定,无论是在VB还是C#编码。
没有任何影响。 编译代码时,对编译器来说重要的是字段/属性的名称空间和可见性。 在为一个标识符命名时,下划线与任何其他字符一样重要。 真正的诀窍是使用你和你周围的人会理解的约定。
专用字段的_fieldName表示法很容易中断 。 使用“这个”。 记谱法是不可能的。 你怎么打破_符号? 注意:
private void MyMethod() { int _myInt = 1; return; }
你去了,我只是违反了你的命名约定,但它编译。 我宁愿有一个命名约定是a)不是匈牙利语和b)明确的。 我赞成废除匈牙利的命名,这在某种程度上符合资格。 而不是variables名称前的对象types,你有它的访问级别。
将其与variables@my_number
的名称@my_number
到作用域的名称并不可破解的Ruby对比。
编辑:这个答案已经消极。 我不在乎,它保持。