我们为成员变量使用哪种前缀?

时间:2020-03-06 14:30:43  来源:igfitidea点击:

毫无疑问,理解代码的关键是为成员变量赋予前缀,以便可以轻松地将它们与"普通"变量区分开。

但是,我们使用哪种前缀?

我一直在使用m_作为前缀的项目上工作,在其他项目上,我们仅使用下划线(我个人不喜欢,因为仅下划线还不够说明性)。

在另一个项目中,我们使用了长前缀形式,其中还包括变量类型。例如mul_是unsigned long类型的成员变量的前缀。

现在,让我知道我们使用哪种前缀(请说明原因)。

编辑:你们大多数人似乎没有成员变量的特殊前缀编码!这取决于语言吗?根据我的经验,C ++代码倾向于使用下划线或者m_作为成员变量的前缀。那其他语言呢?

解决方案

仅下划线。

就我而言,之所以使用它,是因为这就是我的工作场所中编码标准文档所说的。但是,我看不到在变量的开头添加m_或者一些可怕的匈牙利语的意义。极简主义的"仅下划线"使其保持可读性。

mul_示例正朝着Charles Simonyi的Apps Hungarian表示法发展。

我更喜欢保持简单,这就是为什么我喜欢使用m_作为前缀。

这样做使查看原始声明的位置变得更加容易。

没有。我曾经使用下划线,但是在其他人不喜欢它并且从未错过它的项目中被人淘汰。体面的IDE或者体面的内存将告诉我们什么是成员变量,什么不是。我们项目的一名开发人员坚持要放置" this"。在每个成员变量的前面,当我们在名义上属于" his"的代码区域工作时,我们会对他幽默。

如果没有必要,则无,否则下划线。适用于python。

我根本不使用任何前缀。如果我遇到将局部变量或者方法参数与类成员混淆的危险,则方法或者类太长,会从拆分中受益。

这(可以说)不仅使代码更易读和更"流利",而且最重要的是鼓励结构良好的类和方法。最后,它归结为一个完全不同于前缀或者无前缀问题的问题。

更新:好吧,喜好和喜好改变了,不是吗。我现在使用下划线作为成员变量的前缀,因为从长远来看,它已被证明对识别局部变量和成员变量很有帮助。尤其是新的团队成员有时在难以识别的时候会遇到困难。

No doubt, it's essential for understanding code to give member variables a prefix so that they can easily be distinguished from "normal" variables.

我对此主张提出异议。如果语法高亮了一半,那么这并不是最没有必要的。一个好的IDE可以让我们用可读的英语编写代码,并可以通过其他方式向我们显示符号的类型和范围。当插入点位于其中之一上时,Eclipse通过突出显示符号的声明和使用来很好地完成工作。

编辑,谢谢,苗条:Eclipse之类的语法突出显示功能也可以使我们使用粗体或者斜体文本,或者完全更改字体。例如,对于静态内容,我喜欢使用斜体。

另一个编辑:这样想吧;变量的类型和范围是辅助信息。它应该可用并且容易找到,但不要对我们大喊大叫。如果我们使用诸如m_之类的前缀或者诸如LPCSTR之类的类型,那么当我们只想读取代码的主要信息时,这就会变得很混乱。

第三编辑:无论语言如何,均适用。

这有点取决于我们使用的语言。

在C中,我们可以使用'this'前缀引用任何成员,例如'this.val',这意味着不需要前缀。 VB具有与" Me"类似的功能。

在有内置符号表示成员访问权限的语言中,我看不到使用前缀的含义。在其他语言中,我想使用该语言常用的约定是有意义的。

请注意,使用内置符号的好处之一是,我们可以在访问类的属性和方法时使用它,而不会损害它们的命名约定(在访问非私有成员时尤其重要)。使用任何一种指标的主要原因是作为一个标志,它在类中引起了可能的副作用,因此在使用其他成员时,最好使用它,而不管它们是字段/属性/方法/等如何。 。

这确实取决于语言。
我是C ++专家,在所有内容前加下划线有点棘手。在某些情况下(取决于范围),该语言保留了以下划线开头的内容。对于双下划线,或者在下划线后加上大写字母,也有特殊处理。因此,我说只是避免这种混乱,而只需选择其他前缀即可。 IMO表示" m"是可以的。 'm_'有点多,但也不可怕。确实是一个口味问题。

但是请注意那些_leadingUnderscores。我们会惊讶地发现有这么多编译器和库内部组件如此命名,如果我们不太谨慎的话,肯定有发生意外和混淆的空间。拒绝吧。

我更喜欢使用this关键字。
那意味着this.data或者this-> data而不是一些社区相关的命名。

因为:

  • 如今,IDE键入" this。"会弹出intellinsense
  • 在不知道定义命名的情况下对所有人显而易见

BTW在变量前加上字母来表示它们的类型已经过时了,它们已经被优秀的IDE所淘汰,这让我想起了Joel的文章

这取决于我使用的框架!如果我正在编写MFC代码,则使用m_和匈牙利表示法。对于其他内容(通常是STL / Boost),则向所有成员变量添加下划线后缀,而不必担心匈牙利符号。

