IDesign C#編程規範

來源:互聯網
上載者:User

原文轉自:http://www.cnblogs.com/ShiningRay/archive/2005/04/11/135263.html

命名規則和風格 

1.  類和方法名採用Pascal風格 
    public class SomeClass
    {
       public SomeMethod(){}
    }
2.  局部變數和方法參數採用camel風格 
    int number;
    void MyMethod(int someNumber)
    {}
3.  介面名採用I作為首碼 
    interface IMyInterface
    {..}
4.  私人成員變數採用m_作為首碼
    public class SomeClass
    {
       private int m_Number;
    }
5.  自訂屬性類名採用Attribute作為尾碼
6.  自訂異常類名採用Exception作為尾碼
7.  採用動詞-對象對命名方法,例如ShowDialog()
8.  有傳回值的方法應該取名表示其傳回值,例如GetObjectState()
9.  採用描述性的變數名。 
    a) 避免採用單字母的變數名,如i或t;而是採用index或temp。
    b) 對public和protected成員避免採用用匈牙利命名法。
    c) 不要採用縮寫(例如將number縮寫為num)。
10.  總是使用C#預定義的類型,而不是使用System命名空間中的別名。例如:採用object不用Object,採用string不用String,採用int不用Int32。
11.  對於泛型,類型採用大寫字母。當處理.NET類型Type時保留尾碼Type。
     // 正確:
     //Correct:
     public class LinkedList
     // 避免使用:
     //Avoid: 
     public class LinkedList 
12.  採用有意義的命名空間名,例如產品名稱或公司名稱。
13.  避免使用類的全稱,而是採用using語句。
14.  避免在命名空間內使用using語句。
15.  將所有framework命名空間名放在一起,後面放自訂或第三方的命名空間名。
     using System;
     using System.Collections;
     using System.ComponentModel;
     using System.Data;
     using MyCompany;
     using MyControls;
16.  採用委託推斷,不要顯式執行個體化委託。
     delegate void SomeDelegate();
     public void SomeMethod()
     {}
     SomeDelegate someDelegate = SomeMethod;
17.  嚴格遵守縮排格式。
     a) 縮排採用3個空格。 
     b) 不用採用tab或非標準的縮排,如1、2或4個空格。
18.  注釋縮排和其注釋的代碼在同一層次。
19.  所有注釋要經過拼字檢查。拼字錯誤的注釋表明開發的草率。
20.  所有成員變數應該定義在前面,和屬性或方法間空開一行。
     public class MyClass
     {
        int m_Number;
        string m_Name;

        public void SomeMethod1()
        {}
        public void SomeMethod2()
        {}
     }
21.  局部變數的定義儘可能靠近它的初次使用。
22.  檔案名稱應該體現其包含的類。
23.  當使用partial類型且每部分分配一個檔案時,以類型名加P和序數命名每個檔案。
     //In MyClassP1.cs
     public partial class MyClass
     {}
     //In MyClassP2.cs
     public partial class MyClass
     {}
24.  左大括弧總是放在新行中。
25.  匿名方法模仿普通方法的布局,和匿名委託定義放在一行。
     a) 遵守將左大括弧放在新行的規則。
     delegate void SomeDelegate(string someString);
     //正確
     //Correct: 
     public void InvokeMethod()
     {
        SomeDelegate someDelegate = delegate(string name)
                                    {
                                       MessageBox.Show(name);
                                    };
        someDelegate("Juval");
     }
     //避免採用:
     //Avoid
     public void InvokeMethod()
     {
        SomeDelegate someDelegate = delegate(string name){MessageBox.Show(name);};
        someDelegate("Juval");
     }
26.  沒有參數的匿名方法使用空括弧。
     a) 僅當匿名方法可能被用於任何委託時省略括弧。
     delegate void SomeDelegate();
     //Correct 
     SomeDelegate someDelegate1 = delegate()
                                  {
                                     MessageBox.Show("Hello");
                                  };
     //Avoid 
     SomeDelegate someDelegate1 = delegate
                                  {
                                     MessageBox.Show("Hello");
                                  };

