为了强调或不强调,这就是问题所在

The*_*kie 123 c#

如果二进制版本将被其他框架语言使用,那么在C#中不使用下划线为私有字段添加前缀是否有任何问题?例如,因为C#是区分大小写的,你可以调用字段"foo"和公共属性"Foo",它可以正常工作.

这会对像VB.NET这样的不区分大小写的语言产生什么影响,如果名称只能通过大小写来区分,那么是否会出现任何CLS兼容(或其他)问题?

Tri*_*Gao 254

重要更新(2016年4月12日):

我们注意到,.NET CoreFX团队的内部标准坚持使用下划线符号而不提供任何有关原因的见解.但是,如果我们仔细观察,以排除#3事情变得很明显,有制度_,t_,s_那建议前缀为什么_选择摆在首位.

  1. 我们_camelCase用于内部和私有字段,并尽可能使用readonly.前缀实例字段_,静态字段s_和线程静态字段t_.在静态字段上使用时,readonly应该在static(即static readonly不是readonly static)之后.
  2. 我们避免,this.除非绝对必要.

因此,如果您就像.NET CoreFX团队正在开发一些性能关键,多线程,系统级代码,那么您强烈建议您:

  • 坚持他们的编码标准和
  • 使用下划线和符号
  • 不要再读这个答案了

否则请继续阅读......

原始答案:

让我们首先就我们所谈论的内容达成一致.问题是如果可见性修饰符允许,我们如何从非静态方法和类/子类的构造函数中访问实例成员.

下划线符号

  • 建议您在私有字段的名称中使用"_"前缀
  • 它还说你绝不应该使用"这个",除非绝对必要

这种表示法

  • 建议你只使用"这个".访问任何实例成员

为什么这种符号存在?

因为这就是你的方式

  • 当它们共享相同名称时,从一个字段中分辨出一个参数
  • 确保您在当前实例的上下文中工作

public class Demo
{
   private String name;
   public Demo(String name) {
       this.name = name;
   }
}
Run Code Online (Sandbox Code Playgroud)

为什么下划线符号存在?

有些人不喜欢输入"this",但他们仍然需要一种区分字段和参数的方法,所以他们同意在字段前面使用"_"

public class Demo
{
   private String _name;
   public Demo(String name) {
      _name = name;
   }
}
Run Code Online (Sandbox Code Playgroud)

人们可能会认为这只是个人品味的问题,两种方式同样好/坏.然而,在某些方面,这种符号胜过下划线 - 符号:

明晰

  • 下划线 - 符号杂乱无章
  • 这个符号保持名称完整

认知负荷

  • 下划线符号不一致,它使您以特殊方式处理字段,但是每次您需要问自己是否需要属性或字段时,您不能将其与其他成员一起使用

  • 这个符号是一致的,你不必考虑,你只需要总是使用"this"来指代任何成员

更新:正如所指出的,以下不是一个优势点

保养

  • 下划线表示要求你_在重构时要注意,比如将一个字段转换为属性(删除_)或相反(添加_)

  • 这种符号没有这样的问题

自动完成

当您需要查看实例成员列表时:

  • 下划线 - 表示法对你没什么帮助,因为当你输入"_"时,自动完成弹出窗口会显示私有字段和链接集合中可用的所有类型与其他实例成员混合
  • 这个符号给你一个明确的答案,通过输入"this"所有你看到的是成员列表,没有别的

歧义

有时你必须在没有Intellisense帮助的情况下处理代码.例如,当您在线进行代码审查或浏览源代码时.

  • 下划线 - 符号是模棱两可的:当你看到Something.SomethingElse时,你无法判断Something是否是一个类而SomethingElse是它的静态属性......或者Something是一个当前实例属性,它有自己的属性SomethingElse

  • 这个符号很清楚:当你看到Something.SomethingElse它只能意味着一个带有静态属性的类,当你看到这个.Something.SomethingElse你知道Something是一个成员而SomethingElse是它的属性

扩展方法

