【问题标题】:C# Field Naming Guidelines?C# 字段命名准则?
【发布时间】:2010-07-06 14:00:25
【问题描述】:

我将自己编写一些 C# 代码,但我想确保我遵循最广泛接受的命名约定,以防我想聘请其他开发人员、发布我的代码或出售我的代码。现在我正在遵循微软设定的命名约定,因为它们似乎是最广泛接受的。他们没有提到的一件事是为私有字段命名。在大多数情况下,我看到它们以camelCase 命名,例如受保护的字段,但是这给我带来了一个问题,因为参数名称应该在camelCase 中。以下面的构造函数为例:

public GameItem(string baseName, string prefixName, string suffixName)
{
    //initialize code
}

现在,如果我对私有字段也使用 camelCase,则会出现命名冲突,除非我使用“this”来访问类字段(我认为这违反了大多数标准,更不用说意味着更多的输入)。一种解决方案是给参数一个不同的名称,但是给相同的数据 2 个不同的名称在逻辑上没有意义。我知道的唯一其他在 C++ 编码中很常见的解决方案是在开头给私有成员一个下划线(_camelCase)。 C# 编码是否普遍接受该解决方案?这个问题是否有另一种解决方案(比如只使用属性(使用 PascalCase)来访问字段,即使在类本身中也是如此)?

【问题讨论】:

  • 选择一个并保持一致!这才是最重要的......
  • 我将“this”用于私有字段。
  • 我使用this 或带有protected set 的公共属性,并且它们的首字母大写。如果可以,请查看 M$ FxCop。
  • 开始更多地考虑它,并且始终通过属性访问它们可能更有意义。我认为这有两个原因:1.所有关于如何访问字段的代码的一致性和 2.如果需要添加验证检查,我将不得不切换我的所有代码以使用属性,所以最好事先这样做。你怎么看待一直使用属性?

标签: c# naming-conventions


【解决方案1】:

_camelCase 字段在我看到的情况下很常见(这是我们在我们的地方使用的,Microsoft prefer for the .NET Runtime)。

我个人使用这个标准的理由是,输入_ 比this. 更容易识别私有字段

例如:

void Foo(String a, String b)
{
    _a = a;
    _b = b;
}

对比

void Foo(String a, String b)
{
    this.a = a;
    this.b = b;
}

我发现第一个更容易键入,它可以防止我意外地分配给名为a 而不是this.a 的参数。 Code Analysis 可维护性规则强化了这一点:

  • CA1500 变量名不应与字段名匹配。

我的另一个原因是,this. 是可选的(Visual Studio / Code 会提示您删除它们),如果它不与局部变量或参数名称冲突,则更难知道您正在使用哪个变量。如果您在所有私有字段的开头都有一个_,那么您始终知道哪个是字段,哪个具有本地范围。

【讨论】:

  • 微软不建议 _camelCase 用于私有字段 (msdn.microsoft.com/en-us/library/ta31s3bc(v=VS.71).aspx)。如果类和方法范围之间的命名冲突,您可以使用 this 关键字来引用类成员。这也是 Resharper 默认建议的...
  • 我同意将 _camelCase 用于模块级变量或属性变量。但正如 João Angelo 所说,最重要的是保持一致。这不是关于标准是什么,而是你拥有它们并执行它们。 Koen - Resharper(当然在 v5 中)使用 _camelCase。
  • _我们 _don't _need _your _underscores _here
  • 如果您启用 .NET Framework 源代码单步执行,或者如果您使用 CLI 反编译器工具(例如 Reflector 或 ILSpy)查看框架源代码,您会注意到甚至 Microsoft 也开始遵循此指南来自 .NET 3.0+。
  • @DaveShaw 新程序集中定义的任何类。例如System.Windows.DependencyProperty(在WindowsBase上)在_camelCase中有几个私有字段。
【解决方案2】:

关注Microsoft Naming Guidelines。 guidelines for field usage 表示它应该是驼峰式,而不是前缀。请注意,一般规则是没有前缀;具体规则是不用前缀来区分静态和非静态字段。

不要将前缀应用于字段名称或静态字段名称。具体来说,不要对字段名称应用前缀来区分静态字段和非静态字段。例如,应用 g_ 或 s_ 前缀是不正确的。

和(来自General Naming Conventions)

请勿使用下划线、连字符或任何其他非字母数字字符。

