为什么我不应该在字段前加上?

Tra*_*rap 49 c# field naming-conventions hungarian-notation

我从来都不是匈牙利表示法的粉丝,除非你做了一些非常低级的编程,否则我总是觉得它很无用,但在每个C++项目中,我都采用了某种匈牙利符号政策,并且使用一些"非真正匈牙利"的前缀作为m_表示字段,s_表示静态,g_表示全局变量等等.

很快我意识到它在C#中有多么无用,并逐渐开始放弃我所有的旧习惯......但是'm_'的事情.我仍然在私有字段上使用m_前缀,因为我真的觉得能够区分参数,本地和字段非常有用.

MSDN上字段页面命名约定说我不应该,但它没有说明原因(例如Google的惯例通常倾向于合理化他们的处方).

有没有理由我不应该或只是风格问题.如果是后者,前缀通常被认为是一种不好的风格,我是否可以期待其他人在代码库上做出负面反应?

Mat*_*ell 52

我喜欢成员字段的下划线前缀.大多数情况下我喜欢它,因为这样,我的所有成员字段都按字母顺序显示在屏幕顶部向导栏中的方法之前.

WizardBar

  • @Seph我已经开始在C#中使用_前缀了.忘记2年前的评论:P (5认同)
  • 不是个好主意.可以保留下划线前缀.如果我们以此为习惯,我们最终会在某一天碰到那些碰撞,迫使我们打破惯例. (4认同)
  • 我添加了我的投票,用于在成员字段前加下划线.这真的有帮助. (2认同)
  • @ kizzx2在内部,c#对自动实现的属性的后备字段使用下划线前缀,因此将此用于您自己的私有字段将匹配实现.还有哪些下划线前缀保留? (2认同)

Mat*_*ttJ 38

当你应该:

  • 当你的项目编码指南说你应该

当你不应该:

  • 当您的项目编码指南说您不应该

如果您还没有任何指导原则,您可以自由选择您或您的团队想要的任何内容,并且感觉最舒服.就个人而言,当编写C++时,我倾向于使用m_作为成员,它确实有帮助.当用其他语言编写代码时,特别是那些没有真正类的代码(如Javascript,Lua),我没有.

总之,我不相信有"正确"和"错误"的方式.

  • 我觉得很清楚我在问什么.这不是关于何时我应该遵循指南.我无法理解的是为什么人们会继续投票给出这个答案.可能我没有说清楚自己. (5认同)
  • 他不是要求正确或错误的方式,而是认为我们认为正确的方式. (3认同)
  • 正如我所说,正确的方法是他的方式;) (2认同)

Ðаn*_*Ðаn 21

C#3.0中的自动实现的属性功能不再需要这种约定.而不是写作

string m_name;
public string Name { get { return m_name; } }
Run Code Online (Sandbox Code Playgroud)

要么

string _Name;
public string Name { get { return _Name; } }
Run Code Online (Sandbox Code Playgroud)

(或任何其他约定),你现在可以写

public string Name { get; private set; }
Run Code Online (Sandbox Code Playgroud)

由于您不再需要显式的后备存储变量,因此您不再需要为其提供名称; 从而避免了整个讨论.

显然,当您确实需要显式支持存储(例如执行验证)时,此参数不适用.

  • 这适用于自动属性,但是在get/set中具有逻辑的属性仍然需要后备存储,因此它不回答问题. (5认同)
  • 那么不公开公共属性(即从 app.config 读取的 m_ConnectionString)的私有成员呢? (2认同)

Chr*_*ris 11

正如一些人所提到的,MS指南说:

不要为字段名称使用前缀.例如,不要使用g_或s_来区分静态字段和非静态字段.

我碰巧同意这一点.前缀使您的代码看起来很丑陋,浪费空间而且无关紧要.话虽如此,通常使用字段来支持属性,其中字段和属性将具有相同的名称(私有字段为驼峰,属性为pascal情况).在VB中,这不起作用,因为VB不区分大小写.在这种情况下,我建议使用单个_前缀.不多也不少.它看起来更干净,恕我直言.

  • 实际上,MS指南说这些指南不包含内部和私有字段(http://msdn.microsoft.com/en-us/library/ms229012.aspx) (3认同)
  • 考虑到 .NET Framework 充满了以 m_ 为前缀的私有字段,这很有趣 (2认同)

Sco*_*ttS 11

我已经尝试过m_,s_,只是_,而且根本没有前缀.我已经决定只使用_来表示所有静态和实例变量.我认为区分静态变量和实例变量并不重要.理论上听起来不错,在实践中它不会产生问题.

一位同事曾经做过一个令人信服的论据来消除所有前缀,我们在一个项目上尝试过,它比我预期的更好.我把它带到了我的下一个项目,并对它"干扰"Intellisense感到恼火.当您遇到以下情况时

int foo;
public int Foo
{
  get { return foo; }
}
Run Code Online (Sandbox Code Playgroud)

开始输入foo将建议实例变量和属性.使用下划线对变量进行前缀消除了令人烦恼的双重建议,因此我切换回使用_.


Ben*_*n S 10

我尝试遵循MSDN .NET库指南.它们包括命名指南部分.

显然,这些是您的项目指南的次要因素.

  • 方法参数没有混淆.C#已经有办法将变量识别为类成员,即"this".字首. (2认同)
  • 究竟.我不喜欢一遍又一遍地输入'this'只是因为变量名称在它们不需要时是相同的. (2认同)

arg*_*son 10

我更喜欢标记属性支持字段(虽然已经提到.NET 3.0+减少了对自动属性的需求)带下划线而不是"m".首先,当我使用它们时,它将它们置于InteliSense列表的顶部.

我承认我需要了解MSDN的指导方针,这些天来事情可能会如此迅速地改变.


rba*_*all 9

使用像resharper这样的工具,真的没有前缀的理由.此外,如果您编写简短的方法,您应该能够非常快速地告诉var的来源.最后,我想我不会真的看到需要区分静态或不静态,因为如果你尝试做一些你无法做的事情,再次resharper就会变成红线.即使没有resharper,你也许可以被编译器保存.


Sea*_*ean 6

我总是前缀的成员变量与M_和静态变量S_为你的国家,同样的原因.有些人使用下划线为成员变量添加前缀,但我总是发现这有点奇怪(但这只是个人偏好).

我工作的大多数人都使用m_/s_前缀.只要你保持一致,我认为你使用的东西并不重要.


Inf*_*ris 5

我从不使用它们.它鼓励草率编码.MSDN编码指南,就是它所处的位置.

  • 命名构造函数参数'name'和保存值'_name'的字段有什么用? (8认同)
  • 为什么?怎么应该鼓励草率编码??? (3认同)