2  編碼慣例

1. 避免在一個檔案中放多個類。
2. 一個檔案應該只對一個命名空間提供類型。避免在同一檔案中有多個命名空間。
3. 避免檔案長度超過500行(除了機器自動產生的代碼)。
4. 避免方法定義超過25行。
5. 避免超過5個參數的方法。使用結構傳遞多個參數。
6. 每行應該不超過80個字元。
7. 不要手工編輯任何機器產生的程式碼。 
    a) 如果修改機器產生的程式碼,修改代碼格式和風格以符合本編碼通訊協定。
    b) 儘可能採用partial類以分解出需要維護的部分。
8. 避免對顯而易見的內容作注釋。 
   a) 代碼應該是自解釋的。 由可讀性強的變數和方法組成的好的代碼應該不需要注釋。
9. 僅對操作的前提、內在演算法等寫文檔。
10. 避免方法級的文檔。 
     a) 對API文檔採用大量的外部文檔。
     b) 方法級注釋僅作為對其他開發人員的提示。
11. 決不要寫入程式碼數值, 而總是聲明一個常量。
12. 僅對本來就是常量的值使用const修飾符,例如一周的天數。
13. 避免對唯讀變數使用const修飾符。在此情況下,採用readonly修飾符。 
     public class MyClass
     {
        public readonly int Number;
        public MyClass(int someValue)
        {
           Number = someValue;
        }
        public const int DaysInWeek = 7;
     }
14.  對任何假設採用assert。
      a) 平均地,每5行中就有一行是斷言。 
      using System.Diagnostics;
      object GetObject()
      {
            object obj = GetObject();
            Debug.Assert(obj != null);
15.  每行代碼應該經過白盒測試。
16.  僅捕獲已經顯式處理了的異常。
17.  在拋出異常的catch語句中,總是拋出最初異常以保持最初錯誤的堆棧位置。
     catch(Exception exception)
     {   
        MessageBox.Show(exception.Message);
        throw;  //Same as throw exception;
     }
18.  避免將錯誤碼作為方法的傳回值。
19.  避免定義自訂的異常類。
20.  定義自訂異常時:
      a) 從ApplicationException繼承 
      b) 提供自訂的序列化。
21.  避免在一個程式集中有多個Main()方法。
22.  僅對最需要的類型標記為public,其他的標記為internal。
23.  避免採用friend程式集,因為這樣增加了程式集間的耦合度。
24.  避免使用依賴於從特定位置啟動並執行程式集的代碼。
25.  盡量減少應用程式集(用戶端EXE程式集)的代碼。採用類庫而不要包含商務邏輯層代碼。
26.  避免對枚舉提供明確的值。
     //Correct 
     public enum Color
     {   
        Red,Green,Blue
     }
     //Avoid 
     public enum Color
     {   
        Red = 1,Green = 2,Blue = 3
     }
27.  避免對枚舉指定類型。
     //Avoid 
     public enum Color : long
     {   
        Red,Green,Blue
     }
28.  if語句總是使用括弧,即使它包含一句語句。
29.  避免使用?:條件算符。
30.  避免在布爾條件陳述式中調用函數。賦值到局部變數並檢查它們的值。
     bool IsEverythingOK()
     {...}
     //避免:
     if(IsEverythingOK())
     {...}
     //採用:
     bool ok = IsEverythingOK();
     if(ok)
     {...}
31.  總是使用從0開始的數組。
32.  總是使用一個for迴圈顯式地初始化一個參考型別的數組。
     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.  對非密封類總是將public和protected方法標記為virtual。