编辑:我会注意到文档并没有具体说明 private 字段,而是指出 protected 字段应该是驼峰式的。我想您可以从中推断出任何私有字段的约定都是可以接受的。当然,公共静态字段不同于受保护的(它们是大写的)。我个人的观点是,受保护/私有在范围上的差异不足以保证命名约定的差异,尤其是当您似乎想要做的只是将它们与参数区分开来时。也就是说,如果您遵循受保护字段的准则,则必须在这方面与私有字段不同地对待它们,以便将它们与参数区分开来。 在提到类中的类成员时,我使用this 来明确区分。

编辑 2

我采用了我当前工作中使用的约定,即为私有实例变量添加下划线前缀,并且通常仅使用 PascalCase(通常是自动属性)将受保护的实例变量作为属性公开。这不是我个人的偏好,但我已经习惯了,并且可能会遵循它,直到出现更好的东西。

【讨论】:

  • 命名准则只关注外部可见的标识符。
  • OK 哪个更正确:this.employee this._employee 还是 this.m_employee?
  • @hellboy 查看我的更新我现在使用下划线前缀,通常不再使用 this.
  • > 内部和私有字段不包含在指南中
【解决方案3】:

通常有两种广泛使用的方式来命名字段(总是使用 camelCase):

使用下划线前缀

void F(String someValue) {
  _someValue = someValue;
}

使用this. 访问字段并避免名称冲突

void F(String someValue) {
  this.someValue = someValue;
}

我个人更喜欢后者,但我会使用我工作的组织制定的任何约定。