如果不使用"this",则无法在实例本身上使用扩展方法.

  • 下划线 - 表示法要求您不要使用"this",但是必须使用扩展方法
  • 这个符号可以让你免于犹豫,你总是使用"这个",期间.

Visual Studio支持

官方建议

有很多官方指南清楚地说"不要使用下划线",特别是在C#中

  • 这是一个惊人的答案.感谢您抽出宝贵时间来编译所有这些信息. (19认同)
  • 为什么要区分性能关键,多线程,系统级代码和其他代码?如果我的代码是性能关键/系统级代码,如何使用`_camelCase`来帮助我? (7认同)
  • 使用下划线与编写性能关键,多线程或系统级代码无关.重要的是一致性,CoreFX团队只是一个同意特定约定的团队.这是一个很好的答案,有一个非常好的分析比较命名约定,但我相信增加的部分说"下划线更好,因为CoreFX团队这么说"真的降低了它的质量. (6认同)
  • 不是来自C++,因为在C++中保留了以语言和标准库用法的下划线开头的标识符. (5认同)
  • 我的问题是我理解逻辑推理.https://en.wikipedia.org/wiki/Inference但是嘿,我觉得并不适合所有人. (5认同)
  • 我几乎不同意您关于`this.`提高清晰度和`_`降低清晰度的每个结论。 (3认同)
  • 官方建议在C#中使用_:https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md(从@landoncz评论到http://stackoverflow.com/一个/二十五万四千一百零九分之六百七十七万三千七百六十九) (2认同)
  • CoreFX团队的专家们开发了一种约定,使用“ _”来处理与多线程和关键性能代码有很大关系的不同方面。如果您的项目不涉及多线程和关键性能代码,那么CoreFX团队的做法可能不相关。 (2认同)
  • 我与@ChrisMarisic在一起,我不同意此答案中的大多数论点。1.“下划线符号会使名称混乱”-我看不到单个“ _”字符会比“ this”的五个字符混乱得多。如果您的论据是仅在需要时使用“ this。”,则转到下一点:2.“此符号是一致的”-不是仅在真正需要的地方使用它,在这种情况下,使用的是不一致的定义。如果您真的想在每种情况下使用它,那么可以回到第1点。 (2认同)
  • 回应对下划线的奇怪路线的批评是"性能关键,多线程,系统级代码".可以指出.Net Core团队已经全部复古,违反了既定的公司标准,但建议在编写性能关键代码时很有帮助."嘿看,我使用多余的下划线,现在我的代码速度提高了20%!" (2认同)
  • 我没看错,我很讽刺。好吧,所以(a)如果您对性能至关重要的工作……是的,我愿意。(b)然后强调,因为核心团队这样做了。逻辑不起作用。许多.Net团队(我工作过最多的团队)都在执行性能关键代码而没有下划线。如果.Net Core团队参与其中,那么从事性能关键代码的人是否应该参与?这只是一个团队做出的风格选择。您可以在不使用下划线的情况下指示核心团队提到的不同字段类型。 (2认同)
  • C# 框架设计指南一书中的命名指南第 3.6.4 节命名字段不包括私有私有字段。杰夫·普罗塞斯 (Jeff Prosise) 补充了他的见解并写道:“根据个人喜好,我通常在私有字段的名称前加上下划线(例如,_connection)。当我在一段时间后重新阅读代码时,这让我很明显哪些字段不适合公共消耗。此约定在 .NET Framework 中被大量使用 - 例如,在 System.Net.HttpWebRequest 和 System.Web.HttpContext 中 - 但并未在整个过程中使用。”。 (2认同)

Dan*_*gby 67

取自Microsoft StyleCop帮助文件:

TypeName: FieldNamesMustNotBeginWithUnderscore

CheckId: SA1309

原因: C#中的字段名称以下划线开头.

规则说明:

当字段名称以下划线开头时,会违反此规则.