MFC类

class CFoo  
{  
private:  
    int m_nAge;  
    CString m_strAddress;  
public:  
    int GetAge() const { return m_nAge; }  
    void SetAge(int n) { m_nAge = n; }  
    CString GetAddress() const { return m_strAddress;  
    void SetAddress(LPCTSTR lpsz) { m_strAddress = lpsz; }  
};

STL类

class foo  
{  
private:  
    int age_;  
    std::string address_;  
public:  
    int age() const { return age_; }  
    void age(int a) { age_ = a; }  
    std::string address() const { return address_; }  
    void address(const std::string& str) { address_ = str; }  
};

现在,这两种不同的样式似乎有些奇怪,但是它对我有用,并且编写了很多不使用与MFC本身相同样式的MFC代码,这看起来很丑陋。

我倾向于在C ++中使用m_,但不介意在Java或者C#中将其保留。并且取决于编码标准。对于下划线和m_混合使用的旧代码,我会将代码重构为一个标准(给定合理的代码大小)

使用C#,我已经从'm_'前缀改为下划线,因为'm_'是C ++的传统。

正式的Microsoft准则告诉我们不要使用任何前缀,在私有成员上使用驼峰大小写,在公共成员上使用pascal大小写。问题在于,这与来自同一来源的另一条准则相冲突,该准则指出我们应使所有代码与.NET中使用的所有语言兼容。例如,VB.NET在大小写之间没有区别。

所以对我来说只是一个下划线。这也使通过IntelliSense的访问变得容易,并且仅调用公共成员的外部代码不必看到视觉上凌乱的下划线。

更新:我认为C的" this。"前缀不能解决" Me"问题。在VB中,仍然会看到与" Me.Age"相同的" Me.age"。

我用 @。

:D j / k-但是否取决于语言。如果它具有getter / setter,我通常会在私有成员变量前放置一个_,而get_ / setter的名称将不带_。否则,我通常不使用任何东西。

如果确实有必要给成员变量加上前缀,那么我肯定更喜欢m_而不是下划线。我发现下划线本身会降低可读性,并且可能与C ++保留字混淆。

但是,我确实怀疑成员变量是否需要任何特殊的符号。即使忽略IDE帮助,也不清楚为什么本地变量和成员变量之间会产生混淆。

另一个技巧是命名约定:

所有成员变量均照常命名,没有任何前缀(或者在项目中通常使用" this"。)

但是它们很容易与局部变量区分开来,因为在我的项目中,这些局部变量总是被命名为:

