两个C#命名约定:您怎么看?

时间:2009-05-05 04:08:35

标签: c# naming-conventions

我有两个特定的 C#编码约定我一直在练习,感情复杂。 我很想知道人们的想法。他们是:

#1。在类之后的名称实例,它是camelCased的实例

#2:“匹配属性名称”

以下是理由:

#1。在类之后的名称实例,它是camelCased的实例

我将此作为命名约定的默认设置。当然,也有例外。但是始终如一地使用显着可以提高代码清晰度和可维护性。代码如下所示:

var dataConnection = new DataConnection();
//not: var dataConn, dbConn, sqlConn, myDbPickOfTheDay etc.

FileInfo fileInfo = new FileInfo();

Timer timer = new Timer(); 

//etc.

我正处于这样的代码导致我身体疼痛的地步:

DataConnection dbConn = new DataConnection();

我无法强调这个约定如何消除变量名称游戏的痛苦和愤怒。

这种惯例与尝试以试图表明实例正在做什么的方式命名事物形成鲜明对比,这相当于试图创造性地将业务案例嵌入到代码中。代码有一种方法可以重构到这些原始名称最多会产生误导的程度。

对我而言,这个惯例是黄金。它还可以防止对同一件事略微调整变量名的可怕做法。

实践中这种惯例的一个例子是:

