为什么我不应该前缀我的领域?

我从来没有成为匈牙利符号的粉丝,我一直觉得它是没用的,除非你正在做一些非常低级别的编程,但是在每一个C ++项目中,我已经执行了某种匈牙利符号策略,它使用了一些“不真正匈牙利”的前缀,如字段,静态,g_和全局等等。

不久,我意识到在C#中有多么无用,并逐渐开始放弃我所有的旧习惯,但是这个'm_'的东西。 我仍然使用私人领域的m_前缀,因为我真的觉得能够区分参数,当地人和领域是非常有用的。

MSDN的字段页面的命名规则说我不应该,但是它没有说明为什么(例如Google的惯例通常倾向于合理化他们的处方)。

是有原因,我不应该或只是一个风格的问题。 如果是后者,前缀通常被认为是不好的风格,我能期待其他人在代码库上的负面反应吗?

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

WizardBar

当你应该:

  • 当你的项目编码准则说你应该

当你不应该:

  • 当你的项目编码准则说你不应该

如果你还没有任何指导方针,你可以自由select你或你的团队想要什么,并感到最舒服。 就个人而言,在编码C ++时,我倾向于使用m_作为成员,这确实有帮助。 当用其他语言进行编码时,特别是那些没有真正类的语言(比如Javascript,Lua),我不这样做。

总之,我不相信有一个“正确”和“错误”的方式。

C#3.0中的自动实现的属性function不需要这种约定。 而不是写作

 string m_name; public string Name { get { return m_name; } } 

要么

 string _Name; public string Name { get { return _Name; } } 

(或任何其他惯例),你现在可以写

 public string Name { get; private set; } 

既然你不再需要显式的后备存储variables,你不必再为它提供一个名字; 从而避免了整个讨论。

显然,当你确实需要显式的后台存储来执行validation时,这个参数不适用。

正如一些人所暗示的,MS准则说:

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

我恰好同意这一点。 前缀使您的代码看起来丑陋,浪费空间与无关紧要的字符。 话虽如此,通常使用字段来支持字段和属性名称相同的属性(私有字段是骆驼大小写,属性是pascal大小写)。 在VB中,这是行不通的,因为VB不区分大小写。 在这种情况下,我build议使用单个_前缀。 没有更多,不能less。 它看起来更干净,恕我直言。

我已经尝试过m_,s_,只是_,并且根本没有前缀。 我已经决定对所有静态和实例variables使用_。 从实例variables中区分静态variables并不重要。 理论上听起来不错,实际上这不会造成问题。

一位同事曾经提出了一个令人信服的论据来消除所有的前缀,我们在一个项目上尝试了这个项目。 我把它推进到我的下一个项目,并且变得恼火,它与Intellisense“干涉”。 当你有以下情况

 int foo; public int Foo { get { return foo; } } 

开始键入foo将build议实例variables和属性。 用一个下划线前缀variables消除了恼人的双重build议,所以我切换回使用_。

我尝试按照MSDN .NET库准则 。 它们包括命名指南部分。

显然,这些是次要的项目准则。

我更喜欢用下划线标记属性后台字段(尽pipe正如已经提到的.NET 3.0+减less了对自动属性的需求),而不是“m”。 当我使用它们时,它将它们放在InteliSense列表的顶部。

我承认我需要在MSDN的指导方针上进行修改,现在的情况可能会变得如此之快。

有了像resharper这样的工具,前缀真的没有任何理由。 另外,如果你写简短的方法,你应该能够很快地告诉var来自哪里。 最后,我想我真的不会看到有必要区分一个静态的,因为如果你尝试做一些你无法做到的事情,resharper将会红线。 即使没有resharper,你可能会被编译器保存。

我总是用成员variables的前缀m_和静态variabless_出于同样的原因,你说。 有些人在成员variables前加一个下划线,但是我总是觉得这有点奇怪(但这只是个人喜好)。

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

我从不使用它们。 它鼓励潦草的编码。 MSDN编码准则,这是在哪里。

