天天看點

程式設計中的66個好習慣

1. 避免将多個類放在一個檔案裡面。  

2. 一個檔案應該隻有一個命名空間,避免将多個命名空間放在同一個檔案裡面。

3. 一個檔案最好不要超過500行的代碼(不包括機器産生的代碼)。  

4. 一個方法的代碼長度最好不要超過25行。

5. 避免方法中有超過5個參數的情況。使用結構來傳遞多個參數。  

6. 每行代碼不要超過80個字元。  

7. 不要手工的修改機器産生的代碼。  

a) 如果需要編輯機器産生的代碼,編輯格式和風格要符合該編碼标準。

b) Use partial classes whenever possible to factor out the maintained portions.  

8. 避免利用注釋解釋顯而易見的代碼。  

a) 代碼應該可以自解釋。好的代碼由可讀的變量和方法命名是以不需要注釋。

9. Document only operational assumptions, algorithm insights and so on.   

10. 避免使用方法級的文檔。  

a) 使用擴充的API文檔說明之。  

b) 隻有在該方法需要被其他的開發者使用的時候才使用方法級的注釋。(在C#中就是///)

11. 不要寫死數字的值,總是使用構造函數設定其值。  

12. 隻有是自然結構才能直接使用const,比如一個星期的天數。  

13. 避免在隻讀的變量上使用const。如果想實作隻讀,可以直接使用readonly。

C# code
public
     
    class
     MyClass {   
                    
    public
     
    readonly
     
    int
     Number;   
                    
    public
     MyClass(
    int
      someValue)   
                    {       
                       Number 
    =
     someValue;   
                    }   
                    
    public
      
    const
     
    int
      DaysInWeek 
    =
     
    7
    ; 
                }
     
   
      

14. 每個假設必須使用Assert檢查  

a) 平均每15行要有一次檢查(Assert)  

C# code
using
     System.Diagnostics;

            
    object
     GetObject() {…} 

            
    object
     obj 
    =
     GetObject();

            Debug.Assert(obj 
    !=
     
    null
    );

   
      

15. 代碼的每一行都應該通過白盒方式的測試。  

16. 隻抛出已經顯示處理的異常。  

17. 在捕獲(catch)語句的抛出異常子句中(throw),總是抛出原始異常維護原始錯誤的堆棧配置設定。   

C# code
catch
    (Exception exception) 
             {      
                 MessageBox.Show(exception.Message);   
                 
    throw
     ;  
    //
    和throw exception一樣。 
    

                 }
     
   
      

18. 避免方法的傳回值是錯誤代碼。  

19. 盡量避免定義自定義異常類。  

20. 當需要定義自定義的異常時:  

a) 自定義異常要繼承于ApplicationException。

b) 提供自定義的序列化功能。

21. 避免在單個程式集裡使用多個Main方法。  

22. 隻對外公布必要的操作,其他的則為internal。  

23. Avoid friend assemblies, as it increases inter-assembly coupling.  

24. Avoid code that relies on an assembly running from a particular location.  

25. 使應用程式集盡量為最小化代碼(EXE客戶程式)。使用類庫來替換包含的商務邏輯。  

26. 避免給枚舉變量提供顯式的值。   

  //正确方法   

  public enum Color  

  {   

  Red,Green,Blue  

  }  

  //避免  

  public enum Color {   

  Red = 1,Green = 2,Blue = 3  

  }  

27. 避免指定特殊類型的枚舉變量。   

  //避免   

  public enum Color : long {Red,Green,Blue}

28. 即使if語句隻有一句,也要将if語句的内容用大括号擴起來。  

29. 避免使用trinary條件操作符。  

30. 避免在條件語句中調用傳回bool值的函數。可以使用局部變量并檢查這些局部變量。

  bool IsEverythingOK()  

  {…}

  //避免

  if (IsEverythingOK ())  

  {…}  

  //替換方案   

  bool ok = IsEverythingOK();  

  if (ok)  

  {…}

31. 總是使用基于0開始的數組。  

32. 在循環中總是顯式的初始化引用類型的數組。  

C# code
public
     
    class
     MyClass {

                MyClass[] array 
    =
     
    new
      MyClass[
    100
    ]; 

                
    for
    (
    int
     index 
    =
     
    0
    ; index 
    <
     array.Length; index
    ++
    )  

                    array[index] 
    =
     
    new
      MyClass(); 
              }

     
   
      

33. 不要提供public 和 protected的成員變量,使用屬性代替他們。  

34. 避免在繼承中使用new而使用override替換。  

35. 在不是sealed的類中總是将public 和 protected的方法标記成virtual的。  

36. 除非使用interop(COM+ 或其他的dll)代碼否則不要使用不安全的代碼(unsafe code)。  