class Person { ...
   public string FirstName { get; set; }

//and then
var person = new Person();
person.FirstName = firstName; //where firstName comes from somewhere else.

非常容易阅读。很无聊。在维护代码方面,无聊非常好。

然而,这个惯例引导我进入#2:

#2“匹配属性名称”(缺少更好的标题)

以下是一个例子:

public class ShoppingCart { ..
  private Item item;
  public Item Item {  //<---- ?
  get { return this.item; } ...

编译器非常满意这一点。事实上,它暴露了一个非常好的界面:

//notice how tempting it is to just say "ShoppingCart cart ... "
ShoppingCart shoppingCart = new ShoppingCart();  
shoppingCart.Item = item;

现在,替代方案是创造性的 - 你实际上需要为Item打出两个好的变量名:公共属性名和私有成员变量名。

你有多少次看过这个并且想立即退休?

 public class ShoppingCart { ..
      private Item cartItem;
      public Item ShoppingCartItem { 
      get { return this.cartItem; } ..
  ///....
  ShoppingCart userShoppingCart = new ShoppingCart();
  userShoppingCart.ShoppingCartItem = userSelection;

我对第一次约会感到非常满意,我认为我可以和#2一起生活。

您怎么看?

7 个答案:

答案 0 :(得分:12)

如果你不知道并且你在乎,C#已经有了命名标准

http://msdn.microsoft.com/en-us/library/xzf533w0(VS.71).aspx

另外,再次查看您的约定......这里有更多建议。

  • fileInfo看起来非常接近FileInfo,但除了它的类型之外没有任何意义,我可以通过鼠标悬停在类型或智能感知中快速获得。我建议使用含义和一些上下文命名变量(如果可用)。 remoteWebServerLog,localWebServerLog,甚至是localWebServerLogFileInfo,如果你喜欢名字中的类型。

    如果我可以提交任何回复代码的建议,那么你之后会写6 + mos。你会摸不着头脑,试图弄清楚你所有的dbConn和fileInfo是什么。什么文件?什么db?很多应用程序都有几个dbs,这个是对OrdersDB或ShoppingCartDB的dbConn吗?

  • 类命名应该更具描述性。我们更喜欢ShoppingCartItem而不是Item。如果每个ListBox,DropDown等都将它们的集合项命名为“Item”,那么您将与许多名称空间发生冲突,并且将被迫使用MyNameSpace.ShoppingCart.Item来丢弃您的代码。

说了这么多......即使经过多年的编码,我仍然搞砸了,并没有100%的时间遵守规则。我甚至可能使用了FileInfo fi = ...但这就是为什么我喜欢我的Resharper“Refactor-&gt; Rename”命令并经常使用它。

答案 1 :(得分:2)

显然,您不能在项目 string *,中为每个System.String命名,但对于您不使用很多的东西,尤其是。你只需要其中一个,并且你的代码中的函数从它的名字中显而易见的东西,这些命名约定是完全可以接受的。

无论如何,他们就是我做的。

我会使用更具体的名称,例如Timer对象。什么是计时器? 但我肯定会命名一个DataConnection dataConnection。

*即使“string”不是关键字......

答案 2 :(得分:2)

第1号公约可能会变得令人困惑。如果你在同一个方法中有两个FileInfo个对象 - 比如一个Source和一个Target--你需要偏离约定来命名这两个。

变量名称应该是助记符 - 向不经意的观察者表明其使用的意图。

对于这两个约定的组合,也许你最开心......例如sourceFileInfo和targetFileInfo,按照这个例子。

答案 3 :(得分:0)

我一直做1,发现它非常易读。我在2的栅栏上。我发现它在某些情况下令人困惑,主要是因为由于标识符相同而很难区分类型和属性。

答案 4 :(得分:0)

我一直遵循惯例1。虽然,如果有两个并排的对象,我会添加一个额外的限定符。

但话虽如此,强制执行此惯例可能会有问题:

  1. 在某个上下文中cart可能是ShoppingCart对象的足够好的名称(例如,如果同一个函数中没有其他'cart'与之混淆)。
  2. 有时,约定可能会完全模糊声明对象的目的。例如Window scoreBoard = new Window()表示我们有一个确实是Window的对象,但它被用作scoreBoard。非常富有表现力。但按照惯例1,您必须编写Window window = new Window(),这完全隐藏了此窗口背后的意图。
  3. 所以我会说在任何地方使用这个命名理念,除非它阻碍意义或出现不合理的要求。

    关于公约2,我完全同意。保持属性名称简洁并让对象名称完成其调用的全部含义是一件优雅的事情。它与命名良好的对象完美配合。所以没有理由害羞地使用它。

答案 5 :(得分:0)

我通常会遵循约定#1,但对于长类名,我倾向于使用类的首字母。如果我指的是同一类型的多个对象,那么我会预先给类型名称添加一个名称,指明它是哪一个或者它用于什么。

如果有意义,我经常使用约定#2。没有比像你列出的cart.ShopingCartItem这样的例子更糟糕的事了,它是ShoppingCart的一个属性,这使得属性名称的一部分完全是多余的。但是,我很可能将类ShoppingCartItem和属性Item命名为。项目的名称有点过于通用,而ShoppingCartItem会告诉您正在使用的项目类型。

答案 6 :(得分:0)

我强烈不喜欢在范围内有多个标识符的概念,这些标识符仅在大/小写的使用方面有所不同;如果我有我的druthers,使用标识符的代码将需要使用相同的大写/小写字母组合作为其声明,但代码既不允许在同一范围内声明两个标识符,只有大小写,也不能访问任何标识符 - 除了大小写 - 匹配内部范围中的标识符。虽然我所知道的语言(当然不是VB或C#)都没有强制执行这样的规则,但是遵循这些规则编写的代码可以在区分大小写和不区分大小写的语言之间自由移植,而不必重命名标识符。

因此,我不喜欢模式#2。 CLS合规性要求该样式的任何标识符都限制在privateinternal范围内。由于vb.net和C#都允许名称以下划线开头,如果属性名为Trait,我认为没有理由支持trait而不是_trait。使用后一个名称可以清楚地区分程序员想要从他的手指在换档键上滑动的后备变量写入的情况。

对于模式#1,如果类型或方法的整个目的围绕某个特定类型的单个封装对象解析,我更喜欢使用my或带the的参数作为前缀。即使在编译器允许将相同的名称用于实例成员和参数的情况下,使用不同的前缀也可以避免在需要另一个的情况下意外使用其中一个。