默认情况下,StyleCop不允许使用下划线,m_等标记本地类字段,而使用'this'.字首.使用'this'的好处.它同样适用于所有元素类型,包括方法,属性等,而不仅仅是字段,使得对类成员的所有调用都可以立即识别,无论使用哪个编辑器来查看代码.另一个优点是它在实例成员和静态成员之间创建了一个快速,可识别的区别,它不会被加上前缀.

如果字段或变量名称旨在匹配与Win32或COM关联的项的名称,因此需要以下划线开头,请将字段或变量放在特殊的NativeMethods类中.NativeMethods类是包含以NativeMethods结尾的名称的任何类,用作Win32或COM包装器的占位符.如果项目放在NativeMethods类中,StyleCop将忽略此违规.

不同的规则描述表明,除了上述内容之外,首选实践是使用小写字母启动私有字段,使用大写字母启用公共字段.

编辑:作为后续,StyleCop的项目页面位于:http://code.msdn.microsoft.com/sourceanalysis.通过帮助文件阅读可以深入了解他们为什么建议各种风格规则.

  • StyleCop似乎在说,如果我在引用任何类成员时一直使用`this`,我可以通过搜索`this`找到所有类成员的所有调用.我无法与之争辩,但我也想不到我需要这样做的时间.我要做的最后一件事就是在编码中添加乏味,并用"this"(几乎是*匈牙利语)丢弃我的代码几乎没有实际的好处.事实上,如果我正在查看一行代码,那么以大写字母或下划线开头的任何东西都是类成员,任何小写字母都是本地的. (14认同)
  • 在同一软件中也有一条规则,即你不应该只有两个不同的字段.那么你如何处理由公共财产包装的受保护变量? (10认同)
  • 它主要是"最佳实践"类型的东西.正如规则所述,前缀为"this"的前缀可以应用于任何非静态成员,而前缀为任何其他内容**可能因语言语法规则而无法应用."this"关键字使预期目标明显清晰. (7认同)
  • 我也赞成语言对问题的解决方案("这个")而不是人为的解决方法. (5认同)
  • 我对"无下划线"事情的唯一问题是,当针对(网络)表单等进行编程时,仅仅使用'this'并没有帮助我完全过滤到我定义的那些私有字段,而只是给了我这个对象中包含的800万个其他属性的巨大列表. (5认同)

Bin*_*ier 46

没有任何效果.

编写符合CLS的库的部分建议是不要有两个公共/受保护实体,这些实体仅根据具体情况而不同,例如,您应该

public void foo() {...}
Run Code Online (Sandbox Code Playgroud)

public void Foo() {...}
Run Code Online (Sandbox Code Playgroud)

您所描述的内容不是问题,因为私有项目对库的用户不可用

  • 我正在使用下划线.将它们与参数和局部变量区分开来更容易. (44认同)
  • 我只将_用于私有字段,但由于3.5自动属性,我几乎从不拥有私有字段.通常我唯一有私有字段的时候是我在非基本类型上实现延迟加载. (4认同)
  • @balexandre我倾向于避免使用Objective-C代码:) (4认同)
  • PS 就个人而言,我在 C# 中没有下划线。对我来说,这是个人喜好,而不是宗教信仰 (2认同)

M4N*_*M4N 24

由于我们讨论的是私有字段,因此它不会影响您班级的用户.

但我建议在私有字段中使用下划线,因为它可以使代码更容易理解,例如:

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)
  {
    ..
  }
}
Run Code Online (Sandbox Code Playgroud)

在我们的团队中,我们始终对私有字段使用下划线前缀.因此,在阅读某些代码时,我可以非常轻松地识别私有字段,并将它们与本地和参数区分开来.在某种程度上,下划线可以看作是"这个"的简写版本.

  • @Martin:下划线作为"this"的简写问题是,它不一定适用于所有类成员,而"this"可以.我认为代码使用"this"关键字更容易/更清晰.在您的示例中,if(foo == x)将始终引用参数foo. (17认同)
  • 好吧,我*总是*前缀'this',无论我是在追求一个领域,财产还是方法. (14认同)
  • 对我来说,下划线是"this"的简写符号. (9认同)
  • @TheCodeJunkie:你的代码库中有很多冗余字符. (3认同)
  • 在R#中,建议不要调用参数foo.为什么不把它称为'价值',因为你知道它将用于设置Foo? (2认同)

