代码之家  ›  专栏  ›  技术社区  ›  Trap

为什么我不能在字段前面加前缀?[闭门]

  •  49
  • Trap  · 技术社区  · 17 年前

    我从来都不是匈牙利符号的爱好者,除非你做了一些低水平的编程,我总是觉得它很没用,但是在每一个C++项目中,我都在执行某种匈牙利符号法,并且使用一些‘匈牙利语’前缀作为字段的My,Syt用于静态,GGI用于全局等等。

    很快我意识到这在C#中是多么无用,并逐渐开始放弃我所有的旧习惯。。。但是“m__”的事情。我仍然在私有字段上使用m_u前缀,因为我发现能够区分参数、局部变量和字段非常有用。

    naming conventions for fields page at MSDN 说我不应该,但没有说明原因(比如谷歌的惯例通常倾向于合理化他们的处方)。

    25 回复  |  直到 11 年前
        1
  •  52
  •   Community Mohan Dere    9 年前

    WizardBar

        2
  •  40
  •   Ðаn    6 年前

    当你应该:

    当你不应该:

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

    m_ 对会员国来说,这确实有帮助。当用其他语言编写代码时,特别是那些没有真正类的语言(比如Javascript、Lua),我不会。

    简言之,我不相信有“对”和“错”的方法。

        3
  •  21
  •   Ðаn    17 年前

    C#3.0中自动实现的属性特性以某种方式减少了对该约定的需求。而不是写作

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

    或

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

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

    public string Name { get; private set; }
    

    因为您不再需要显式的backingstore变量,所以您不再需要为它命名;从而避免了整个讨论。

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

        4
  •  11
  •   Chris    17 年前

    正如一些人所暗示的,MS指南说:

    不要对字段名使用前缀。 区分静态与非静态 领域。

    我恰好同意这一点。前缀会使代码看起来很难看,并用无关紧要的字符浪费空间。话虽如此,通常使用字段来支持字段和属性都具有相同名称的属性(私有字段为camel case,属性为pascal case)。在VB中,这不起作用,因为VB不区分大小写。在这种情况下,我建议使用单个前缀。不多也不少。只是看起来更干净了,伊莫。

        5
  •  11
  •   ScottS    17 年前

    我已经尝试过m_u,s_u,just u,而且根本没有前缀。我已经决定对所有静态变量和实例变量使用u。我认为区分静态变量和实例变量并不重要。从理论上讲,这听起来不错,但在实践中,这不会产生问题。

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

    开始键入foo将同时建议实例变量和属性。在变量前面加下划线可以消除恼人的双重建议,所以我改回使用just ux。

        6
  •  10
  •   Ben S    17 年前

    我试着跟着你走 MSDN .NET library guidelines . 包括 naming guidelines 部分

        7
  •  10
  •   argibson    17 年前

    我更喜欢用下划线而不是“m”来标记属性支持字段(尽管如前所述,.NET 3.0+通过自动属性减少了需要)。首先,当我开始使用它们时,它将它们放在智能感知列表的首位。

    我承认我需要温习一下MSDN的指导原则,这些天事情变化太快了。

        8
  •  10
  •   rball    17 年前

    对于像resharper这样的工具,确实没有理由使用前缀。此外,如果您编写简短的方法,您应该能够非常快速地知道var来自何处。最后,我想我真的看不出有必要区分静态和非静态,因为如果你尝试做一些你不能做的事情,resharper会再次把它画成红线。即使没有resharper,编译器也可能会保存您。

        9
  •  6
  •   Sean    17 年前

    我总是在成员变量前面加上前缀 m_ 和带有 和你说的理由一样。有些人在成员变量前面加下划线,但我总是觉得这看起来有点奇怪(但这只是个人偏好)。

    与我共事的大多数人都使用m_u/s_u前缀。我真的不认为你使用什么太重要,只要你保持一致。

        10
  •  5
  •   Inferis    17 年前

    我从不使用它们。它鼓励草率的编码。 MSDN编码指南,就是它的所在。

        11
  •  4
  •   Nick Westgate    10 年前

    以下是使用ux(而不是m_x)的几个原因。

    (1) 许多BCL的人不顾MS的命名指南这么做。(查看他们的 blog )那些人编写了框架,所以他们有一些值得效仿的好习惯。MSDN上一些最有用的示例代码是由他们编写的,因此使用下划线约定。这是事实上的行业标准。

    (2) 一个下划线是通过简单地读取源代码来消除方法和类级变量歧义的一种明显但不引人注目的方法。它帮助人们理解新(或旧)代码 一瞥 读的时候。是的,您可以将鼠标移到IDE中查看这一点,但我们不应该被迫这样做。你可能想在文本编辑器中阅读,或者我敢说,在纸上阅读。

    (3) 有人说您不需要任何前缀,因为方法会很短,如果需要,稍后可以将字段更改为自动实现的属性。但在现实世界中,方法的长度与它们需要的长度一样长,字段和属性之间存在重要差异(例如序列化和初始化)。

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

        12
  •  4
  •   Ðаn    6 年前

    至于我个人的意见,既然这里需要,我投票赞成你放弃 m_ 完全

    我相信最好的方式是所有成员都参与进来 PascalCased private 成员),并且所有参数都是 camelCased

    而不是 m_MyProperty _MyProperty ,我曾经见过,甚至推广过),使用 MyPropertyValue . 它更容易阅读和理解,更重要的是,它与intellisense中的原始属性名称非常接近。

    归根结底,这就是我喜欢后缀的原因。如果我想访问 使用intellisense您(通常)键入“ My <down-arrow> <tab> “,因为那时你离得够近了 MyProperty MyPropertyValue 你在名单上。如果您想访问 m_MyProperty 使用intellisense,您必须键入“ m_My <tab> ".

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

        13
  •  3
  •   krosenvold    17 年前

    C++和C语言之间有一个重要的区别:工具支持。当你遵循既定的指导方针(或共同的变化),你将得到一个深层次的工具支持,C++从未有过。遵循这些标准,工具可以执行比其他方法更深入的重构/重命名操作。Resharper就是这样做的。因此,请遵守其中一项既定标准。

        14
  •  3
  •   itsmatt    17 年前

    我从不这样做,原因是我[试图]保持我的方法简短。如果我可以在屏幕上看到整个方法,我可以看到参数,我可以看到局部变量,这样我就可以知道类拥有什么,什么是参数,什么是局部变量。

    我通常使用特定的符号命名参数和局部变量,但并不总是这样。如果不前后矛盾,我什么都不是。我依赖于这样一个事实,即我的方法很短,当它们应该只做X时,我会尽量阻止它们做X、Y和Z。

    不管怎样,那是我的两分钱。

        15
  •  3
  •   Magnus    17 年前

    请有人解释一下接口上I-prefix的.NET风格。:)

        16
  •  3
  •   Ðаn    8 年前

    我习惯的是,私人物业的f.ex“string\u name”值很小。公众的名字是“名字”。方法中的输入变量使用小写字母“void MyMethod(string name)”。

    如果你有静态常数,它通常是用大号字母写的。 static const MYCONST = "hmpf" .

        17
  •  3
  •   DavidRR Chris Brandsma    7 年前

    它被称为微软的.NET图书馆指南,但实际上 Brad Abrams's 观点( document here

    人们倾向于赞同大多数人的观点,而不是对某一特定风格有充分的理由。

    重要的一点是评估为什么使用一种特定的风格以及为什么它比另一种风格更受欢迎——换句话说,选择一种风格要有理由,不仅仅是因为每个人都说这是应该做的事情——为自己着想。

    不使用旧式匈牙利语的基本原因是使用了不同的缩写词,每个队都有不同的缩写词,而且很难学习——这很容易通过不缩写来解决。

    随着可用开发工具的更改,样式应该更改为最有意义的样式-但每个样式项都有一个坚实的理由。

    下面是我的风格指南和我的理由——我一直在寻找改进我的风格的方法,以创建更可靠、更易于维护的代码。

    变量命名约定

    我们对变量命名约定都有自己的看法。有许多不同的样式可以帮助生成易于维护的高质量代码——任何支持变量基本基本信息的样式都可以。特定命名约定的标准应该是,它有助于生成可靠且易于维护的代码。不应使用的标准包括: 很难看 微软(即Brad Abrams)表示,不要使用这种风格——微软并不总是能产生最可靠的代码,只要看看Expression Blend中的bug就可以了。 读取代码时,变量名应立即传达有关变量的三个基本事实,这一点非常重要: 其范围 它的类型是 a清楚地了解它的用途

    m_u字段变量 传递给方法的p_u参数 静态变量 类型:如果一个人在实际使用另一种类型时认为自己使用的是特定类型,则可能会发生严重错误。同样,我们不需要鼠标悬停在任何变量上来确定其类型,我们只是假设我们知道其类型,这就是错误的产生方式。

    缩写:缩写是邪恶的,因为它们对不同的开发人员意味着不同的东西。一个开发人员可能认为前导小写“s”表示字符串,而另一个开发人员可能认为它表示有符号整数。缩略语是懒散编码的一个标志——花一点额外的时间,键入全名,让开发人员清楚地知道必须维护代码。例如,“str”和“string”之间的区别仅为三个字符——使代码易于维护并不需要更多的努力。

    自文档化代码:为变量名添加清晰的描述可以让其他开发人员非常容易地阅读和理解代码-使名称易于理解,以便团队经理能够阅读和理解代码,而不必成为开发人员。

    变量名称部件的顺序:建议的顺序是范围类型说明,因为: IntelliSense将对所有相似的作用域进行分组,并且在每个作用域内,IntelliSense将对所有相似的类型进行分组,这使得查找更容易-尝试以另一种方式查找变量 这是一种相当普通的风格,很容易理解 它会通过的

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

    控制结构单行语句 所有控制结构(if、while、for等)的单行语句都应该用大括号括起来,因为添加一个新语句很容易,因为它没有意识到给定语句属于一个控制结构,这将破坏代码逻辑而不会产生任何编译时错误。

    方法异常包装 所有的方法都应该用一个外部的try-catch来包装,这个trap提供了一个恢复、识别、定位、记录和决定是否抛出的地方。正是意外异常导致我们的应用程序崩溃——通过包装每个方法捕获所有未处理的异常,我们保证识别并记录所有异常,并防止应用程序崩溃。这需要更多的工作,但结果是值得的努力。

    压痕

        18
  •  2
  •   rmeador    17 年前

    每当我有选择的时候,我从不使用任何匈牙利疣。这是额外的输入,不能传达任何有意义的信息。任何好的IDE(我根据此功能的存在定义为“好”)都允许您对静态成员、实例成员、成员函数、类型等有不同的语法高亮显示。没有理由用IDE提供的信息来混乱代码。这是避免用注释掉的旧代码弄乱代码的必然结果,因为版本控制系统应该负责这些事情。

        19
  •  2
  •   Guffa    17 年前

    我们选择的代码标准是使用uu作为成员变量的前缀。其中一个原因是它使得在intellisense中很容易找到局部变量。

    在我们同意这个标准之前,我使用了另一个标准。我根本没有使用任何前缀,而是写了 this.memberVariable 在代码中显示我正在使用一个成员变量。

        20
  •  2
  •   Greg Beech    17 年前

    最接近官方指南的是 StyleCop ,Microsoft提供的一个工具,它可以自动分析源文件并检测推荐编码样式中的冲突,并且可以在Visual Studio和/或自动化生成(如MSBuild)中运行。

    我们在我们的项目中使用它,它确实有助于使开发人员之间的代码样式和布局更加一致,尽管需要提醒的是它确实需要时间 相当地

    回答你的问题-它不允许任何匈牙利符号,也不允许任何类似的前缀 m_

        21
  •  2
  •   Jay    17 年前

        22
  •  2
  •   Ðаn    17 年前

    也可能有一些见解可以从中收集 C++编码标准 ( 萨特,赫伯 和 亚历山大·安德烈 , 2004). 第0项的标题是“不要为小事操心。(或:知道什么不应该标准化)。”。

    他们通过说“如果您不能决定自己的命名约定,请尝试…私有成员变量”,稍微触及了这个特定的问题 像这样_ …“(请记住,前导下划线的使用受C++中非常具体的规则约束)。

    然而,在到达之前,他们强调一定程度的一致性“……重要的不是设置规则,而是与文件中已经使用的样式保持一致……”

        23
  •  2
  •   Eric Cosky    17 年前

    当面对这些现实时,使用m_和所有其他匈牙利规则开始有一定的意义,即使有维护开销,因为当查看不熟悉的代码时,只需查找符号类型就可以节省大量时间。当然,现在我们有了智能感知和“去定义”,所以命名约定的主要省时动机已经不存在了。我认为这样做没有多大意义,我通常会尝试遵循.NET库指南,只是为了保持一致,并可能获得更多的工具支持。

        24
  •  1
  •   Ðаn    6 年前

    如果您没有按照特定的准则进行编码,那么应该继续使用实际的 m_ 注释,如果项目编码指南中有这样的说明,则对其进行更改。

        25
  •  0
  •   Mark Stock    17 年前

    发挥作用。

    • 不要使用成员变量。

    如果您确实必须,但仅当您确实必须时,请使用一个且仅一个变量来访问您的应用程序/环境。