熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#編碼標准--編碼習慣

2022-06-13   來源: .NET編程 

    避免將多個類放在一個文件裡面

    一個文件應該只有一個命名空間避免將多個命名空間放在同一個文件裡面

    一個文件最好不要超過行的代碼(不包括機器產生的代碼)

    一個方法的代碼長度最好不要超過

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

    每行代碼不要超過個字符

    不要手工的修改機器產生的代碼

  a)  如果需要編輯機器產生的代碼編輯格式和風格要符合該編碼標准

  b)  盡可能使用分部類來提出需要維護的部分

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

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

    避免使用方法級的文檔

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

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

    不要硬編碼數字的值總是使用構造函數設定其值

    只有是自然結構才能直接使用const比如一個星期的天數

    避免在只讀的變量上使用const如果想實現只讀可以直接使用readonly

  public class MyClass

  {

  public readonly int Number;

  public MyClass(int  someValue)

  {

  Number = someValue;

  }

  public  const int  DaysInWeek = ;

  }

    每個假設必須使用Assert檢查

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

  using SystemDiagnostics;

  object GetObject()

  {…}

  object obj = GetObject()

  DebugAssert(obj != null)

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

    只拋出已經顯示處理的異常

    在捕獲(catch)語句的拋出異常子句中(throw)總是拋出原始異常維護原始錯誤的堆棧分配

  catch(Exception exception)

  {

  MessageBoxShow(exceptionMessage)

  throw ;  //和throw exception一樣

  }

    避免方法的返回值是錯誤代碼

    盡量避免定義自定義異常類

    當需要定義自定義的異常時

  a)  自定義異常要繼承於ApplicationException

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

    避免在單個程序集裡使用多個Main方法

    只對外公布必要的操作其他的則為internal

    避免友元程序集因為它能增加間裝配耦合

    避免代碼依賴於從特定位置運行的程序集

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

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

  //正確方法

  public enum Color

  {

  RedGreenBlue

  }

  //避免

  public enum Color

  {

  Red = Green =  Blue =

  }

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

  //避免

  public enum Color  : long

  {

  RedGreenBlue

  }

    即使if語句只有一句也要將if語句的內容用大括號擴起來

    避免使用三目條件操作符

    避免在條件語句中調用返回bool值的函數可以使用局部變量並檢查這些局部變量

  bool IsEverythingOK()

  {…}

  //避免

  if (IsEverythingOK ())

  {…}

  //替換方案

  bool ok = IsEverythingOK()

  if (ok)

  {…}

    總是使用基於開始的數組

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

  public class MyClass

  {}

  MyClass[] array = new  MyClass[];

  for(int index = ; index < arrayLength;  index++)

  {

  array[index] = new  MyClass()

  }

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

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

    在不是sealed的類中總是將public 和 protected的方法標記成virtual的

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

    避免顯示的轉換使用as操作符進行兼容類型的轉換

  Dog dog = new GermanShepherd()

  GermanShepherd shepherd = dog  as  GermanShepherd;

  if (shepherd != null )

  {…}

    當類成員包括委托的時候

  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(thisEventArgsEmpty)

  }

  }

  }

    不要提供公共的事件成員變量使用事件訪問器替換這些變量

  public class MySource

  {

  MyDelegate m_SomeEvent ;

  public event MyDelegate SomeEvent

  {

  add

  {

  m_SomeEvent += value;

  }

  remove

  {

  m_SomeEvent = value;

  }

  }

  }

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

    總是使用接口

    類和接口中的方法和屬性至少為:的比例

    避免一個接口中只有一個成員

    盡量使每個接口中包含個成員

    接口中的成員不應該超過

  a)  實際情況可能限制為

    避免接口成員中包含事件

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

    在類層次中顯示接口

    推薦使用顯式的接口實現

    從不假設一個類型兼容一個接口

  SomeType obj;

  IMyInterface obj;

  /* 假設已有代碼初始化過obj接下來 */

  obj = obj as IMyInterface;

  if (obj != null)

  {

  objMethod()

  }

  else

  {

  //處理錯誤

  }

    表現給最終用戶的字符串不要使用硬編碼而要使用資源文件替換之

    不要硬編碼可能更改的基於配置的字符串比如連接字符串

    當需要構建長的字符串的時候使用StringBuilder不要使用string

    避免在結構裡面提供方法

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

  b)  可以重裁操作符

    總是要給靜態變量提供靜態構造函數

    能使用早期綁定就不要使用後期綁定

    使用應用程序的日志和跟蹤

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

    在switch語句中總是要有default子句來顯示信息(Assert)

  int number  = SomeMethod()

  switch(number)

  {

  case :

  TraceWriteLine(Case :

  break;

  case :

  TraceWriteLine(Case :

  break;

  default :

  DebugAssert(false)

  break;

  }

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

  // 正確使用this的例子

  public class MyClass

  {

  public MyClass(string message )

  {}

  public MyClass()  : this(hello

  {}

  }

    除非你想重寫子類中存在名稱沖突的成員或者調用基類的構造函數否則不要使用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)

  }

  }

    基於模板的時候要實現Dispose()和Finalize()兩個方法

    通常情況下避免有從SystemObject轉換來和由SystemObject轉換去的代碼而使用強制轉換或者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;

  }

  }

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

  public class Customer

  {…}

  //避免

  public interface IList<T> where T : Customer

  {…}

  //正確

  public interface ICustomerList : IList<Customer>

  {…}

    不確定在接口內的具體方法的限制條件

    總是選擇使用C#內置(一般的generics)的數據結構


From:http://tw.wingwit.com/Article/program/net/201311/12176.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.