36.  除非涉及到互操作,永遠不要用不安全的代碼。
37.  避免顯式類型轉換。使用as演算法防護性地轉換類型。
       Dog dog = new GermanShepherd();
       GermanShepherd shepherd = dog as GermanShepherd;
       if(shepherd != null)
       {...}
38.  類成員有委託時:
       a) 使用前將委託複製到局部變數,以避免並發衝突。
       b) 調用前始終檢查委託是否為空白。
       public class MySource
       {
          public event EventHandler  MyEvent;
          public void FireEvent()
         {
            EventHandler temp = MyEvent;
            if(temp != null)
            {
               temp(this,EventArgs.Empty);
            }
         }
      }  
39.  不要提供public的事件成員變數,而是使用事件訪問器。
       public class MySource
       {
          MyDelegate m_SomeEvent;
          public event MyDelegate SomeEvent
          {
             add
            {
                m_SomeEvent += value;
             }
             remove
            {
                m_SomeEvent -= value;
             }
          }
       }
40.  使用Programming .NET Components中定義的EventsHelper類安全地發布事件。
41.  總是使用介面。
       a) 參見Programming .NET Components第一和第三章。
42.  類和介面中方法和屬性的比例至少是2:1。
43.  避免使用一個成員的介面。
44.  努力使每個介面擁有3-5個成員。
45.  每個介面不用超過20個成員。
       a) 12可能是實際應用的極限了。
46.  避免將事件作為介面成員。
47.  避免使用抽象方法,而是使用介面代替。
48.  在類層次中暴露介面。
       a) 參見Programming .NET Components第三章。
49.  優先使用明確的介面實現。
       a) 參見Programming .NET Components第三章。
50.  永遠不要假設一種類型支援某個介面。防護性地檢查是否支援該介面。
       SomeType obj1;
       IMyInterface obj2;
      
       /* Some code to initialize obj1, then: */
       obj2 = obj1 as IMyInterface;
       if(obj2 != null)
      {
        obj2.Method1();
       }
       else
      {
         //Handle error in expected interface 
      }  
51.  將呈現給使用者的字串永遠不用寫入程式碼,而是使用資源。
52.  發布時可能修改的字串永遠不用寫入程式碼,例如連接字串。
53.  構建一個長字串時,使用StringBuilder,不要用string。
54.  避免提供帶結構的方法。
       a)  參數化的建構函式是鼓勵使用的。
       b)  可以重載算符。
55.  當提供靜態成員變數時,總是提供一個靜態建構函式。
56.  只要可以用前期綁定就不要用後期綁定。
57.  對應用程式進行日誌和跟蹤。
58.  除非在switch語句中跳轉,永遠不要用goto語句。
59.  switch語句中總是使用default用於加斷言。
       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。
       //Example of proper use of this
       public class MyClass
       {
          public MyClass(string message)
          {}
          public MyClass() : this("hello")
          {}
       }
61.  除非為瞭解決調用基類建構函式時成員名的衝突,否則不要使用base訪問基類的成員。
     //Example of proper use of 抌ase?
     public class Dog
     {
        public Dog(string name)
        {}
        virtual public void Bark(int howLong)
        {}
     }
     public class GermanShepherd : Dog
     {
        public GermanShepherd(string name): base(name)
        {}
        override public void Bark(int howLong) 
        {
           base.Bark(howLong);  
        }
     }
62.  根據Programming .NET Components第四章中的模板實現Dispose()和Finalize()方法。
63.  使用泛型的代碼中避免與System.Object進行類型轉換,而是使用限制或as算符。
       class SomeClass
       {} 
        //避免 :
       class MyClass 
      {   
          void SomeMethod(T t)   
         {
           object temp = t;      
           SomeClass obj = (SomeClass)temp;   
         }
       }
       //正確 :
       class MyClass where T : SomeClass
       {   
          void SomeMethod(T t)   
          {
             SomeClass obj = t;   
          }
       }