Chr*_*sic 14

从那时起,在一个具有非常具体和非常毫无意义的风格规则的环境中工作后,我继续创造自己的风格.这是我在很多方面来回翻转的一种类型.我最终决定私有字段永远是_field,局部变量永远不会_并且将是小写,控件的变量名称将松散地遵循匈牙利表示法,参数通常是camelCase.

我讨厌this.关键字,我认为它只会增加太多的代码噪音.我喜欢Resharper的删除多余的这个.关键词.

6年更新: 我正在分析Dictionary<TKey,T>并发访问的特定用法的内部结构,并将私有字段误读为本地变量.私有字段肯定不应该与局部变量的命名约定相同.如果有一个下划线,那将是非常明显的.

  • `this`关键字是对当前对象的保证引用.你没有用下划线得到它.不需要厌恶"这个". (16认同)
  • 为什么要发明一个"标准".'这个.' 告诉你对象是一个实例变量'Class'.告诉你它是一个类变量.其他一切都是堆栈变量.下划线属于同一堆坏的想法,匈牙利记谱现在分解. (13认同)
  • @ DRAirey1太容易错过这个.当你需要的时候,你最终会和国家做一些奇怪的事情. (3认同)
  • @ChrisMarisic您当然欢迎您对`_`的使用持有意见,但如果没有明确的话,请不要将其作为既定标准. (3认同)
  • @ChrisMarisic如果你不习惯这样做,那就太容易错过了.忘记在成员字段前放置一个`_`也没什么不同.一旦你完成了一段时间,你就会习惯于用`this来标记你的成员字段.ReSharper的'删除冗余这个关键字'只会增加问题.官方C#命名指南明确禁止使用下划线.正如其他人所说的那样,匈牙利表示法的"`re".养成使用"this."来标记田野成员的习惯,你会发现当你是作曲家时不容易错过. (2认同)
  • 我因“我继续创造自己的风格”而迷失了你。 (2认同)

Lan*_*her 12

我喜欢下划线,因为我可以使用小写名称作为方法参数,如下所示:

public class Person
{
    string _firstName;

