2008/3/15

C# 命名規則

記得剛開始寫網路程式時,主管丟了一份他寫的所謂程式開發的規則說明檔案給我,由於那時剛開始寫asp不久,所以對於這樣的規定倒是覺還還滿值得參考的。之後自已也開始帶人了以後,每每有新人進來,我也一樣會請他先看一下這份文件,除了當作一個程式撰寫的標準之外,其實也可以當作個人在程式開發上的一個寫作習慣。 後來開始接觸.NET以後,其實一直很希望也可以找個時間寫一份文件,當作.NET程式開發時的一個準則,除了提醒自已,也可以讓新加入的Team Member可以很快的進入狀況,更快的看懂其他人所寫的程式。只是常常因為專案太趕,想做的事情、想看的書太多而遲遲無法進行。 最近終於又打起了做這份文件的主意,但是要寫的東西太多了,所以一樣一樣來應該會比較實際一點;那就先從寫程式最常碰到,也是第一個會碰到的命名(Naming)問題開始好了! 由於.NET下我最常用的是C#,所以Naming主要是以此為據。開始首先要跟大家提兩個基本的Naming方式:

  • PascalCase
    每個單字的的第一個英文字母大寫,例如: TextBox、ConnectionString
  • camelCase
    除了第一個單字以外,每個單字的的第一個英文字母大寫,例如:getName, isValid
以上兩種方式,在看國外的程式命名規則時常會看到;主要是英文以大小寫做不同的命名方式,再搭配不同的用命名規則來使用它們。
接下來就是重頭戲了;由於C#的語法很多,所以先以我們常用的幾種語法來做規則的定義,其他的語法再陸續補完。
  • Namespaces (命名空間): ClarkRabbit.Blog.Utility + PascalCase (公司名稱.專案名稱.功能名或服務名稱)
    命名空間以統一、能夠輕易辨識所屬專案及功能為主,以『.』區隔也能夠明顯的表示程式架構。
    好範例: Yahoo.Portal.News 、 Microsoft.Msn.Search
    壞範例:YAHOO.PT.NWCR.DEMO.UT

  • Classes (類別):SearchService + PascalCase
    以簡單、有意義的命名方式來為Class命名,切勿使用含糊、不明確的方式為Class命名。
    好範例: MemberData, ProductInfo
    壞範例: Data, Status

  • Methods (方法):public void InitializeStatus() + PascalCase
    以能夠表達功能意義的 動詞+名詞 或 能夠表達其意義的 動詞 來表示這個方法的用途。
    好範例:
    public void SetWidth(int width);
    public void Show();
    public void SaveImage();
    壞範例:
    public void Add();
    public void Action();

  • Methods with return values (帶傳回值的方法):public int GetBuildingHeight() + PascalCase
    命名方式為動詞+名詞,以能夠表達回傳的值為何來命名。
    好範例:
    public int GetMemberAge();
    public List<MemberData> ListAllMemberData();
    壞範例:
    public int MemberAge();
    public List<MemberData> AllMember();

  • Constants (常數):public const int MAX_NICKNAME_LENGTH = 20;
    以英文大寫字體帶底線分隔單字,並以有意義的命名來表示常數。
    好範例:
    public const string DEFAULT_NICKNAME = "JOHN DOE";
    壞範例:
    public const int Size = 1; (分不清楚是變數還是常數)
    public const int MESSAGELENGTH = 200; (字連在一起無法辨識)

  • Properties/Enumerations (屬性/列舉):public int NumbersOfCar + PascalCase
    以有意義的名詞 或 形容詞+名詞來替屬性命名。
    好範例:
         public int CarLength
         {
            get;
            set;
         }
         
         public enum CarStyle
         {
            Normal,
            Special
         }     
         

  • Local Variables (區域變數):public void SetBlockWidth(int blockWidth); + camelCase
    以camelCase區分此為區域變數,命名依舊要以有意義的名稱來命名。
    好範例:
    public void SetMemberName(int memberName);
    壞範例:
    public void SetData(int _memberName, int _memberAge); //不要使用底線當作前置字元

  • Interfaces (介面):interface ICloneable + PascalCase
    介面一率以I開頭,依介面的意義為介面命名,例如可複製的介面以ICloneable命名,可以被格式化的介面以IFormattable來命名。
    好範例:
         interface IFormattable
         {
            //......
         }
        
    壞範例:
         interface Formattable //看不出來為介面
         {
            //........
         } 
        
         interface INAME  //看不出來介面意義為何
         {
            //.........
         }
         

  • Events (事件):public delegate void MemberCreatedEventHandler(object sender, MemberCreatedEventArgs e) PascalCase
    事件以有意義且能夠清楚表達事件被觸發時機的名稱為主,最後加上EventHandler為命名,其事件傳遞參數的class以EventArgs為結尾。
    好範例:
         public delegate void MouseLeftEventHandler(Object sender, MouseLeftEventArgs e);
        
    壞範例:
         public delegate void MouseLeft(Object sender, MouseLeftMessage e);
        
以上的規則,clark參考了一些外國的Programmer所寫的規則,看過幾篇以後,覺得都大同小異,主要也是因為統一這樣的規定以後,開放原始碼出來大家也會比較習慣。所以clark也不以自已之前的規則為主,而是儘量以統一的規則來常作自已的標準。

0 意見: