为了强调或不强调,这就是问题所在

时间:2009-01-16 12:10:16

标签: c#

如果二进制版本将被其他框架语言使用,那么在C#中不使用下划线为私有字段添加前缀是否有任何问题?例如,因为C#区分大小写,所以可以调用字段“foo”和公共属性“Foo”,它可以正常工作。

对于不区分大小写的语言(例如VB.NET)是否会产生任何影响,如果名称只能通过大小写区分,是否会出现任何CLS合规(或其他)问题?

13 个答案:

答案 0 :(得分:233)

重要更新(2016年4月12日):

我们注意到.NET CoreFX团队的内部标准insists on using the underscore-notation没有提供任何有关原因的见解。但是,如果我们仔细查看规则#3,很明显有一个_t_s_前缀系统可以说明为什么_首先被选中

  
      
  1. 我们将_camelCase用于内部和私有字段,并尽可能使用readonly。使用_的前缀实例字段,带有s_的静态字段和带有t_的线程静态字段。在静态字段上使用时,readonly应该在static之后(即static readonly而不是readonly static)。
  2.   
  3. 除非绝对必要,否则我们会避免使用this.
  4.   

因此,如果您就像.NET CoreFX团队正在开发一些性能关键,多线程,系统级代码,那么您强烈建议您:

  • 遵守他们的编码标准和
  • 使用下划线符号和
  • 不要再读这个答案了

否则请继续阅读...

原始答案:

让我们首先就我们所谈论的内容达成一致。问题是如果可见性修饰符允许,我们如何从非静态方法和类/子类的构造函数中访问实例成员。

下划线表示法

  • 建议您使用" _"私有字段名称中的前缀
  • 它还说你永远不应该使用"这个"除非它是绝对必要的

这表示法

  • 建议您只使用"这个。"访问任何实例成员

为什么存在这种符号?

因为这就是你的方式

  • 在共享相同名称的字段中区分参数
  • 确保您在当前实例的上下文中工作

实施例

public class Demo
{
   private String name;
   public Demo(String name) {
       this.name = name;
   }
}

为什么下划线符号存在?

有些人不喜欢打字"这个",但是他们仍然需要一种区分字段和参数的方法,所以他们同意使用" _"在田野面前

实施例

public class Demo
{
   private String _name;
   public Demo(String name) {
      _name = name;
   }
}

有人可能认为这只是个人品味的问题,两种方式同样好/坏。然而,在某些方面,这种符号胜过下划线 - 符号:

<强>净度

  • 下划线 - 符号杂乱的名字
  • 这个符号保持名称不变

认知负荷

  • 下划线 - 符号不一致,它会让您以特殊方式处理字段,但每次您需要问自己是否需要属性或字段时,都不能将其与其他成员一起使用

  • 这个符号是一致的,你不必思考,你只是总是使用&#34;这个&#34;引用任何成员

  

更新:正如所指出的,以下不是优势点

     

<强>维护

     
      
  • 下划线 - 表示法要求您在重构时密切关注_,例如将字段转换为属性(删除_)或相反(添加_)< / p>

  •   
  • 这个符号没有这样的问题

  •   

<强>自动完成

当您需要查看实例成员列表时:

  • 下划线 - 符号对你没什么帮助,因为当你输入&#34; _&#34;自动完成弹出窗口显示私有字段以及链接集合中可用的所有类型与其他实例成员混合
  • 这个符号通过输入&#34;这个&#34;给你一个明确的答案。所有你看到的是成员列表,没有别的

<强>歧义

有时你必须在没有Intellisense帮助的情况下处理代码。例如,当您在线进行代码审查或浏览源代码时。

  • 下划线 - 表示法含糊不清:当你看到Something.SomethingElse时,你无法判断Something是否是一个类而SomethingElse是它的静态属性......或者Something是一个当前实例属性,它有自己的属性SomethingElse

  • 这个符号很清楚:当你看到Something.SomethingElse时,它只能表示一个具有静态属性的类,当你看到这个。Something.SomethingElse你知道Something是一个成员而SomethingElse是它的属性< / p>

扩展方法

如果不使用&#34;这个,就不能在实例上使用扩展方法。&#34;

  • 下划线 - 表示法要求您不要使用&#34;这个&#34;,但是您必须使用扩展方法
  • 这个符号可以让你免于犹豫,你总是使用&#34;这个&#34;,句号。

Visual Studio支持

官方推荐

有很多官方指导明确说明&#34;不要使用下划线&#34;特别是在C#

答案 1 :(得分:67)

取自Microsoft StyleCop帮助文件:

<强>类型名:  FieldNamesMustNotBeginWithUnderscore

<强> CheckId:  SA1309

<强>原因: C#中的字段名称以下划线开头。

规则说明:

当字段名称以下划线开头时,会违反此规则。

默认情况下,StyleCop不允许使用下划线,m_等标记本地类字段,而使用'this。'前缀。使用'this。'的优点是它同样适用于所有元素类型,包括方法,属性等,而不仅仅是字段,使得对类成员的所有调用都可以立即识别,无论使用哪个编辑器查看代码。另一个优点是它在实例成员和静态成员之间创建了一个快速,可识别的区别,它不会被加上前缀。

如果字段或变量名称旨在与与Win32或COM关联的项目的名称匹配,因此需要以下划线开头,请将字段或变量放在特殊的NativeMethods类中。 NativeMethods类是包含以NativeMethods结尾的名称的任何类,用作Win32或COM包装器的占位符。如果项目放在NativeMethods类中,StyleCop将忽略此违规。