37. 避免顯示的轉換,使用as操作符進行相容類型的轉換。 Dog dog = new GermanShepherd();  

  GermanShepherd shepherd = dog as GermanShepherd;  

  if (shepherd != null )  

  {…}

38. 當類成員包括委托的時候  

a) Copy a delegate to a local variable before publishing to avoid concurrency race condition.   

b) 在調用委托之前一定要檢查它是否為null

  public class MySource  

  {   

  public event EventHandler MyEvent;   

  public void FireEvent()   

  {   

  EventHandler temp = MyEvent;   

  if(temp != null )   

  {   

  temp(this,EventArgs.Empty);   

  }   

  }  

  }  

39. 不要提供公共的事件成員變量,使用事件通路器替換這些變量。  

  public class MySource  

  {   

  MyDelegate m_SomeEvent ;   

  public event MyDelegate SomeEvent   

  {   

  add   

  {   

  m_SomeEvent += value;   

  }   

  remove   

  {   

  m_SomeEvent -= value;   

  }   

  }  

  }  

40. 使用一個事件幫助類來公布事件的定義。  

41. 總是使用接口。  

42. 類和接口中的方法和屬性至少為2:1的比例。  

43. 避免一個接口中隻有一個成員。  

44. 盡量使每個接口中包含3-5個成員。  

45. 接口中的成員不應該超過20個。  

a) 實際情況可能限制為12個  

46. 避免接口成員中包含事件。  

47. 避免使用抽象方法而使用接口替換。  

48. 在類層次中顯示接口。  

49. 推薦使用顯式的接口實作。  

50. 從不假設一個類型相容一個接口。Defensively query for that interface.  

C# code
SomeType obj1; 
      IMyInterface obj2; 
      
    /*
     假設已有代碼初始化過obj1,接下來 
    */
     
      obj2 
    =
     obj1 
    as
     IMyInterface;
      
    if
     (obj2 
    !=
     
    null
    ) 
      {   
        obj2.Method1(); 
      } 
      
    else
     
      {   
        
    //
    處理錯誤 
    

    
      } 
     
   
      

51. 表現給最終使用者的字元串不要使用寫死而要使用資源檔案替換之。  

52. 不要寫死可能更改的基于配置的字元串,比如連接配接字元串。  

53. 當需要建構長的字元串的時候,使用StringBuilder不要使用string  

54. 避免在結構裡面提供方法。  

a) 建議使用參數化構造函數  

b) 可以重裁操作符  

55. 總是要給靜态變量提供靜态構造函數。  

56. 能使用早期綁定就不要使用後期綁定。  

57. 使用應用程式的日志和跟蹤。  

58. 除非在不完全的switch語句中否則不要使用goto語句。  

59. 在switch語句中總是要有default子句來顯示資訊(Assert)。

  int number = SomeMethod();  

  switch (number)  

  {  

  case 1:   

  Trace.WriteLine("Case 1:");  

  break;  

  case 2:   

  Trace.WriteLine("Case 2:");  

  break;  

  default:   

  Debug.Assert(false);  

  break;  

  }

60. 除非在構造函數中調用其他構造函數否則不要使用this指針。

  // 正确使用this的例子  

  public class MyClass  

  {   

  public MyClass(string message )   

  {

  }   

  public MyClass() : this("hello")   

  {

  }  

  }  

61. 除非你想重寫子類中存在名稱沖突的成員或者調用基類的構造函數否則不要使用base來通路基類的成員。

  // 正确使用base的例子  

  public class Dog  

  {   

  public Dog(string name)   

  {}   

  virtual public void Bark( int howLong)   

  {}  

  }  

  public class GermanShepherd : Dog  

  {   

  public GermanShe pherd(string name): base (name)   

  {}   

  override public void Bark(int howLong)   

  {   

  base .Bark(howLong);   

  }  

  }

62. 基于模闆的時候要實作Dispose()和Finalize()兩個方法。  

63. 通常情況下避免有從System.Object轉換來和由System.Object轉換去的代碼,而使用強制轉換或者as操作符替換。

  class SomeClass  

  {}  

  //避免:  

  class MyClass <T>   

  {   

  void SomeMethod(T t)   

  {   

  object temp = t;   

  SomeClass obj = (SomeClass)temp;   

  }  

  }  

  // 正确:  

  class MyClass <T> where T : SomeClass  

  {   

  void SomeMethod(T t)   

  {   

  SomeClass obj = t;   

  }  

  }  

64. 在一般情況下不要定影有限制符的接口。接口的限制級别通常可以用強類型來替換之。  

  public class Customer  

  {…}

  //避免:  

  public interface IList <T> where T : Customer   

  {…}  

  //正确:  

  public interface ICustomerList : IList <Customer>   

  {…}

65. 不确定在接口内的具體方法的限制條件。  

66. 總是選擇使用C#内置(一般的generics)的資料結構。