【讨论】:

    【解决方案4】:

    简答:使用_privateField,即在私有字段中使用前导下划线。

    长答案:这里是...

    很久以前,Microsoft 曾经建议将camelCase 用于字段。见here。请注意该文档的创建时间是 2008 年 10 月 22 日。很古老。

    然而,微软最近的代码库描绘了一幅不同的画面。

    1. 查看 .NET Runtime GitHub 存储库的C# Coding style。 #3 是讨论的重点。这是相关部分

      我们将_camelCase 用于内部和私有字段,并尽可能使用readonly。

    2. 还可以查看 Coding style of Roslyn repository,它明确表示它遵循 .NET 运行时的约定。
    3. 再看看.NET Standard contributing page,它还说(至少现在)遵循与.NET CoreFX 相同的指南,这是.NET 运行时的前身。
    4. consolidation 之前,CoreCLR 也建议遵循与 CoreFX 相同的指南。
    5. 即使WinForms repo 也提到使用相同的标准。
    6. 我想我已经说得够多了。因此,总而言之,如果您想遵循 Microsoft 建议的指南,我想您知道该怎么做;对私有字段使用前导下划线,例如:_privateField。

    我的意见:我个人也更喜欢在我的私有字段中使用前导下划线 - 使它很容易区分,而不需要 this。

    【讨论】:

    • 我明白你在说什么.. 但是为什么 Visual Studio CTRL + . 构造函数变量上的自动完成功能会 this.private = private; 呢?然后在课堂的其余部分,很明显,当我做neo4jRepository 时是neo4jRepository - 那么_neo4jRepository 如何更清楚。我不明白它如何使它更容易区分。如果你可能使用非 DI 的东西,比如对一件事进行计数,而对另一件事使用计数的方法.. 是的 _count 那么意味着这个计数。但是到底为什么每个人都用 DI 来做这件事。我的眼睛在流血
    • 这是约定俗成的问题,仅此而已。当您遵循约定时,更容易毫无困难地理解代码的意图——它可以是任何约定,只要您遵守它。由于越来越多的人已经一贯地使用这个约定,你最好习惯它,否则你的眼睛只会更痛;-)
    • 是的,很好的约定,尤其是 C# 8 下划线 _ 将被用于丢弃变量。祝你好运,不要混淆(开始使用 __ ?叹息)。这种过度使用下划线以避免在构造函数中输入this.(即使VS自动在2次键盘敲击中为您生成此代码)实际上导致了指数级的更多输入,因为在整个类中您必须输入_不必要的。当您有隐藏类变量的方法时,我会使用_。框架设计师的正当理由……而不是 S.O.L.I.D 软件开发人员。只是我的意见。
    • 我不明白您如何将 throw away 变量 _ 与以 _ 开头的字段联系起来。前者只是一个下划线,在特定的上下文中使用,而后者后面有更多的字符。顺便说一句,_ 作为变量名不是 C#8 的东西,它是 dates back even earlier。
    • 避免_?的更多理由
    【解决方案5】:

    在我们的商店中,我们使用 Microsoft 建议的私人会员指南开始了我们的第一个 C# 项目,即

    camelCaseFieldName
    

    但我们很快就混淆了私有成员和参数,并切换到

    _camelCaseFieldName
    

    这对我们来说效果更好。

    私有成员通常具有在方法调用之外持续存在的状态 - 前导下划线往往会提醒您这一点。

    另请注意,对属性使用 AutoVariable 语法可以最大限度地减少对私有支持字段的需求,即

    public int PascalCaseFieldName { get; set;}
    

    如需了解(大部分)遵循 MS 指南的简洁标准,请查看 net-naming-conventions-and-programming-standards---best-practices

    【讨论】:

    • 请注意,自动属性仍然使用私有支持字段,您只是将其创建委托给编译器,而不是您自己声明它。有趣的是 - 为支持字段生成的名称非常奇怪。例如:属性Int32 Count { get; set; } 的自动生成的支持字段将命名为<Count>k__BackingField。这与任何命名准则相去甚远,它甚至使用了对 C# 中的标识符无效的字符(但这没关系,因为除非您使用反射,否则您通常永远不会看到这一点)。
    • @FlorianS.:这也是这个奇怪名字的原因,他们不想引入与自动生成和不可见变量的命名冲突。
    【解决方案6】:

    如前所述,Microsoft Naming Guidelines 剂量不涵盖私有字段和局部变量命名。而且您在 Microsoft 内部也找不到一致性。如果您在 Visual Studio 中生成类或一次性模式,它将创建类似

    public MyClass(int value)
    {
        this.value = value;
    }
    

    或

    private bool disposedValue = false; // To detect redundant calls
    
    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            ...
        }
    }
    

    幸运的是,微软开放了越来越多的代码,所以让我们看看他们的 repos,例如ASP.NET Core MVC

    private readonly IControllerActivator _controllerActivator;
    private readonly IControllerPropertyActivator[] _propertyActivators;
    

    或.NET Core

    private T[] _array;
    

    您可能会说,它实际上不是 Microsoft,而是 .NET Foundation。有道理,我们来看看Microsoft repos:

    private readonly MetricSeries zeroDimSeries;
    

    但这里是ancient Microsoft implementation of MVC

    private IActionInvoker _actionInvoker;
    

    所以没有任何关于私有字段命名的通用做法或官方指南。只需选择一个你喜欢的并坚持下去。

    【讨论】:

      【解决方案7】:

      最重要的是选择一个标准并坚持下去。在IDesign 上查看 iDesign 的 C# 编码标准(这是右侧的链接)。这是一个很棒的文档,涵盖了命名准则等内容。他们建议对局部变量和方法参数使用驼峰式大小写。

      【讨论】:

      • 我们的 .NET 开发人员也与 IDesign 编码标准合作。朱瓦尔不会错的,对吧? :)
      【解决方案8】:

      我们使用StyleCop 在整个代码中强制保持一致性。 StyleCop 是 used within Microsoft 强制执行一组通用的最佳实践,用于 C# 源代码的布局、可读性、可维护性和文档。

      您可以在构建时运行 StyleCop 并让它生成样式违规警告。

      要回答您的具体问题,私有字段应采用驼峰命名法并以“this”为前缀。

      【讨论】:

        【解决方案9】:

        Philips Healtcare C# Coding Standard

        MSDN - Eric Gunnerson

        编辑:我使用“this”关键字来访问 C# 和 Java 中的非静态成员。

        【讨论】:

          【解决方案10】:

          按照 Microsoft 的命名约定,私有字段应以下划线为前缀。

          例如:

          private int _myValue;
          

          祝你好运!

          【讨论】:

          • 微软在其最佳实践指南中推荐。
          • FxCop 不关心内部标识符,但对外部使用有益的应该对内部标识符有益。此外,下划线看起来很难看(恕我直言)。下划线前缀不适用于某些要集成到框架和互操作的语言。还有一个包含 15 个名为 _whatever 的私有字段的类会减慢智能感知输入速度。
          • @Ian P:我没有看到在任何地方使用下划线前缀的建议。约定只提到下划线不要在类等中使用它们。
          • 我发现了不使用前缀的做法:Do not apply a prefix to field names or static field names. Specifically, do not apply a prefix to a field name to distinguish between static and nonstatic fields. For example, applying a g_ or s_ prefix is incorrect. 他们没有特别提到非公共字段,但你明白了。链接:msdn.microsoft.com/en-us/library/ta31s3bc.aspx
          • 对我来说,这表明它与匈牙利符号有关,这不是我所说的。如果您阅读任何微软员工的博客,它们(嗯,我见过的所有)都在私有字段前加上 _。
          【解决方案11】:

          我用来区分私有类变量和方法参数的约定是:

          private string baseName;
          private string prefixName;
          private string suffixName;
          
          public GameItem(string baseName, string prefixName, string suffixName)
          {
              this.baseName = baseName;
              this.prefixName = prefixName;
              this.suffixName = suffixName;
          }
          

          【讨论】:

            【解决方案12】:

            我对此也有疑问,然后我决定查看微软的 github 代码。我看过的几乎所有源代码都有下划线用于私有字段。

            https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/ 文档似乎没有提到这种用法。

            【讨论】:

              【解决方案13】:

              看看 ReSharper。它将突出显示您的姓名不符合普通准则的所有地方,您可以对其进行自定义。另外,当然还有很多其他的生产力增强功能。

              【讨论】:

                【解决方案14】:

                我这样做;它非常符合 MSDN。

                class MyClass : MyBaseClass, IMyInterface
                {
                    public event EventHandler MyEvent;
                    int m_MyField = 1;
                    int MyProperty {
                        get {
                            return m_MyField;
                        }
                        set {
                            m_MyField = value;
                        }
                    }
                
                    void MyMethod(int myParameter) {
                        int _MyLocalVaraible = myParameter;
                        MyProperty = _MyLocalVaraible;
                        MyEvent(this, EventArgs.Empty);
                    }
                }
                

                这里有更多细节: http://jerrytech.blogspot.com/2009/09/simple-c-naming-convention.html

                【讨论】:

                • 我认为这是很久以前的指导方针......目前,绝对不是!我也不喜欢隐式访问修饰符。
                • 是的,这是真的。大多数编码人员会跳过 _、m_ 和 s_ 前缀。再者,没有人不能通过名称来判断 var 的范围。事实上,大多数编码人员已经将他们的命名简化为 thisName 和 ThisName ,仅此而已。对我来说,这是不对的。但我承认这是最常见的。
                • IMO,除了是一个过时的约定之外,它也很丑陋。
                【解决方案15】:

                我用 VB 做的比 C# 多得多,所以我想我把一些做法(偏见?)从前者带到了后者。

                我喜欢属性的私有字段有一个前导下划线 - 尤其是在 C# 中,因为它区分大小写(谁的想法是 that 反正?)我为模块/类范围的变量添加前缀也用“m”来加强他们的范围。

                如果你不喜欢这样,你真的不会喜欢这样:我通常也使用类型前缀(属性字段除外) - “o”代表对象,“s”用于字符串,"i" 用于整数等。

                我不能用经过同行评审的论文或其他任何东西来捍卫这一点,但它对我们有用,这意味着我们不会被大小写或字段/参数混淆所困扰。

                所以...

                Class MyClass
                
                    Private msClassVariable  As String = ""
                
                    Private _classProperty As Integer = 0
                    Property Readonly ClassProperty() As Integer
                        Get
                            Return _classProperty
                        End Get
                    End Property
                
                    Sub New()
                
                        Dim bLocalVariable As Boolean = False
                        if _classProperty < 0 Then _classProperty = 0
                        msClassVariable  = _classProperty.ToString()
                        bLocalVariable = _classProperty > 0
                    End Sub
                
                End Class
                

                【讨论】:

                  【解决方案16】:

                  就个人而言,我通过前缀“the”来修改参数名称,例如 theSamplingRate。对我来说,这很有意义:)

                  【讨论】:

                    【解决方案17】:
                    private string baseName; 
                    private string prefixName; 
                    private string suffixName; 
                    
                    public GameItem(string _baseName, string _prefixName, string _suffixName) 
                    { 
                        this.baseName = _baseName; 
                        this.prefixName = _prefixName; 
                        this.suffixName = _suffixName; 
                    } 
                    

                    【讨论】:

                    • -1。这个约定在我所见过的任何地方都没有作为最佳实践发布,而且该帖子的格式非常糟糕。在更个人的层面上,我认为方法签名中的 _'s 显着混淆了代码,并且由于它在那里使用而不是在私有访问器中使用,因此它也将在整个客户端类中可见,而不仅仅是在您的代码中。
                    • 除了增加参数名称的视觉复杂性之外,“_”在其他编程上下文中通常用于表示“私有”。参数名称是公共方法签名的一部分,因此不应使用下划线前缀。此外,方法参数与局部变量几乎没有区别,因此对一个使用下划线而对另一个不使用下划线(或者更糟糕的是,也用于局部变量)是不一致的。
                    • 你是从哪里得知这个作为 C# 的命名指南的?该问题要求提供指南,而不是您可能使用的任何内容。正如@Matt 所描述的,你的不是标准的,而且在任何方面都不明智。
                    猜你喜欢
                    • 2011-01-09
                    • 2010-12-01
                    • 1970-01-01
                    • 2014-07-10
                    • 2014-03-03
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-05-23
                    相关资源
                    最近更新 更多