Microsoft为什么要使参数,局部变量和私有字段具有相同的名称命名约定?


18

我很早以前问过这个问题:如何在C#中命名私有变量?

在一个答案中,我被指向Microsoft的MSDN页面,该页面显示私有变量/字段应按以下方式命名:

private int myInteger;

但是参数将是:

void SomeMethod(int myInteger)

局部变量是这样的:

int myInteger;

所以当你这样引用它们时

myInteger = 10;

您无法知道您在谈论哪个。

我现在开始一个新项目,我的一位同事问我为什么我们不做点什么来区别其中至少一些。

我在想同样的事情。微软的标准为什么没有使这些保持不同?


10
您是什么意思,“您无法知道您在谈论哪个人”?当然可以-作用域。
Thomas Owens

2
该指南似乎已过时,重新共享默认值(已成为事实上的样式指南)建议为私有字段添加下划线前缀,这是我一直都会做的事情。

25
@kekekela:绝对不会过时;StyleCop将显式标记以下划线开头的成员变量的所有实例。坦率地说,我发现下划线毫无意义且令人讨厌,因为外壳传达了完全相同的信息。如果您需要使作用域明确,则在前缀分配this.
亚伦诺特,2011年

12
@Aaronaught我发现了一堆多余的“ this”。分散在我的代码中毫无意义且令人讨厌。

12
@kekekela:我唯一要做的就是在构造函数中,在构造函数中这很有意义,因为您实际上是在传递用于初始化成员字段(this.component = component)的值。如果您发现自己在别的范围内存在模棱两可的范围,那么您将拥有“一堆多余的'this'。散布在您的代码中”,那么您的代码编写得不好。
亚伦诺特,2011年

Answers:


14

最初的命名约定为类成员使用m_前缀,这被简化为简单的下划线。您将看到很多使用下划线前缀的较旧的C#Microsoft代码。但是,我曾经在Tech Ed中听到,领先的下划线不符合CLS。我认为这就是为什么他们转向更简单的“一劳永逸”方案的原因。过去(现在不确定)是VB.Net的不区分大小写的名称也不符合CLS。

对于其价值,我仍然使用班级成员的下划线。即使您可以使用此方法消除歧义(此名称与名称相对),但错误仍然存​​在。

您不必执行MS告诉您的所有操作。


1
我认为您已经将“符合CLR”与“符合CLS”混淆了。如果某些内容不符合CLR,则不会编译。CLS只是警告它可能与其他语言不兼容,并且基本上只影响公共成员(从技术上讲,您的程序集外部可见的内容)。
Joel C

@Joel-你是对的。这个问题解决了:stackoverflow.com/questions/1195030/…–
dave

2
我仍然使用“ m_”前缀...
CesarGon 2011年

4
+1“因为您不必执行MS告诉您的所有操作”。自己想一想!
gbjbaanb

1
如果该字段不是protected,则不符合CLS标准private
Rachel

9

localparameter变量以相同的方式命名,因为它们的范围相同

至于私有变量,对此有不同的看法。我一直使用这里找到的标准,该标准指定_在私有变量之前使用前导,尽管作者确实说这_有点争议,Microsoft建议不要这样做。

维基百科指出在C和C ++中

以双下划线或下划线和大写字母开头的名称保留用于实现(编译器,标准库),不得使用(例如__reserved或_Reserved)。

因此,也许这就是Microsoft建议这样做的原因,尽管众所周知,许多Microsoft开发人员_无论如何都使用前缀作为其私有变量。


2
关于具有相同范围(+1)的参数和局部变量的要点。没有人提到。结果是,如果您需要与参数同名的局部变量,则只需使用参数即可。虽然我个人觉得下划线很丑陋和不精确。而this绝对是指当前对象。我不明白对此的仇恨this。是因为被误解了吗?
詹森·S

4

我不能肯定地告诉你为什么他们没有让他们与众不同。除非参与制定标准的人碰巧看到了这个问题,否则没有人可以做到。

许多人通过在实例变量前面加上_或来创建自己的约定m_,但我真的不认为这很重要。您可以从上下文中推断出很多东西,如今,IDE足够聪明,可以为您提供帮助。例如,带有ReSharper插件的Visual Studio将以不同的颜色显示局部变量和实例变量。

如果区分两个作用域确实很重要,则可以使用this.前缀来引用实例变量:

public class Test
{
    private int myInteger;

    void SomeMethod(int myInteger)
    {
        this.myInteger = 10; // sets instance variable to 10
        myInteger = 10; // does not affect the instance variable.
    }
}

如果没有其他任何插件,Visual Studio默认情况下将为您提供Intellisense的帮助:

屏幕截图

(弹出窗口可能仍由ReSharper设置样式,但是ReSharper并未对内置Intellisense的功能添加任何内容,因此,尽管现有的外观可能有些不同,但仍然可以同时使用这两种选择。 )

您还可以使用代码分析工具(例如FxCopStyleCop)来帮助您捕获变量命名和范围的潜在问题。


详细讲解this,我始终喜欢this,因为它肯定指向当前实例,无论您身在何处,因此非常准确。下划线或下划线m约定仅是-可能会或可能不会引用实例变量的约定,并且它们被冗余this。我认为下划线唯一有用的地方是不区分大小写的VB,以区分对象名称和类名称。但这是另一个故事。
詹森·S

4

微软的标准为什么没有使这些保持不同?

微软公司的人们写了一本书,叫做《框架设计准则》,其中解释了许多约定,包括为什么用骆驼装东西,而用帕斯卡装东西。

编辑(添加书中的详细信息):