  • aSomething:代表一个对象。
  • someManyThings:对象列表。
  • isAState或者hasSomeThing:布尔状态。

任何不以" a"," some"或者" is / has"开头的变量都是成员变量。

由于VB.NET不区分大小写,因此我的成员变量在其名称的其余部分前都带有下划线和驼峰式大小写。我将财产名称大写。

Dim _valueName As Integer

Public Property ValueName() As Integer

我在这里使用驼峰式的保护套,并像其他许多东西一样强调。我使用下划线是因为我使用Cand时已经习惯在构造函数中避免使用'this'关键字。我使用驼峰式案例方法范围的变体,因此下划线会提醒我当时正在使用的范围。否则,只要我们不尝试添加代码中已经显而易见的不必要信息,我就认为这无关紧要。

大多数时候,我使用python。 Python要求我们使用self.foo才能访问当前类实例的属性foo。这样,就解决了混淆我们正在处理的实例的局部变量,参数和属性的问题。

通常,即使我不喜欢被迫这样做,我还是喜欢这种方法。因此,我理想的做法是不执行此操作,而是在此属性或者self上使用某种形式的属性访问,以获取成员变量。这样,我就不必将元数据的名称弄乱了。

保持一致比什么都重要,因此请选择我们和队友可以达成共识并坚持下去的事情。并且,如果我们所编码的语言有约定,则应尝试遵守该约定。没有比遵循前缀规则不一致的代码库更令人困惑的了。

对于c ++,除了_有时会前缀编译器关键字这一事实,还有另一个原因更喜欢m_。 m代表成员变量。这也使我们能够区分局部变量和其他类别的变量,s_表示静态变量,g_表示全局变量(但当然不要使用全局变量)。

至于IDE将永远照顾注释,IDE确实是我们查看代码的唯一方法吗?差异工具是否具有与IDE相同的语法语法质量?源代码管理修订历史记录工具如何?我们甚至从不将源文件放在命令行中吗?现代的IDE是出色的效率工具,但是无论我们要阅读的上下文如何,代码都应该易于阅读。

对于我自己的项目,我将_​​用作后缀(如上文中的Martin York所述,_作为前缀由C / C ++标准为编译器实现提供存储),而在处理Symbian项目时则使用i。

class SomeClass {
    private int mCount;
    ...
    private void SomeFunction(string pVarName) {...}
}

我给成员变量加上'm'前缀,给参数(在函数中)加上'p'前缀。因此代码如下所示:

我发现这可以快速告诉我们任何变量的基本范围(如果没有前缀,则为局部变量)。另外,在阅读函数时,我们无需考虑传递的内容以及什么是局部变量。

我们使用m_,然后使用经过稍微修改的Simonyi表示法,就像Rob在先前的回复中所说的那样。因此,前缀似乎很有用,并且m_不太麻烦并且易于搜索。

为什么要用符号呢?为什么不仅仅遵循(针对.NET)依赖于名称大小写的Microsoft注释建议呢?

最后一个问题:如前所述,VB.NET对大小写无关。数据库和(尤其是)DBA也是如此。当我必须保持直截了当的customerID和CustomerID(例如C#)时,这会使我的大脑受伤。因此,大小写是一种表示形式,但不是一种非常有效的表示法。

  • 不使用IDE即可提高对代码的人工理解。就像在代码审查中一样-最初我仍然觉得最容易在纸上进行。
  • 是否曾经编写过T-SQL或者其他RDBMS存储过程?在数据库列名称上使用前缀表示法确实很有帮助,特别是对于那些喜欢使用文本编辑器进行此类操作的人而言。

前缀表示法在几种方面具有价值:

简而言之,将前缀作为一种表示法很有用,因为仍然存在无法使用智能IDE的开发环境。考虑一下IDE(一种软件工具),它允许我们提供一些快捷方式(例如智能输入),但不包含整个开发环境。

IDE是一个集成开发环境,就像汽车是运输网络一样:只是较大系统的一部分。我不想遵循"驾车"的习惯,比如呆在有标记的道路上,有时,它只是为了穿越一个空旷的地方而变得更快。依靠IDE来跟踪变量类型,就像需要汽车的GPS在空旷的地方行走一样。最好以便携式形式获得知识(尽管可能有些尴尬,但可能会有" m_intCustomerID"),而不是每次进行小小的改动都会跑回汽车。

也就是说,m_约定或者" this"约定都是可读的。我们喜欢m_,因为它易于搜索,并且仍然允许变量键入跟随它。同意太多其他框架代码活动使用简单的下划线。

在Java中,一种常见的约定是在成员变量前加上" my"和UseCamelCaseForTheRestOfTheVariableName。

private int fooBar;
public int FooBar
{
  get { return fooBar; }
  set { fooBar = value; }
}

我曾经在C ++中使用m_ perfix,但在CI中,更喜欢仅对字段使用驼峰大小写,对其属性使用pascal大小写。

我和不使用前缀的人在一起。

如今,IDE是如此出色,从语法着色,鼠标悬停的工具提示以及易于导航到其定义的信息一目了然,很容易找到有关变量的信息。

这是从变量和命名约定的上下文(例如,lowerCamelCase用于局部变量和私有字段,UpperCamelCase用于属性和方法等)以及布尔值" hasXXXX"和" isXX"之类的东西之上的。

我已经有好几年没有使用前缀了,但是我确实曾经是一个" this"。给怪物加上前缀,但除非绝对必要,否则我已经取消了(谢谢,Resharper)。

TGpHttpRequest = class(TOmniWorker)
strict private
  hrHttpClient  : THttpCli;
  hrPageContents: string;
  hrPassword    : string;
  hrPostData    : string;

我是怪人,我在类名(驼峰式)的开头加上成员变量的前缀。

TGpHttpRequest = class(TOmniWorker)
strict private
  FHttpClient  : THttpCli;
  FPageContents: string;
  FPassword    : string;
  FPostData    : string;

大多数Delphi人只使用F。

无前缀。并且,对于纯功能/基于堆栈的无变量名称。但是,如果我真的要使用副作用,而我又想输出任何东西,那我就使用p->,其中p是传递给函数的参数的外部指针。

__EXTERN_GLOBAL_hungariannotationvariabletypeVendorName-my_member_prefix-Category-VariableName

我认为使用前缀/前缀变得很愚蠢。

考虑mul例子,我的成员变量是无符号长整数,代表乘法指令的操作码。

  • 帮助使用智能感知对成员进行分组。
  • 读取代码时更容易发现成员变量。
  • 难以隐藏具有局部定义的成员变量。

单个_仅用作可视指示符。 (C#)

Symbian使用" i"作为成员的前缀,并使用" a"作为参数的前缀。

我只使用_后缀(如上文所述,前缀_在c / c ++中是保留的)。我之所以喜欢它,主要是因为我讨厌像'aCircle'这样的参数名称,除非绝对必要,否则我也不喜欢写this.circle。 (我只对公共访问成员变量执行此操作,因为我不使用下划线后缀,因为这些变量是cos)。

如果语言支持this或者Me关键字,则不使用前缀,而使用所述关键字。

_而不是this。

我喜欢m_,但只要在代码库中使用约定,我都会很酷。

public class Person {
  private String _name;

  public Person(String name) {
    _name = name;
  }
}

我也使用_而不是this,因为它更短(少了4个字符),并且很好地指示了成员变量。此外,使用此前缀可以避免命名冲突。例子:

public class Person {
  private String name;

  public Person(String name) {
    this.name = name;
  }
}

与此进行比较:

段落数量不匹配