在属性中使用的变量是否有任何C#命名约定?

52

假设我们有一个变量,我们想要它命名为 Fubar

假设 Fubar 是一个字符串 (String)!

这意味着我们应该这样定义 Fubar:

public string Fubar;

现在,假设我们想让Fubar拥有一个getter和setter(换句话说,成为C#属性)!

private string Fubar;
public string Fubar_gs
{
    get
    {
        //Some fancy logic
        return Fubar;
    }
    set
    {
        //Some more fancy logic
        Fubar = value;
    }
}

太好了!这一切都很好,但是,如果我想将属性命名为Fubar而不是原始变量该怎么办?

显然,我只需重命名两个变量。但问题是,原始变量的最佳名称是什么?

这种情况下是否有命名约定?


12
请注意,这也适用:public string Fubar{get;set;} - Tim Schmelter
2
只需将私有成员fubar重命名为mfubar、_fubar、fFubar、pfubar,选择一个标准并坚持使用它。 - Tony Hopkinson
12个回答

144

根据Microsoft的命名规范,正确的方式应该是:

private string fubar;
public string Fubar { get { return fubar; } set { fubar = value; } }

然而,许多人更喜欢在私有字段前加下划线,以帮助最小化误将字段首字母大小写错误并在本意为使用属性时却使用了字段,或者反之的可能性。

因此,经常会看到以下写法:

private string _fubar;
public string Fubar { get { return _fubar; } set { _fubar = value; } }

采取哪种方法最终由您决定。默认情况下,StyleCop将强制执行前者,而ReSharper将强制执行后者。

C# 6中引入了声明属性默认值或创建只读属性的新语法,减少了对具有没有特殊逻辑的后备字段的属性的需求在getset方法中。您可以简单地编写:

public string Fubar { get; set; } = "默认值";

或者

public string Fubar { get; } = "只读值";


谢谢你的回答!你不是第一个提供下划线的人,但我必须说,你的回答是最有信息量的!我选择了你的回答,因为它包括标准和普遍接受的做法。 - Georges Oates Larsen
6
根据微软命名指南,其表示“内部和私有字段不受指南的约束”,这与该帖子略有矛盾。 - johnildergleidisson
微软的资本化指南也指出:不要假设所有编程语言都区分大小写,它们并不是。名称不能仅因大小写而不同。正如上面的评论所提到的,对于私有实例字段没有提供任何指导,这真的让属性支持字段的约定由开发人员自行决定。 - thudbutt
实际上,对于 C#6 的只读字段,有一种更简单/更清晰的方法,即 public string Fubar => "只读值"; - dylanh724
@thudbutt - 这个规则仅适用于两个名称都是外部可见的情况(因此可以由不同的CLR语言访问)。 "private"声明(private string fubar;)只能被当前语言编译器(C#)看到,因此与公共声明(public string Fubar ...)在大小写上可能有所不同。 - ToolmakerSteve
实际上这已经不再是事实了。他们并没有明确指定只有私有属性,而是公共属性和私有字段。但是同样的理由也适用于私有属性,因为私有字段更好。https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions - SacredGeometry

10

6
不,请不要使用任何下划线。 - Yoda
9
我认为你的意思是“使用任何下划线都不要,请不要使用”。 - jamheadart
2
下划线前缀的一个好处是,在实例方法内部,很容易就能区分出一个引用是指向私有字段还是方法属性。 - ToolmakerSteve
1
@ToolmakerSteve 是的,使用下划线没有真正的负面影响,我已经使用C# 20多年了,这只是一种偏好(有些人不喜欢)。 - Keith Nicholas
与局部变量相比,对于私有字段和属性来说,使用它们绝对可以提高可读性。此外,微软在其自己的编码规范中也建议正确使用它们。所以,是的,一定要使用它们。https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions - SacredGeometry

7
如果您的私有变量以小写字母开头,您可以右键单击它们并让VS为您生成getter/setter代码;
重构->封装字段...
它将使用大写字母命名属性。

这是一个很好的提示,只需稍作修改即可适用于大写变量或以下划线开头的变量。 - Avada Kedavra
2
不是回答问题的内容,但是因为提供了一个很好的提示,我点了+1。 - Konrad Viltersten

6

逻辑肯定是必须使用的 :( - Georges Oates Larsen

5
好的,框架设计准则文件中指出:

字段命名规范适用于静态的公共和受保护字段。内部和私有字段不在规范之列,成员设计准则不允许公共或受保护实例字段。

✓ DO使用PascalCasing编写字段名称。

✓ DO使用名词、名词短语或形容词来命名字段。

X DO NOT使用前缀来命名字段。

例如,不要使用“g_”或“s_”表示静态字段。

因此,对于私有字段,没有官方推荐。但是,如果您在属性上使用VS 2017快速操作“转换为完整属性”,则会发生以下情况:

VS 2017 quick action "Convert to full property"

因此,可以认为在私有字段前加下划线是比较标准的做法。


另外,如果只有一个静态字段表示类(在Unity中经常看到),通常会使用s_前缀。如果到处都是静态属性,看起来很丑。 - dylanh724

4
不幸的是,目前没有通用的约定。你需要根据实际情况选择适合自己的方法。我在不同的代码库中见过以下所有方法。 方法1
private string _fubar;   //_camelCase
public string Fubar { ... }

方法二

private string fubar;    //camelCase
public string Fubar{ ... }

方法三

private string _Fubar;    //_PascalCase
public string Fubar{ ... }

此外,还有一些框架需要更多的创造力,比如使用属性并将其记录为成员变量,因此使用成员的样式而不是属性的样式(是的,Unity!我在指责你和你的MonoBehaviour.transform的属性/成员)。
为了消除代码库中的歧义,我们使用自制规则:
- 尽量使用更恰当的命名,通常在公共属性中使用的成员具有略微不同的目的。因此,很可能大多数情况下可以找到一个不同且合适的名称;如果不可能,那么它的目的只是为了保存公共属性的状态,那么何不将其命名为nameValue呢? - 如果可能,请使用自动属性。
通过我们的方法,大多数时候我们避免了对下划线“_”产生疑惑,同时拥有了更可读的代码。
private string fubarValue; //different name. Make sense 99% of times
public string Fubar { ... } 

1
我认为方法1是最标准的。有些人不喜欢下划线“_”,但它确实有助于避免意外的大小写不匹配。 - dylanh724
1
@dylanh724 - Approach 1 的另一个好处是,在实例方法内部,很容易就能区分出一个引用是指向私有字段还是方法属性。 - ToolmakerSteve

2
编码规范的好处在于可以选择的种类非常多: 选择一个适合自己的约定并保持一致性。
Microsoft 约定——pascalCase 私有字段和 CamelCase 属性很整洁,但由于拼写错误可能会导致错误。我认为前置下划线约定很烦人,因为每次键入名称时都需要两个额外的按键,但是你不会出现太多拼写错误(或者至少编译器首先捕获它们)。

2
的方式是:
private string _fubar;
public string Fubar
{
    get
    {
        return _fubar;
    }
    set
    {
        _fubar = value;
    }
}

然而,如果只是一个没有额外逻辑的基本getter/setter,你可以直接编写:
public string Fubar { get; set; }

不需要后备变量或任何其他东西。


2
我认为,一个名称更好:
public string Fubar { get; private set; }

1
另一种声明默认值的方法。
    private string _fubar = "Default Value";
    public string Fubar
    {
        get { return _fubar; }
        set { _fubar = value; }
    }

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