在书中,他们提到进行可用性研究,以及从收购Turbo Pascal小组中吸取的一些教训。同样,虽然并非所有语言都区分大小写(例如VB),但其他语言也区分大小写(例如C#),所以一种命名方式应该保持一致。不能仅依靠案例的差异来区分项目。如果坚持框架其余部分使用的约定,则将减少开发人员的困惑。

第3章,命名准则。
第3.1节是大写约定。

camelCasing用于参数名称。
PascalCasing用于名称空间,类型和成员名称。如果名称中包含2个字母的首字母缩写词,请将其大写,例如IOStream

3.5节介绍了命名类,结构和接口。
3.6节介绍了命名类型成员。
第3.7节介绍了命名参数。


4
您是否愿意为那些不拥有本书的人总结一下?
克拉米(Kramii)恢复莫妮卡(Monica)2011年

我同意Kramii。总结会很棒!
瓦卡诺2011年

@ Kramil,Vaccano,看来我必须再次从库中将其检出。通常,我只有在开始新工作时才这样做,并且讨论转向命名和编码标准。
Tangurena

1
大声笑,因此“不能仅依靠大小写的差异来区分项目”,然后继续说使用camelCase或PascalCase区分项目。
gbjbaanb

1

因为它们很容易区分,因为它们取决于所写的上下文。

例如,您是否曾经使用过参数作为成员变量?还是将局部变量作为参数?作为局部变量的成员变量如何?

  • 所有成员变量都在类的“主体”中。我真的不赞成在可以this用来将其与具有类似名称的局部变量区分开时,需要在成员前面加上前缀的论点,否则就不需要了。

  • 局部变量也只能在方法范围内或在代码块范围内定义。

  • 参数始终在方法签名中定义。

如果您将所有这些类型的变量混淆或混合在一起,那么您确实应该更多地考虑代码设计,以使其更具可读性或可发现性。给他们比更好,更自我描述的名字myInteger


0

我无法回答您有关Microsoft标准的问题。如果你想有一个标准来区分这些事情,标准我使用PL / SQL参数与前缀的参数名in_out_io_,对于IN-,OUT-,并在出包参数。函数局部变量的前缀为v_


0

我知道的大多数公司都有编码标准,这些标准指定下划线或小写字母m(我假设为“成员”)作为其成员变量的前缀。

所以

_varName

要么

mVarName


2
是的,但是MS禁止成员使用m,这是OP的目标。
Christopher Bibbs,

“大多数公司”不包括Microsoft,即与该问题有关的公司。
亚伦诺特,2011年

1
我没有意识到Micrsoft MSDN是Microsoft的内部编码标准。
JeffO 2011年

1
@JeffO:没错,这是不对的,但是他们的内部编码指南却说了同样的话
亚伦诺特,2011年

0

正如其他人指出的那样,通常可以通过使用范围来分辨使用哪个项目。实际上,您不能将参数和局部变量放在同一范围内,如果要使用私有变量,只需使用this.myInteger。因此,我认为Microsoft不必担心太多,因为您可以根据需要轻松区分它们。

话虽这么说,但令我惊讶的是,还没有人说过,但是忘记了微软及其命名约定(现在有人可能已经说过了,因为我不得不参加一次会议,并且公开而没有提交它)。匈牙利表示法也是从Microsoft开始的命名约定(或者是Xerox?我不记得Simonyi提出它的时候)。我想不出一个我认识的人,直到今天还没有诅咒匈牙利符号的名称。在我工作的地方,我们对此感到非常恼火,以至于提出了自己在内部使用的标准。这对我们来说更有意义,并加快了工作速度(它实际上与Microsoft现在的建议非常接近,但是除私有变量外,所有情况都是帕斯卡情况)。

话虽这么说,微软使用的新标准(骆驼案和帕斯卡案的混合物)还不错。但是,如果您和您的同事不喜欢它,请提出自己的一套标准(总的来说是最好的)。当然,这取决于您的公司是否已有一套标准。如果这样做,请坚持下去。否则,请提出对您和您的同事有效的方法。只要保持逻辑。

自从Aaronaught询问有关Charles Simonyi和匈牙利符号的引用以来,http//en.wikipedia.org/wiki/Charles_Simonyi

http://en.wikipedia.org/wiki/匈牙利语

http://msdn.microsoft.com/zh-CN/library/aa260976(v=VS.60).aspx

http://ootips.org/hungarian-notation.html

http://www.hitmill.com/programming/vb/Hungarian.html

http://web.mst.edu/~cpp/common/hungarian.html

最后两个只是匈牙利表示法的示例,而ootips链接只是一些有关该主题的观点的引文。请注意,还有系统匈牙利表示法,但据我所知,这也受到Microsoft程序员的欢迎(尽管与Simonyi的应用程序版本不同,但我不知道是谁)。


1
1)匈牙利不是Microsoft发明的,并且2)您所指的“匈牙利”是匈牙利类型,而不是语义匈牙利。
亚伦诺特,2011年

我从来没有说过微软提出过它。我实际上说过查尔斯·西蒙尼(Charles Simonyi)提出了它(特别是应用匈牙利表示法的应用程序)。微软大力推动它,但我从未说过他们创建了它(实际上,我说我不确定他是否在施乐或微软时代创建了它)。我以它为例,说明了一家大型公司(Microsoft)建议的处理方式。在所有这些方面,我的观点是,OP不必担心命名惯例,即他不曾为之工作的公司说的是“正确的方式”(除非他在Microsoft工作,在这种情况下他应该关心)。
JaCraig

[需要引用]
Aaronaught

1
嗯,我们不需要引用匈牙利的表示法。[需要的引用]是针对您答案中所有可疑的声明。
亚伦诺特,2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.