不同的规则说明表明,除上述内容外,首选做法是使用小写字母启动私有字段,使用大写字母启用公用字段。

编辑: 作为后续工作,StyleCop的项目页面位于:http://code.msdn.microsoft.com/sourceanalysis。阅读帮助文件可以深入了解他们为什么会提出各种风格规则。

答案 2 :(得分:45)

它将具有效果。

编写符合CLS的库的部分建议是,不要有两个公共/受保护的实体,这些实体的区别仅在于 NOT

public void foo() {...}

public void Foo() {...}

您所描述的内容不是问题,因为私人项目对于库的用户不可用

答案 3 :(得分:23)

由于我们讨论的是私有字段,因此不会影响您班级的用户。

但我建议在私有字段中使用下划线,因为它可以使代码更容易理解,例如:

private int foo;
public void SetFoo(int foo)
{
  // you have to prefix the private field with "this."
  this.foo = foo;

  // imagine there's lots of code here,
  // so you can't see the method signature



  // when reading the following code, you can't be sure what foo is
  // is it a private field, or a method-argument (or a local variable)??
  if (foo == x)
  {
    ..
  }
}

在我们的团队中,我们始终对私有字段使用下划线前缀。因此,在阅读某些代码时,我可以非常轻松地识别私有字段,并将它们与本地和参数区分开来。在某种程度上,下划线可以看作是“这个”的速记版本。

答案 4 :(得分:14)

在一个具有非常具体和非常无意义的风格规则的环境中工作之后,我开始创建自己的风格。这是我在很多方面来回翻转的一种类型。我最终决定私有字段永远是_field,局部变量永远不会_并且将是小写,控件的变量名称将松散地遵循匈牙利表示法,参数通常是camelCase。

我讨厌this.关键字,我认为它只会增加太多的代码噪音。我喜欢Resharper的删除多余的这个。关键字。

6年更新:我正在分析Dictionary<TKey,T>的内部结构,了解并发访问的特定用法,并将私有字段误读为本地变量。私有字段肯定不应该与局部变量的命名约定相同。如果有一个下划线,那将是非常明显的。

答案 5 :(得分:12)

我喜欢下划线,因为我可以使用小写名称作为方法参数,如下所示:

public class Person
{
    string _firstName;

    public MyClass(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get { return _firstName; }
    }
}

答案 6 :(得分:6)

由于Martin提到的原因,我仍然非常喜欢在私有字段前使用下划线,还因为私有字段将在IntelliSense中排序。尽管匈牙利语前缀符号一般都是邪恶的。

然而,最近我发现使用下划线前缀作为私人成员是不受欢迎的,即使我不太清楚为什么。也许别人都知道?它只是前缀原则吗?或者是否存在涉及泛型类型的名称修改的东西,它们在编译的程序集中得到下划线或什么?

答案 7 :(得分:5)

Style Cop建议与否,深入.NET Framework会显示成员变量的大量“_”用法。无论风格警察的创造者是什么推荐,都不是大多数MS员工使用的。 :)所以我会坚持使用下划线。因为我个人使用下划线减少错误,所以这个(例如:使用varName = varName而不是this.varName = varName,它真的卡在我身上)

答案 8 :(得分:3)

我认为基本的类级别字段在语言设计中是错误的。如果C#的属性有自己的局部范围,我会更喜欢它:

public int Foo
{
   private int foo;
   get
   {
      return foo;
   }
   set
   {
      foo = value;
   }
}

这样可以完全停止使用字段。

我唯一一次使用下划线为私有字段添加前缀是属性需要单独的后备字段时。这也是我使用私有字段的唯一时间。 (因为我从不使用保护,内部或公共字段,这是我使用字段周期的唯一时间。)就我而言,如果变量需要具有类范围,则它是类的属性。

答案 9 :(得分:2)

私有字段的_fieldName表示法很容易破解。使用“这个”。符号是不可能打破的。你怎么打破_符号?观察:

private void MyMethod()
{
  int _myInt = 1; 
  return; 
}

你去了,我只是违反了你的命名惯例,但它编译了。我宁愿有一个命名惯例,即a)不是匈牙利人,b)明确的。我赞成废除匈牙利语命名,这在某种程度上符合条件。而不是变量名前面的对象类型,而是具有其访问级别。

将此与Ruby对比,其中变量@my_number的名称将名称绑定到范围并且是不可破解的。

编辑:这个答案消极了。我不在乎,它留下来。

答案 10 :(得分:1)

如果希望程序集符合CLS,则可以在assemblyinfo文件中使用CLSCompliant属性。 当您的代码包含不符合cls的内容时,编译器会抱怨。

然后,当您有2个仅在大小写不同的属性时,编译器将发出错误。 另一方面,当你在同一个班级有私人领域和公共财产时,就没有问题。

(但是,我也总是在我的私人成员前面加上一个下划线。当我读取我的代码时,某个变量是一个成员字段时,它也有助于我说清楚。)

答案 11 :(得分:0)

我喜欢在我的私人领域前面使用下划线有两个原因。已经提到过一个,这些字段在代码和Intellisense中的相​​关属性中脱颖而出。第二个原因是我可以使用相同的命名约定,无论我是用VB编写还是用C#编码。

答案 12 :(得分:0)

没有任何影响。编译代码时,对编译器来说重要的是字段/属性的命名空间和可见性。在命名标识符时,下划线与任何其他字符一样重要。真正的诀窍是使用您和周围的人都能理解的惯例。