第一部分 簡介
本文檔只適用於C#語言以及其實現的.NET Framework公共類型系統(CTS)
一、使用編碼規範的目標:定義一些原則以保證編碼格式的一致性,提高代碼的可讀性和可維護性,並保護開發人員儘量減少由編碼引起的錯誤。
二、術語和定義
1.訪問修飾符:
public protected internal private C#中大多數成員使用private,而藉口和枚舉默認的訪問修飾符爲public
2.駱駝命名法
第一個單詞的首字母小寫,後續各單詞的首字母均大寫。
例:depName
3.公共類型系統
.NET Framework公共類型系統(CTS)定義如何聲明、使用和管理類型。所有本地的C#類型都基於CTS,支持跨語言集成。
4.標識符
自定義的標記,用於唯一命名對象或對象實例
例:public class MyclassOfPersonal{}
5.帕斯卡命名法
第一個單詞首字母大寫,後續個單詞的首字母也大寫。
三、命名總則
1.命名慣例:c 表示駱駝命名法p 表示帕斯卡命名法 – 表示下劃線爲前綴
標識符 public protected internal private 說明
項目文件 p 與程序集和命名空間匹配
源文件 p 與包含的類匹配
其他文件 p 在可能的位置使用
命名空間 p 與項目/程序集部分匹配
類或結構 p p p p 爲子類添加後綴
接口 p p p p 用大寫字母I作前綴
方法 p p p p 使用動詞或動詞與對象組合
屬性 p p p p 不要用Get或Set做前綴
字段 p p p _c 只使用private字段,不使用胸牙利命名法
常量 p p p _c
靜態字段 p p p _c 只使用private字段
枚舉 p p p p 枚舉符中的可選項也必須符合帕斯卡命名法
委託 p p p p
事件 p p p p
參數 c
2.編碼風格
代碼 風格
源文件 每個文件有一個命名空間和一個類
大括號 位於新行,可選時始終使用括號
縮進 使用大小爲4的製表符
註釋 使用//或///,不使用“…”,也不使用星號框註釋方法
變量 每個聲明有一個變量
3.語言用法
本地數據類型 使用內置C#本地數據類型與.NET CTS類型,例如使用int而不是Int32
枚舉 避免更改默認類型
屬性 不要用Get或Set做前綴
方法 最多是用7個參數
base和this 僅用於構造函數或重寫中
foreach語句 不要修改foreach語句中的枚舉項
條件 避免針對true或false計算布貳條件;不使用嵌入式賦值;避免調用嵌入式方法
異常 不得將異常用於流控制;重新引發是使用throw;而不是throw e;只捕獲可以處理的內容; 使用驗證以避免發生異常;從Execption而不是ApplicationException中派生
事件 調用前始終檢查是否爲null
Dispose()和Close() 如果提供了這些方法,則始終對其進行調用,並在需要的位置進行聲明
程序集版本 手動遞增
第二部分 命名慣例
命名慣例:一致性—是可維護代碼的關鍵。對於命名項目、源文件和標識符(如字段、變量、屬性、方法、參數、類、接口、和命名空間),要確保命名的一致性。
一、一些通用的規則
1.始終使用駱駝命名法或帕斯卡命名法。
2.避免使用全部大寫和全部小寫的名稱,單個小寫單詞或字母是允許的。
3.不要創建只按照大寫而改變的命名空間、類、方法、屬性、字段或參數。
4.不要使用以數字字符開頭的名稱。
5.選擇有意義且特定的名稱。
6.儘量使用詳盡而不過於簡潔的命名。
7.變量和屬性應該描述實體而不是類型或大小。
8.不推薦使用匈牙利命名法。
9.避免使用縮略語,除非全程過長。
10.避免使用超過5個字符的縮略語。
11.所有的縮略語都必須爲大家所熟知和接受。
12.對兩個字母的縮略語使用小寫,而對較長的縮略語使用帕斯卡命名法。
13.不使用C#保留字作爲名稱。
14.避免命名與現有.NET Framework命名空間或類型衝突。
15.避免向標識符添加冗長或沒有意義的前綴和後綴。
16.不要在屬性名稱中包含父類名稱。
17.儘量將Can Is Has 用做布爾變量和屬性的前綴。
18.在適當的地方將計算限定符附加給變量名稱,如Average、Count、Sum、Min、Max
19.定義根命名空間時,請將產品名、公司名或開發人員姓名作爲根。
二、名稱用法與語法
項目文件:帕斯卡命名法。始終將程序集名稱與根命名空間匹配。
源文件:帕斯卡命名法,始終將類名與文件名匹配。避免每個文件包括多個類、枚舉(全局)或委託(全局)。包含多個類、枚舉或委託時,使用描述性文件名。
資源或嵌入式文件:儘量使用帕斯卡命名法。使用描述文件內容的名稱。
命名空間:帕斯卡命名法。儘量與醒目/程序集名稱部分匹配。
類或結構:帕斯卡命名法。用名詞或名詞短語作爲類名稱。如果可能,在爲其他類型劃分子類是添加相應的類後綴。
接口:帕斯卡命名法。用大寫字母I作爲接口名稱的前綴。
方法:帕斯卡命名法。儘量使用動詞或動詞與對象組合。
屬性:帕斯卡命名法。屬性名稱應該表示其返回的實體。絕對不要將Get或Set用作屬性名稱的前綴。
字段(Public、Protected或Internal):帕斯卡命名法。避免使用非private字段!請使用屬性。
字段(Private):使用駱駝命名法,並用單個下劃線字符“_”作爲前綴。
常量或靜態字段:作爲字段處理,選擇以上響應的字段訪問修飾符。
枚舉:使用帕斯卡命名法(類型和選項)。
委託或事件:作爲字段處理,選擇以上相應的字段訪問修飾符。
參數:駱駝命名法。
第三部分 編碼風格
編碼風格:以下描述實現C#源代碼推薦的方法,以便創建易於理解、易於維護、可讀性強、結構清晰並且前後一致的代碼。
一、格式設置:
1、每個文件不要生命多個命名空間。
2、避免在單個文件中放置多個類。
3、將大括號{和}放置於新行。
4、在條件語句中使用大括號{和}。
5、使用大小爲4的製表符和縮進。
6、獨立聲明每個變量,即不在同一個語句中聲明多個變量。
7、將命名空間和using語句置於文件頂部。將命名空間分組爲.NET 命名空間和自定義命名空間。
8、按照以下順序按類型對內部類進行分組。
成員變量。
構造函數與終結器。
嵌套枚舉、結構和類。
屬性。
方法。
9、根據訪問修飾符和可見性爲類型中的序列聲明分組。
public
protected
internal
pricate
10、將文件夾名稱附加到子文件夾內源文件的命名空間。
11、遞歸縮進括號內包含的所有代碼塊。
12、使用空白(回車符/換行符、製表符等)分割和組織代碼。
13、將程序集範圍的屬性聲明放置於一個單獨的行。
14、將類型範圍的屬性聲明放置在一個單獨的行。
15、將方法範圍的屬性聲明放置在一個單獨的行。
16、將成員範圍的屬性聲明放置在一個單獨的行。
17、將參數屬性是聲明於參數內聯。
18、如果存有疑問,結構清晰、前後一致爲原則。
二、代碼註釋
1、使用//或///,不使用/*….*/。
2、不使用星號框註釋方法。
3、不要使用行內註釋解釋明顯易懂的代碼,質量高的編碼具有自解釋性能。
4、始終爲public、protected和internal聲明應用C#註釋塊(//)
第四部分 語言用法
一、一般用法
1、不要省略訪問修飾符。用相應訪問修飾符顯式聲明所有標識符,而不允許顯式聲明默認值的標識符。
2、不要使用默認的(“1.0.*”)版本控制模式。手動增加AssemblyVersionAttribute值。
3、將所有程序集的ComVisibleAttibute設置爲false。然後,選擇性地對需要的單個類啓用ComVisibleAttribute。
4、避免程序集之間的相互引用。
二、變量和類型
1、儘量在聲明變量的語句中將變量初始化。
2、使用要求的最簡單的數據類型、列表或對象。例如,一般使用int類型,除非知道需要存儲64位的值,才使用long類型。
3、始終使用內置C#數據類型別名,而不是.NET公共類型系統(CTS),包括:
使用short不用System.Int16
使用int不用System.Int32
使用long不用System.Int64
使用string不用System.String
4、只是將成員變量聲明爲private,使用屬性爲帶有public、protected或internal訪問修飾符的變量提供訪問。
5、避免爲enum指定類型。除非顯式需要long類型,否則使用默認的int類型。
6、避免聲明內聯字符串常數,而是使用常量、資源、註冊表或其他數據資源。
7、只爲簡單類型生命常量。
8、爲複雜類型聲明只讀或靜態只讀變量,而不聲明常量。
9、避免直接類型轉換。而是使用as 運算符並檢查是否爲null。
10、始終使用for循環顯式初始化引用類型的數組。
11、避免裝箱和拆箱值類型。
12、浮點值在小數點前後至少應該各包括一個數字。
13、在字符串常數前加上前綴@,而不使用轉義字符串。
14、不要在循環內連接字符串。
15、不要將字符串與String.Empty或“”相比較來檢查空字符串,而是使用String.Length==0進行比較。
16、避免在循環內進行隱藏的字符串分配,而是使用String.Compare()。
三、流控制
1、避免在條件表達式內調用方法。
2、避免使用foreach循環不可變值類型集合,如字符串數組。
3、不要修改foreach語句中的枚舉項。
4、避免針對true或false計算布爾條件。
5、避免在條件語句內進行賦值。
6、避免使用複合條件表達式,請使用布爾變量將各部分分爲多個易處理的表達式。
7、避免在條件中進行顯式布爾測試。
8、只對具有並行條件邏輯的簡單操作使用switch/case語句。
9、對於短條件序列和複雜條件,優先使用嵌套if/else語句,而不是switch/case。
10、優先使用多態而不是switch/case來封裝和委託複雜操作。
四、異常處理
1、不使用try/catch塊用於流控制。
2、只捕獲可處理的異常。
3、不的聲明空catch塊。
4、避免在catch塊內嵌套try/catch。
5、避免再次引發異常,而是允許其冒泡。
6、如果再次引發異常,則省略throw語句中的異常參數,以保留原始調用堆棧。
7、只使用finally塊從try語句中釋放資源。
8、使用驗證來避免異常。
9、引發新異常時,使用傳遞innerException,以維護異常樹和內部調用堆棧。
五、事件、委託和線程
1、調用前始終檢查事件和委託實例是否爲空。
2、對簡單的時間使用默認的EventHandler和EventArgs。
3、派生一個自定義EventArgs類,以提供附加數據。
4、使用現有的CancelEventArgs類,以允許事件訂閱人控制事件。
六、對象組合
1.在明明空間內部聲明類型,不要使用默認命名空間。
2、不要聲明超過帶有7個參數的方法,而是重構或考慮傳遞結構或類。
3、不要使用new關鍵字隱藏派生類型的成員。
4、在重寫中調用基類構造函數或基本實現時,只使用base關鍵字。
5、考慮使用方法重寫,而不是params屬性。
6、使用枚舉變量或參數值之前始終進行驗證。它們可能包含基本枚舉類型(默認int)支持的任何值。
7、對提供Close()或Dispose()的類調用Close()或Dispose()。
8、用using語句包括Idisosable對象的實例化,以確保自動調用Dispose()。
9、在引用外部資源的類上實現Idisposable接口和模式。
第五部分 對象模型設計
1、優先使用委託而不是繼承。
2、以最簡單的步驟完成有效的操作,然後在時間允許時進行重構。
3、始終將表示層與業務邏輯層分開。
4、始終優先使用接口而不是抽象類。
5、儘量在適當的地方將設計模式名稱附加到類名。
6、如果設計和測試成員是爲了方便擴展,則使該成員爲虛(virtual)成員。