C#编码标准:私有成员变量

39

我看到了两种常见的私有成员变量编码标准:

class Foo
{
    private int _i;
    private string _id;     
}
并且
class Foo
{
    private int m_i;
    private string m_id; 
}

我认为后者来自于C++。此外,许多人在成员变量之前指定类型(例如double m_dVal),以表明它是类型为double的非常量成员变量?

C#中的惯例是什么?


@Andrew Hare 不是完全重复,因为我正在询问一般情况,而不仅限于 m_。谢谢您指出链接... - Sasha
4
那个“重复问题”已被关闭为“重复和答案”。这个问题是有效的(我可以补充说,driis的回答非常有帮助)。 - Jon B
12个回答

69

除了你提到的那两种情况,C#中不给私有成员变量添加前缀也非常普遍。

class Foo
{
    private int i;
    private string id; 
}

这是我所使用的,也是Microsoft内部命名指南推荐使用的。

另请参阅.NET 命名指南


15
同意,唯一的例外是当私有成员作为公共属性的后备存储时,我个人会在其前面添加一个下划线字符。 - Joel Coehoorn
28
我更喜欢使用下划线,因为通过变量名称就可以了解其作用范围。 - Jacob Adams
2
我也总是使用下划线前缀来命名属性的后备字段,因为很容易犯错并得到一个...stackoverflow hur ;) - meandmycode
2
至少在Java中,您可以让编译器抱怨成员访问而不使用“this”限定符。我更喜欢“this.x”而不是“_x”(后者仍然含糊不清)。 - Marcel Jackwerth
5
永远不应该将 i 用作属性或字段名称。然而,在使用 for 循环进行迭代时,使用名为 i 的变量进行迭代(甚至使用 j 进行嵌套循环)是标准做法。唯一不这样做的情况是在迭代二维/三维网格时,此时应该使用 xyz - Dan Bechard
显示剩余8条评论

15

正如Brad Abrams:内部编码指南所指出的:

不要为成员变量添加前缀(_m_s_等)。如果你想区分局部变量和成员变量,你应该在C#中使用“this.”,而在VB.NET中使用“Me.”。


21
似乎他们有一个隐含的内部指导方针:不要使用VB :) - Mehrdad Afshari
2
我想他们一定是这样做的。虽然我希望我有一个链接,但我读到过一个建议,在C#中不要仅使用大小写来区分以保持互操作性。 - Steve Brouillard
2
@Steve Brouillard:是的。不过这只针对公共成员。你不应该有两个仅在大小写上不同的公共成员。这不符合CLS标准。 - Mehrdad Afshari
对于指出这适用于公共成员和CLS兼容性的问题,向@Steve表示赞赏。私有成员则有更多的自由度。使用C#或VB.net进行编码。任何其他东西都不应直接访问它们。但确保在整个项目中保持一致性。并始终为接替者编写代码。 - TamusJRoyce
@KonradRudolph 在类成员之间仅使用case作为区分是一种可怕的做法,无论语言是否支持。 - Darryl

15

我认为在这里最重要的原则是保持一致性。如果您喜欢并且它与您现有的代码风格保持一致,可以使用 "_" 或 "m" 前缀。无论您选择什么,都要坚持一贯性。


4
阿们。唯一需要的标准是一致性。 - gbjbaanb

11

我更喜欢使用你的第一个示例或自动属性,这样可以避免在类中定义私有字段:

public String MyString { get; set; }

使用prop片段可以使这些操作非常快。


2
可以工作,除了你不能使自动属性只读...啊好吧,也许我会在C# 5.0中寻找它。 - Michael Meadows
9
你可以通过将集合设置为私有或受保护来使它们变成“只读”:public String MyString { get; private set; } - Erich Mirabal
2
除非它们不是完全只读,否则类方法仍然可以重置它。 - Chadwick
2
一个类方法也可以设置一个私有字段...有什么区别吗? - Daniel Schaffer
2
我猜@Michael的意思是只读,指的是在类外部无法直接修改而不是readonly关键字。这里涉及到英语单词的重载。 :) - blizpasta
是的,我指的是这个:private readonly string foo;public String MyString { get { return foo; } } - Michael Meadows

8
据我所记,从阅读《框架设计指南》(Framework Design Guidelines)中得知,私有成员变量并没有固定的约定,除了不应使用匈牙利命名法和不应大写变量名的第一个字母(使用驼峰命名法)。书中有引用支持您两个示例以及根本不使用任何前缀。个人而言,我更喜欢“m_”前缀。

7

以下是微软提供的一般指导:

http://msdn.microsoft.com/en-us/library/ms229002.aspx

C#中的自动属性非常好用,我在能用的时候都会使用它们,但有些情况下它们并不适用,例如在进行类型或值检查时。

总体上,使用驼峰命名法,不要为变量名添加任何前缀,如下划线或类型前缀。

public int Age {get; set;}

或者

private int age;
public int Age
{
    get { return age; }
    set
    {
        if(value < 0)
            throw new InvalidOperationException("Age > 0");
        age = value;
    }
}

2
不太喜欢在属性的getter/setter中抛出异常。但这是另一回事 :) - Jon B
我同意,这并不是我经常做的事情。更多是为了举例说明。同意,这是一个完全不同的问题。 - andleer
1
请注意,此文档指出:“字段命名指南适用于静态公共和受保护的字段。内部和私有字段不在指南范围内,成员设计指南不允许公共或受保护的实例字段。”因此,没有官方指导。 - richardtallent

6
最好使用项目中已经使用的内容。如果您开始一个新项目,请使用公司中最常用的内容。

16
如果你开始一家新公司,就抛一枚硬币。 :) - ibz

5

我更倾向于使用下划线作为私有非常量非只读字段的前缀。为什么?原因如下: 1. 简单地查看变量,我可以区分字段和局部/参数变量。对所有字段使用“this.”不是一个选项——它太长了。 2. 参数和字段之间存在歧义:

class Foo
{
  private int id;
  public Foo(int id)
  {
    id = id; //Will compile and work fine. But field will not be initialized.
  }
}

1
这种特定情况将会生成一个警告。 - Matthijs Wessels
2
@MatthijsWessels 有多少地方实施构建策略中的0警告? - Noctis
@Noctis 在大多数编辑器中,你会看到一条波浪线。这样你就能得到视觉提示了。 - Matthijs Wessels

5

我个人一直使用的是你提供的第一个例子:

    public class Foo
    {
        private int _i;
        private string _id;
    }

事实上,我的整个团队都在使用这种方式。此外,你提到的m_dVal被称为匈牙利命名法,可以查看维基百科条目了解更多信息。然而,匈牙利命名法实际上违反了我们团队的编码标准,因此我从不使用它。


2

我不喜欢为成员变量添加任何前缀。对于在方法外声明的变量,我使用"this.memberVariableName"来将它们与在方法内声明的变量区分开来。


一样,我更喜欢在前面加上下划线 _ - Zimano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接