C#编程风格约定

我一直自认为,自己在编程功力还算说的过去,昨天一个老师看了我以前写的代码,说功力还需加强(当时我很郁闷,其实我知道的可能还比他多)。很多时候我们都太注重高水平、尖端的技术,其实很多公司叫你写一段简单的程序,可能就会决定要不要你。他们是从代码中看出了你的阅历,你的水平。这些水平不是体现你的尖端技术(况且很多新技术都是可以学的),而是你的风格,或习惯,而这些恰恰是经过很长的阅历积累起来的。

下面是从网上收集的c#编程风格参考,希望对读者有用。

【参考】《.NET设计规范》Krzysztof Cwalina,Brad Abrams著

C#编程世界中存在许多不同的编程风格约定,每一种都有自己的历史和哲学。本文描述的约定着眼于以下这些目标:

1、必须是实际开发人员使用的约定。为了实现这个目标,我们审查了由.NET框架的开发人员编写的代码。有些约定并未在框架中普遍应用,对此我们不予采纳。

2、约定应该尽可能的合理、简洁。我们认为只要不牺牲代码的可读性,在更少的行数内编写更多的代码通常是有帮助的,因为可以尽可能地减少代码的分屏和拆行,尽可能地增加代码的密度(没有空行)。

3、约定要简单。我们认为编程约定没有必要对每一种格式的每一个细节都锱铢必较。过于复杂的约定会难以遵循,而且与一小组核心约定相比,它们不会再增添太多的价值。

一、通用约定风格

1、花括号的使用

  • 把左花括号放在前一条语句的末尾。
    if (someExpression){
        DoSomething();
    }
  • 使右花括号与左花括号所在的行的行首对齐,除非花括号内只有一条语句。
    if (someExpression){
        DoSomething();
    }
  • 把右花括号放在新的一行的开始处。
    if (someExpression){
        DoSomething();
    }
  • 考虑把只有一条语句的代码块和左右花括号写在同一行。属性的访问方法经常使用这种风格。
    public int Foo{
        get{ return foo; }
        set{ foo = value; }
    }
  • 考虑把只有一个访问方法的属性的所有花括号写在同一行中。
    public int Foo{ get{ return foo; } }
  • 使右花括号单独占一行,除非它后面是else、else if或while。
    if (someExpression){
        do{
            DoSomething();
    } while(someOtherCondition);
    }
  • 避免省略花括号,即使编程语言允许这样做。
    不应该认为花括号是可以省略的。即使对只有一条语句的代码块,仍应该使用花括号。这样可以增强代码的可读性和可维护性。
    for (int i=0; i<100; i++){ DoSomething(i); }
    只有在极少数情况下才可以省略花括号,比如在原来仅有的一条语句后再添加新的语句是不可能的或是非常罕见的。例如,在throw语句后面再添加任何语句都是没有意义的:
    if (someExpression) throw new ArgumentOutOfRangeException(...);
    本条约定的另一个例外是case语句。由于case和break语句已经表示了代码块的起始和结束,因此这些花括号可以被省略。

2、空格的使用

  • 在左花括号之后和右花括号之前加一个空格。
    public int Foo{ get{ return foo; } }
  • 避免在左花括号之前加空格。
    最好如此:if (someExpression){
    可以接受:if (someExpression) {
  • 在形式参数之间的逗号后加一个空格。
    正确:public void Foo(char bar, int x, int y)
    错误:public void Foo(char bar,int x,int y)
  • 避免在实际参数之前加空格。
    最好如此:Foo(mychar,0,1)
    可以接受:Foo(mychar, 0, 1)
  • 避免在左圆括号之后或右圆括号之前加空格。
    最好如此:Foo(mychar,0,1)
    可以接受:Foo( mychar, 0, 1 )
  • 不要在成员的名字和左圆括号之间加空格。
    正确:Foo()
    错误:Foo ()
  • 不要在左方括号之后和右方括号之前加空格。
    正确:x = dataArray[index];
    错误:x = dataArray[ index ];
  • 不要在控制流语句之前加空格。
    正确:while(x==y)
    错误:while (x==y)
  • 避免在二元操作符之前和之后加空格。
    最好如此:if(x==y){ ... }
    可以接受:if(x == y){ ... }
  • 不要在一元操作符之前或之后加空格。
    正确:if(!y){ ... }
    错误:if(! y){ ... }

3、缩进的使用

  • 用4个连续的空格符来进行缩进。
  • 不要用制表位(tab)来进行缩进。
  • 对代码块中的内容进行缩进。
    if (someExpression){
        DoSomething();
    }
  • 对case代码块进行缩进,尽管没有使用花括号。
    switch(someExpression){
        case 0:
            DoSomething();
        break;
        ...
    }

二、命名约定

  • 在命名标示符时遵循《框架设计准则》中的命名规范,除非是内部字段和私有字段。
  • 在命名空间、类型及成员时采用PascalCasing大小写风格,除非是内部字段和私有字段。
  • 用camelCasing大小写风格来命名内部字段和私有字段。
  • 用camelCasing大小写风格来命名局部变量。
  • 用camelCasing大小写风格来命名方法的形式参数。
  • 不要使用匈牙利命名法(也就是说,不要在变量名中包含变量的类型)。
  • 避免给局部变量加前缀。
  • 使用C#语言中对应的别名,不要使用.NET框架中的类型名。
    例如,要使用int而不是Int32,要使用object而不是Object。

三、注释

  • 不要用注释来描述一些对任何人都显而易见的事。
  • 避免使用块注释语法(/*...*/)。即使注释会有多行,也最好是使用单行注释语法(//...)。
    //This is a very long content.
    //This is a very long content.
    //This is a very long content.
    public class List<T> : IList<T>, IList{
        ...
    }
  • 不要把注释放在行尾,除非注释非常短。
    //Avoid
    public class ArrayList{
        private int count;  //-1 indicates uninitialized array
    }

四、文件的组织

  • 不要在一个源文件中包含一个以上的公用类型,除非有嵌套类,或各类型之间的不同之处仅在于泛型参数的数量。
    一个文件中有多个内部类型是允许的。
  • 用相同的名字来命名源文件及其包含的公用类型。
    例如,String类应该在String.cs文件中,而List<T>类则应该在List.cs文件中。
  • 用相同的层次结构来组织文件目录和名字空间。
    例如,应该把System.Collections.Generic.List<T>的源文件放在System\Collections\Generic目录中。
  • 考虑根据下面给出的顺序和组别来对成员进行分组:
    1.所有字段。
    2.所有构造函数。
    3.公有属性及其受保护的属性。
    4.方法。
    5.事件。
    6.所有显式实现的接口成员。
    7.内部成员。
    8.私有成员。
    9.所有嵌套类型。
  • 把不能公开访问的成员和显式实现的接口成员分别放在自己的#region块中。
    #region internal members
    ...
    #endregion
    #region private members
    ...
    #endregion
  • 考虑在每个组别内根据字母顺序来组织成员。
  • 考虑根据由简单到复杂的顺序来组织重载成员。
  • 把using指令放在名字空间的声明之外。
    using System;
    namespace System.Collections{
        ...
    }
posted on 2008-04-15 12:39  RedSoft  阅读(766)  评论(1编辑  收藏  举报