以下是使用_(而不是m_)的几个原因。

(1)许多BCL家伙尽pipeMS的命名指南。 (查看他们的博客 。)那些人写框架,所以他们有一些值得复制的良好习惯。 MSDN上一些最有用的示例代码是由它们编写的,因此使用下划线约定。 这是一个事实上的行业标准。

(2)单一的下划线是通过简单阅读源头来消除方法和类级variables的明显而不显眼的方法。 它可以帮助人们在阅读时了解新的(或旧的)代码。 是的,你可以通过鼠标在IDE中查看,但是我们不应该被迫。 你可能想用文本编辑器阅读,或者我敢说,在纸上。

(3)有人说你不需要任何前缀,因为方法会很短,如果需要的话,可以将该字段更改为自动实现的属性。 但是在现实世界中,方法只要是需要的,字段和属性之间就有重要的区别(例如序列化和初始化)。

脚注:m_中成员的“m”在我们的用法中是多余的,但是它是小写的,因为这些旧命名约定中的一个概念是,以大写字母开头的types名称和以小写字母开头的实例名称。 这不适用于.NET,所以它是双重冗余的。 匈牙利符号有时也适用于旧的C编译器(例如整型或指针转换和算术),但即使在C ++中,它在处理类时也是有用的。

C ++和C#之间有一个重要的区别:工具支持。 当您遵循既定的指导原则(或常见变体)时,您将获得C ++从未有过的深层次的工具支持。 遵循标准允许工具进行更深层次的重构/重命名操作。 Resharper这样做。 所以坚持一个既定的标准。

正如@John Kraft所说,没有“正确的”答案。 MattJ是最接近的 – 你应该始终遵循你公司的风格指引。 当在罗马,等等。

至于我个人的意见,既然这是要求的,我投票决定完全m_

我相信最好的风格是所有成员都是PascalCased ,不pipe可见性如何(这意味着即使是private成员),所有参数都是camelCased 。 我不打破这种风格。

我可以理解前缀属性后台商店的愿望; 毕竟你必须区分领域和财产,对吧? 我同意,你必须。 但是使用后期修复。

而不是m_MyProperty (或者甚至_MyProperty ,我已经看过,甚至曾经提过一次),使用MyPropertyValue 。 阅读和理解起来更容易 – 更重要的是,它在智能感知中接近您的原始属性名称。

最终,这就是我更喜欢后缀的原因。 如果我想使用intellisense来访问MyPropertyValue你通常会input“ My <down-arrow> <tab> ”,因为那时你足够接近,只有MyPropertyMyPropertyValue在列表中。 如果你想使用intellisense访问m_MyProperty ,你必须input“ m_My <tab> ”。

这是关于按键经济,在我看来。

我从来不这样做,原因是为了尽量缩短我的方法。 如果我能在屏幕上看到整个方法,我可以看到这些参数,我可以看到当地人,所以我可以告诉class级拥有什么,什么是参数或本地。

我通常使用特定的符号来命名我的参数和当地人,但并不总是如此。 如果不矛盾,我什么也不是。 我依靠的是我的方法很短,并且试图阻止他们做X,Y和Z时,他们应该只做X.

无论如何,这是我的两分钱。

除非我用vi或Emacs来编辑代码,否则IDE会照顾到我的成员差异显示,所以我很less使用任何特殊的约定。 这也适用于与I或C类的接口的前缀。

有人请在接口上解释I-prefix的.NET风格。 🙂

我习惯的是私人财产得到小的下划线f.ex“string_名称”。 公众获得“名”。 和方法中的inputvariables得到了小写字母“void MyMethod(string name)”。

如果你有静态的const,通常是用大写字母来写的。 “static const MYCONST =”hmpf“。

每当我有select的时候,我都不会使用任何匈牙利疣。 这是额外的打字,并没有传达任何有意义的信息。 任何好的IDE(和我定义“好”基于这个function的存在,等等)将允许你有不同的语法高亮静态成员,实例成员,成员函数,types等。没有理由混乱你的代码与IDE可以提供的信息。 这是一个必然的结果,因为你的版本pipe理系统应该对这些东西负责。