64.  泛型介面不要定義限制。介面層的限制通常能用強型別代替。
       public class Customer
       {...}
       //避免 
       public interface IList where T : Customer 
       {...}
       //正確 
       public interface ICustomerList : IList 
       {...}
65.  不要在介面中定義與方法相關的限制。
66.  在資料結構中總是優先使用C#泛型。

3   項目設定和項目結構

1.  總是以4級警告建立項目(圖略)。
2.  在發布版中將警告作為錯誤(注意這不是VS.NET的預設設定)(圖略)。
    a) 雖然是可選的,本標準也推薦在調試版中將警告作為錯誤。 
3.  永遠不要抑制特定的編譯警告(圖略)。
4.  總是在應用程式的設定檔中顯式地說明支援的運行時版本。參見Programming .NET Components第五章。
5.  避免顯式地自訂版本改向和綁定到CLR程式集。
6.  避免顯式的先行編譯定義(#define)。使用項目設定定義條件編譯常量。 
7.  不要在AssemblyInfo.cs中放任何邏輯。
8.  除了在AssemblyInfo.cs,不要在任何檔案中放程式集屬性。
9.  在AssemblyInfo.cs中提供所有欄位,例如公司名稱、描述、著作權等。
10. 所有程式集應該使用相對路徑引用。
11. 不允許在程式集中循環參考。
12. 避免多模組的程式集。
13. 預設總是以非檢查的方式運行(為了效能考慮),但是對易於溢出或下溢的操作顯式使用檢查模式(圖略)。
     int CalcPower(int number,int power)
     {
        int result = 1;
        for(int count = 1;count <= power;count++)
        {
           checked       
           {
              result *= number;
           }
        }
        return result;
     }
14.  避免使用Exception視窗(Debug|Exceptions)篡改異常處理。
15.  努力對同一邏輯應用程式程式中(通常是一個解決方案)的所有程式集和用戶端使用統一的版本號碼。
16.  Visual Studio.NET應用的設定檔命名為App.config,並將其包括在項目中。
17.  避免使用顯式代碼來排除方法(#if#endif),而是使用條件方法。
     public class MyClass
     {
        [Conditional("MySpecialCondition")]
        public void MyMethod()
        {}
     }
18.  將VS.NET預設的項目結構改為標準的布局,對專案檔夾和檔案應用統一的結構。
19.  連結一個包含所有解決方案級資訊的全域共用檔案(圖略)。
20.  定位字元選用"插入空格",使用3個空格代替定位字元。
     a) 在工具|選項|文字編輯器|C#|定位字元中設定
21.  發布版中應該包含偵錯符號。
22.  總是對程式集簽名,包括用戶端應用程式。
23.  總是使用項目的SNK檔案對Interop 組件簽名(圖略)。

4  Framework特別指導
4.1 資料訪問
1.  總是使用型別安全的資料集或者資料表。避免使用原始的ADO.NET。
2.  訪問資料庫時總是使用事務。
     a) 總是使用服務元件事務。 
     b) 不要使用ADO.NET事務。
3.  總是將交易隔離等級設定為序列的。
     a) 使用其它隔離等級需要管理層決定。
4.  不要使用伺服器瀏覽器將資料庫連接拖到Windows表單、ASP.NET表單或Web服務中。這樣做耦合了介面層和資料層。
5.  避免使用SQL Server驗證。
     a) 而是使用Windows驗證。
6.  將訪問SQL Server的組件以調用該組件用戶端不同的身份運行。
7.  總是在高層用型別安全的類封裝預存程序。僅在那個類中調用預存程序。
8.  避免在預存程序中放任何邏輯。
     a) 如果預存程序中有IF,你可能犯了錯誤。

待續。忽然想到曾閱讀過一篇關於business layer的文章,總體是責問有多少程式真正有business layer,文中甚至倡議presentation layer中不要引用System.Data命名空間,你做得到嗎?小雞射手還不行,嘻嘻...

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.