    public MyClass(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get { return _firstName; }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • public string FirstName {get; 私人集; } (36认同)
  • 这是未来,现在只是`public string FirstName {get; 在构造函数中仍然可以使用setter (4认同)
  • 您可以使用+1时自动属性. (3认同)
  • 您仍然可以使用小写作为方法参数,使用`this`关键字.在持续的并且总是有争议的"强调或不强调"中将其作为一个静音点:`public MyClass(s​​tring firstName){this.firstName = firstName; }` (3认同)

Rah*_*hul 8

2022 年更新

根据 Microsoft 文档:C# 标识符命名约定

命名私有或内部字段时使用驼峰式大小写(“camelCasing”),并以 _ 为前缀。

益处

在支持语句完成的 IDE 中编辑遵循这些命名约定的 C# 代码时,键入 _ 将显示所有对象范围的成员。

  • 我是在这个帖子中写下得票最多的答案的人,我同意这条消息 (2认同)

peS*_*HIr 7

由于Martin提到的原因,我仍然非常喜欢在私有字段前使用下划线,还因为私有字段将在IntelliSense中排序.尽管匈牙利语前缀符号一般都是邪恶的.

然而,最近我发现使用下划线前缀作为私人成员是不受欢迎的,即使我不太清楚为什么.也许别人都知道?它只是前缀原则吗?或者有没有涉及名称修改泛型类型的东西,它们在编译的程序集中得到下划线或什么?

  • 对我来说,这个.当快速通过代码扫描这个词时,它就变得不那么简单了.只是读这个.这就更多了.这就好了,不得不停下来,这就是这个.承认它和this.realize它是this.not一些this.sort的控制字符.我宁愿偶尔找到`_fieldFoo`或`_fieldBar`而不是让我的用法与`this.fieldFoo`或`this.fieldBar`混乱.我发现`this.前缀比领先的下划线更令人震惊. (21认同)
  • 对我来说,当快速_scanning通过代码时,_会混淆_words,它变得不像只是阅读_和_more _like必须停在_every _来确认它并_________ize它_不是某些_sort的控制字符.它还通过实际将字段名称中的第一个有用字符向右推一列来中断缩进.我一般不喜欢C++,因为大多数C++程序员倾向于写出令人难以置信的简洁和慢速阅读的符号/类似机器的代码,我只是不喜欢C#代码中的代码:) (4认同)
  • @AggieEric 一针见血。光看他的句子就让人头疼!在这件事上,我多年来一直试图坚持 MS 的建议,而且我对到处阅读蓝色的“这个”字眼感到非常恶心,我在那里做出了一个书呆子愤怒的决定。现在,我虔诚地仅将 `this` 用于属性引用,或者当我需要明确区分 `this` 和 `base` 时。每个人都有自己的,我想:-) (3认同)
  • 我认为这是因为最终以标点符号开头的任何内容都会损害可读性。这似乎并没有困扰每个人,但对我来说,阅读以标点符号开头的任何内容都感觉非常不自然。代码越像英语,我就越容易阅读。使用现代 IDE,区分本地成员和私人成员之间的区别非常简单,因为它们很可能具有不同的颜色。 (2认同)

jco*_*lum 5

私有字段的 _fieldName 表示法很容易被破坏。使用“这个”。符号是不可能被打破的。你会如何打破 _ 符号?观察:

private void MyMethod()
{
  int _myInt = 1; 
  return; 
}
Run Code Online (Sandbox Code Playgroud)

就是这样,我只是违反了你的命名约定,但它可以编译。我希望有一个a)非匈牙利语和b)明确的命名约定。我赞成废除匈牙利命名,这在某种程度上是合格的。您拥有其访问级别,而不是变量名称前面的对象类型。

将此与 Ruby 进行对比,在 Ruby 中,变量名称@my_number将名称与作用域联系在一起并且牢不可破。

编辑:这个答案是否定的。我不在乎,它会留下来。

  • 如果说开发人员可能不遵循命名约定,那么这并不是对命名约定的有效批评。 (16认同)
  • 哇,你对“容易打破”的定义和我的完全相反。你的意思是“容易故意损坏”,而大多数其他人的意思可能是“容易*意外*损坏”。我将把它作为练习留给读者,以找出哪个与编写可读代码更相关...... (14认同)
  • @Konrad:当你说“作为读者的练习”时,你听起来很自命不凡。这不是数学教科书。 (9认同)
  • 现在负面情绪稍微少了一些:)虽然我们可能逆流而行,但我也不喜欢下划线约定。在我看来,这与匈牙利表示法没有什么不同,而且说实话,它让我的眼睛流血(损害了可读性)。我们在 C# 中抛弃了匈牙利表示法,是时候消除不信任 IDE 的最后痕迹了。 (4认同)
  • 我听说 MS 实际上说在其 C# 风格指南中不能使用下划线。https://blogs.msdn.microsoft.com/brada/2005/01/26/internal-coding-guidelines/ -- 第 2.6 节 -- 看起来 Brad Abrams 至少同意我们的观点! (2认同)
  • 哦不,`this._NOWwhat = 1;`? (2认同)

Mic*_*ker 5

样式警察是否建议,深入.NET Framework会显示成员变量的大量"_"用法.无论风格警察的创造者是什么推荐,都不是大多数MS员工使用的.:)所以我会坚持使用下划线.因为我个人使用下划线减少了很多错误然后这个(例如:使用varName = varName而不是this.varName = varName,它真的卡在我身上)

  • Underscore也推荐用于.NET核心风格指南:https://github.com/dotnet/corefx/wiki/Coding-style (3认同)