最好的方法是与同事达成一致,并坚持下去。 它不一定是最适合每个人的方法,只是同意一种方法比你真正同意的方法更重要。

我们为代码标准select的是使用_作为成员variables的前缀。 其中一个原因是它使得在智能感知中很容易find局部variables。

在我们就这个标准达成一致之前,我用了另外一个 我根本没有使用任何前缀,并在代码中写入this.memberVariable来显示我正在使用成员variables。

用C#3中的属性速记,我发现我使用很less显式的成员variables。

我相信我会为此而惹火,但是这样做。

这被称为微软的.NET库的指导方针,但这真的是布拉德·亚当斯的观点 – 有其他意见有正当理由。

人们倾向于大多数人的观点,而不是具有特定风格的良好的理由。

重要的一点是要评估为什么使用特定的风格,为什么比另一种风格更受欢迎 – 换句话说,select风格的原因不仅仅是因为每个人都认为是要做的 – 要为自己着想。

不使用旧式匈牙利语的根本原因是使用了缩写,这对每个团队来说都是不同的,也很难学习 – 这很容易通过不缩写来解决。

随着可用的开发工具的改变,风格应该改变为最有意义的东西 – 但是对每个风格项目都有一个坚实的理由。

下面是我的风格指南,我的理由 – 我一直在寻找方法来改善我的风格,以创build更可靠,更容易维护的代码。

variables命名约定

我们都有我们对variables命名约定的看法。 有许多不同的风格将有助于生成易于维护的高质量代码 – 任何支持variables基本信息的风格都可以。 特定命名约定的标准应该是它有助于生成可靠且易于维护的代码。 不应该使用的标准是:这是丑陋的微软(即布拉德·亚当斯)说,不要使用这种风格 – 微软并不总是产生最可靠的代码,只要看看在Expression Blend的错误。 阅读代码时,variables名应当立即传达关于variables的三个基本事实,这一点非常重要:它的作用域是清楚地理解Scope的用途:Microsoftbuild议完全依靠IntelliSense。 智能感知是真棒; 然而,一个简单的不会鼠标hover在每个variables上来看它的范围和types。 假设一个variables在一个范围内,它不会造成重大错误。 例如,如果引用variables作为参数传入,并且在局部范围内被更改,那么在方法返回后可能不需要更改。 如果一个字段或一个静态variables在局部范围内被修改,但是一个人认为它是一个局部variables,则会导致意外的行为。 因此,能够只查看一个variables(而不是鼠标hover)并立即知道它的范围是非常重要的。

build议使用以下表示范围的样式。 然而,只要清楚一致地指出variables的作用域,任何样式都是完全可以的:m_字段variables传递给方法的p_参数s_ staticvariables局部variablestypes:如果人们认为他们正在使用特定types,则会发生严重错误他们实际上正在使用不同的types – 再一次,我们只是不会鼠标hover在variables上来确定它的types,我们只是假设我们知道它的types是什么,而错误是如何产生的。

缩略语:缩写是邪恶的,因为它们对不同的开发者可能意味着不同的东西。 一个开发者可能会认为一个主要的小写“s”意味着string,而另一个可能认为它是有符号的整数。 缩写是懒惰编码的标志 – 花费一些额外的时间并input完整的名称,以便向需要维护代码的开发人员说明。 例如,“str”和“string”之间的区别只有三个字符 – 使代码易于维护并不需要太多的努力。

内置数据types的通用和明确的缩写是可以接受的,但必须在团队内标准化。

自我logging代码:为variables名添加清晰的描述使得其他开发人员很容易阅读和理解代码 – 使得名称变得易于理解,团队pipe理者可以在不作为开发人员的情况下阅读和理解代码。

