[C#]Code Convention Sample
前言
通常在團隊開發時,我們會定義出coding standard與coding style,其中也包括了naming的原則等等,這一篇文章,就把這些統稱為Code Convention(規範)。
在這一篇文章,以C#這個程式語言為例,來訂出一個比較common的一些rule,供大家當參考。在應用到自己的團隊時,可以增修某些rule,來更適應自己團隊的習慣。但要先說明的是,會定義出這些rule,就代表著有一定的目的。
Naming (命名規範)
- 只用Camel Case或Pascal Case,請參考這邊
- 避免使用全大寫或全小寫的wording,除了單一個word可以全小寫
-
範例
- Camel: gradeOfStudent
- Pascal: Customer
- 好的命名方式請參考:[讀書心得]Clean Code - Meaningful Names
Coding Style(格式)
- 一個檔案只包含一個namespace,只包含一個class,class名稱與檔名符合。
- Project名稱與dll名稱符合。
- 大括號的{與}各自獨立新的一行,判斷式都一定要加上{}。
- 宣告變數時,每個變數都獨立一行。
- Using namespace時,原生的namespace放最上面,最好都經過IDE的排序功能。
- Visibility越高的,放越前面。外面看的到的,通常命名也都是Pascal。通常public放最上面,protected次之,internal次之,private放下面。建構式放上面,屬性放上面。
- Interface的實作使用region區分。
- Namespace的階層與folder的階層一致。
- 每一個code block,有{}括起來的需按照block層級縮排。
- 使用tab, 斷行等對code進行排版。
- 宣告Attribute時,每個Attribute獨立一行。
最高指導原則:
- 一致
- 清楚
註解
- 註解使用//或///,不用/*...*/,除非是版權宣告。
-
禁止使用"flowbox",範例如下:
// ************************************** // Comment block // **************************************
- inline comment只用來表示:假設、issues、演算法提示。
- 好的程式碼應該從程式碼本身就能表現語意,而不是透過註解來說明程式碼的用途。
- 善用TODO, UNDONE, HACK等工作清單的關鍵字,請參考這邊。
- Public, protected, internal的部分,都應該使用///,來加上document註解。可透過工具來產生API文件。產生的部分,一定要包括<summary>,若有參數與回傳值,則要包括 <param>, <return>。工具的使用,請參考Sandcastle介紹。
Language Usage(變數與型別)
- 宣告時要加上access modifier的宣告,而不使用默認的值。例如void MethodName()就是不好的,改用private void MethodName()。
- 宣告access modifier時要謹慎,原則為:外面要使用此物件,能看到的東西最少,但又缺一不可。可見度範圍越小越好。
- 宣告值的範圍,越小越好。可以用int就不用long,可以用double,就不用decimal。
- 浮點數計算會有誤差,所謂『算錢用浮點,遲早被人扁』,需高精準度或算金額請用decimal。
- 盡量不去修改Enum的預設型別(int),除非不夠大,需要用到long。
- 宣告成constants的應該是簡單的型別,複雜的型別應使用readonly或static readonly。
- 用as轉型並檢查是否為null防呆,而避免使用強轉型。『用as轉型+判斷null,再使用轉型後的物件』,這樣的效率,比『用is判斷型別,再強轉型,再使用轉型後的物件』好。
- 盡量使用強型別。
- 避免boxing與unboxing的發生,會損耗內存記憶體。
- 字串前使用@,來讓字串本身更容易瞭解,而不用脫逸字元。也可以讓字串可透過斷行來排版。
- 善用String.Format來呈現字串的pattern。
- 善用StringBuilder來連結動態的字串。
- 判斷字串是否為空字串,避免用==string.Empty或=="",而使用.Length==0,或是string.IsNullOrEmpty。
- 判斷字串是否相等,盡量透過string.Compare是否為0,而不是透過toUpper()與toLower()轉換後比較。
流程控制
- 避免遞迴,而改用loop。(遞迴只應天上有,凡人應當用迴圈)
- 在foreach中,不要去異動集合範圍。例如在loop中去remove enumerated items。
- 避免在判斷式中,直接判斷某一個方法回傳值。
- 只在很單純的情況下,使用條件運算子(三元運算子),例如int result = isValid ? 9 : 4;
- 不在判斷式裡面assign變數值,例如if((i=2)==2) {…}
- 判斷式若為判斷某一個bool變數,則不需要再用==true或==false,因為bool值就代表該判斷式的意義。例如將if (isValid == true) {…} ,改寫成if (isValid) {…}
- 判斷式組合太複雜時,請用多個bool來表示,請參考[ASP.NET]重構之路系列v7 –簡化判斷式
- Switch case就只適合針對單一的變數進行比較,比較複雜的還是用if/else,但進階的設計方式,應該使用多型來取代switch case或多個判斷式,請參考[ASP.NET]重構之路系列v9 –使用介面+迴圈取代不穩定的判斷式
例外管理
- 避免使用try/catch來當if/else用,try/catch應該要能明確捕捉特定的exception。嚴禁try/catch捕捉到錯誤後,完全沒處理。
- 嚴禁在try/catch的catch block中,再使用try/catch
-
避免re-throw exception
錯誤的例子:
catch(Exception ex) { Log(ex); throw ex; }
正確的例子:
catch(Exception ex) { Log(ex); throw; }
- 可以用判斷式來決定流程,就不用try/catch。
Magic string / Magic number
- 使用constant或Enum來避免magic string與magic number,可參考[ASP.NET]重構之路系列v8 –合併重複的條件片段
- 使用Resources, Constants, Configuration Files, Registry 或其他資料來源,避免hard-code某一個字串。
結論
如同這個系列文的主題描述一樣,程式不是能動就好。誰都可以寫出讓機器懂的程式碼,但不是人人都能寫出人可以看懂的程式碼。訂出Code Convention,可以讓團隊降低開發成本、維護成本。透過工具來檢查程式碼,將可以更有效率的知道,系統是否有符合我們所定義的coding style。
blog 與課程更新內容,請前往新站位置:http://tdd.best/