variables名称部分的顺序:build议的顺序是scope-type-description,因为:IntelliSense会将所有相似的作用域分组,并且在每个作用域内,IntelliSense会将所有类似的types组合在一起,使查找变得容易 – 尝试以另一种方式findvariables。看到和理解的范围,看到和理解的types这是一个相当普遍的风格和易于理解它会通过FxCop

示例:以下是一些示例:m_stringCustomerName p_stringCustomerDatabaseConnectionString intNumberOfCustomerRecords或iNumberOfCustomerRecords或integerNumberOfCustomerRecords这些简单的规则将显着提高代码的可靠性和可维护性。

控制结构单行语句所有的控制结构(if,while,for等等)单行语句都应该总是用大括号包装,因为添加一个新的语句并不意味着一个给定的语句属于一个控制结构打破代码逻辑,不会产生任何编译时错误。

方法exception包装所有的方法应该包装一个外部的尝试抓住哪个陷阱,提供一个地方来恢复,确定,定位,logging,并作出决定抛出与否。 这是意外的exception,导致我们的应用程序崩溃 – 通过包装每个方法捕获所有未处理的exception,我们保证识别和logging所有exception,并防止我们的应用程序崩溃。 这需要多一点工作,但结果是值得的努力。

缩进缩进不是主要问题; 但是,build议使用四个空格而不使用制表符。 如果打印代码,第一个打印机选项卡通常默认为8个空格。 不同的开发者倾向于使用不同的标签大小 微软的代码通常缩进4个空格,所以如果使用任何微软的代码并且使用4个以外的空格,那么代码将需要重新格式化。 四个空间使得它简单和一致。

我不再使用这种风格。 它的开发是为了帮助您快速了解如何使用variables。 较新的开发环境让您通过将鼠标hover在variables上来查看信息。 如果你使用这些新的工具,它的需求已经消失。

在C / C ++中,这个符号的好处是使得查看符号的types变得更容易,而不必去search声明。 这些样式在Intellisense和“Go to Definition”到来之前就已经出现了,我们经常不得不去鹅卵石寻找声明,谁知道有多less个头文件。 在一个大型的项目中,这可能是一个很大的烦恼,在查看C源代码时已经够糟了,但是在使用混合程序集+源代码和原始调用堆栈进行取证时更是如此。

面对这些现实时,使用m_和所有其他的匈牙利规则,即使在维护开销的情况下也开始有意义,因为在查看不熟悉的代码时,查找符号的types会节省多less时间。 当然,现在我们有Intellisense和“Go to Definition”,所以这个命名约定的主要时间节约动机已经不存在了。 我不认为这样做有太多的意义,我一般都试图去与.NET库的准则,以保持一致,可能获得更多的工具支持。

与官方指南最接近的是StyleCop ,它是Microsoft的一款工具,可以自动分析源文件,并从推荐的编码风格中检测违规行为,并且可以从Visual Studio和/或自动构build(如MSBuild)运行。

我们在我们的项目中使用它,它有助于使开发人员之间的代码风格和布局更加一致,但是要注意,它需要相当多的习惯!

要回答你的问题 – 它不允许任何匈牙利符号,也没有任何前缀像m_ (实际上,它根本不允许使用下划线)。

C ++编码标准Sutter,HerbAlexandrescum Andrei ,2004)中也可能得到一些洞察力。 项目#0的标题是“不要让小东西stream汗(或者:知道不要标准化”)。

他们通过说“如果你不能自己决定你的命名约定,尝试…私有成员variablesthisThis_ …”(请记住使用前导下划线在C ++中受到非常特定的规则)。

但是,在到达之前,他们强调一定程度的一致性“…重要的是不要设置规则,而只是为了与文件中已经使用的风格一致…”

如果你没有按照特定的指导方针进行编码,你应该继续使用你的实际m_符号,如果项目编码指导方针是这样的话,就改变它。

有function。

  • 不要使用全局variables。
  • 不要使用静态variables。
  • 不要使用成员variables。

如果你真的必须,但是只有你真的必须使用一个且只有一个variables来访问你的应用程序/环境。