標籤:
原文:http://www.cnblogs.com/wulinfeng/archive/2012/08/31/2664720.html
1 規範目的 ……………………………………………………… 3
2 適用範圍 ……………………………………………………… 3
3 代碼注釋 ……………………………………………………… 3
3.1 代碼注釋約定............................................ 3
3.2 模組頭部注釋規範...................................... 3
3.3 方法注釋規範............................................. 4
3.4 程式碼注釋規範.......................................... 6
3.5 變數注釋規範............................................. 7
4 命名規則 ……………………………………………………… 8
4.1 命名的基本約定.......................................... 8
4.2 各種標示符類型的基本約定......................... 9
4.3 組件名稱縮寫列表....................................... 10
5 其它規範 ……………………………………………………… 11
5.1 編程風格.................................................. 11
5.2 資源釋放.................................................. 13
5.3 錯誤處理.................................................. 13
5.4 其它......................................................... 14
1 規範目的
- 一個軟體的生命週期中,80%的花費在於維護;
- 幾乎沒有任何一個軟體,在其整個生命週期中,均由最初的開發人員來維護;
- 編碼規範可以改善軟體的可讀性,可以讓程式員儘快而徹底地理解新的代碼。為了執行規範,每個軟體開發人員必須一致遵守編碼規範;
- 使用統一編碼規範的主要原因,是使應用程式的結構和編碼風格標準化,以便於閱讀和理解這段代碼;
- 好的編碼約定可使原始碼嚴謹、可讀性強且意義清楚,與其它語言約定相一致,並且儘可能的直觀。
2 適用範圍
- 本規範主要以C#為開發語言的規範,為鮑亮實驗室的原則性規範;
- 由於本規範是為撰寫程式而設計,所以適用於一切有關程式撰寫的工作事項。對於具體的每個項目,可能需要對之進行裁剪和補存。
- 適用人員:軟體工程專業的學生;
- 適用產品:以C#編寫的程式。
3 代碼注釋
3.1 代碼注釋約定
- 所有的方法和函數都應該以描述這段代碼的功能的一段簡明注釋開始(方法是幹什麼)。這種描述不應該包括執行過程細節(它是怎麼做的),因為這常常是隨時間而變的,而且這種描述會導致不必要的注釋維護工作,甚至更糟—成為錯誤的注釋。代碼本身和必要的嵌入注釋將描述實現方法。
- 當參數的功能不明顯且當過程希望參數在一個特定的範圍內時,也應描述傳遞給過程的參數。被過程改變的函數傳回值和全域變數,特別是通過引用參數的那些,也必須在每個過程的起始處描述它們。
3.2 模組頭部注釋規範
以一個物理檔案為單元的都需要有模組頭部注釋規範,例如:C#中的.cs檔案
用於每個模組開頭的說明,主要包括:(粗體字為必需部分,其餘為可選部分)
- 檔案名稱(File Name): 此檔案的名稱
- 功能描述(Description): 此模組的功能描述與大概流程說明
- 資料表(Tables): 所用到的資料表,視圖,預存程序的說明,如關係比較複雜,則應說明哪些是可擦寫的,哪些表為唯讀。
- 作者(Author):
- 日期(Create Date):
- 參考文檔(Reference)(可選): 該檔所對應的分析文檔,設計文檔。
- 引用(Using) (可選)﹕ 開發的系統中引用其它系統的Dll、對象時,要列出其對應的出處,是否與系統有關﹙不清楚的可以不寫﹚,以方便製作安裝檔。
- 修改記錄(Revision History):若檔案的所有者改變,則需要有修改人員的名字、修改日期及修改理由。
- 分割符:*************************** (前後都要)
樣本如下:
3.3 方法注釋規範
1> C# 提供一種機制,使程式員可以使用含有XML 常值的特殊注釋文法為他們的代碼編寫文檔。在原始碼檔案中,具有某種格式的注釋可用於指導某個工具根 據這些注釋和它們後面的原始碼元素產生XML。具體應用當中,類、介面、屬性、方法必須有<Summary>節,另外方法如果有參數及傳回值,則必須有 <Param>及<Returns>節。樣本如下:
/// <summary>
/// …
/// </summary>
/// <param name=””></param>
/// <returns></returns>
2> 事件不需要頭註解,但包含複雜處理時(如:迴圈/資料庫操作/複雜邏輯等),應分割成單一處理函數,事件再調用函數。
3> 所有的方法必須在其定義前增加方法注釋。
4> 方法注釋採用 /// 形式自動產生XML標籤格式的注釋。
標記
說明
備忘
<c>
提供了一種將說明中的文本標記為代碼的方法
<code>
提供了一種將多行指示為代碼的方法
<example>
可以指定使用方法或其他庫成員的樣本。一般情況下,這將涉及到 <code> 標記的使用。
<exception>
對可從當前編譯環境中擷取的異常的引用。
<include>
得以引用描述原始碼中類型和成員的另一檔案中的注釋。
<list>
用於定義表或定義列表中的標題列。
<para>
用於諸如<summary>、<remarks> 或 <returns> 等標記內,使您得以將結構添加到文本中。
<param>
應當用於方法聲明的注釋中,以描述方法的一個參數。
<paramref>
提供了一種指示詞為參數的方法。
<permission>
得以將成員的訪問記入文檔。
<remarks>
用於添加有關某個類型的資訊,從而補充由 <summary> 所指定的資訊。
<returns>
應當用於方法聲明的注釋,以描述傳回值。
<see>
得以從文本內指定連結。
<seealso>
對可以通過當前編譯環境進行調用的成員或欄位的引用。
<summary>
應當用於描述類型或類型成員。
<value>
得以描述屬性。
樣本圖如下:
5> 在公用類庫中的公用方法需要在一般方法的注釋後添加作者、日期及修改記錄資訊,統一採用XML標籤的格式加註,標籤如下:
<Author></Author> 作者
<CreateDate></CreateDate> 建立日期
<RevisionHistory> 修改記錄
<ModifyBy></ModifyBy> 修改作者
<ModifyDate></ModifyDate> 修改日期
<ModifyReason></ModifyReason> 修改理由
<ModifyBy></ModifyBy> 修改作者
<ModifyDate></ModifyDate> 修改日期
<ModifyReason></ModifyReason> 修改理由
<ModifyBy></ModifyBy> 修改作者
<ModifyDate></ModifyDate> 修改日期
<ModifyReason></ModifyReason> 修改理由
</RevisionHistory>
<LastModifyDate></LastModifyDate> 最後修改日期
6> 一個代碼檔案如果是由一人編寫,則此代碼檔案中的方法無需作者資訊,非代碼檔案作者在此檔案中添加方法時必須要添加作者、日期等注釋。
7> 修改任何方法,必須要添加修改記錄的注釋。
3.4 程式碼注釋規範
1> 如果處理某一個功能需要很多行代碼實現,並且有很多邏輯結構塊,類似此種代碼應該在代碼開始前添加註釋,說明此塊代碼的處理思路及注意事項等
2> 注釋從新行增加,與代碼開始處靠左對齊
3> 雙斜線與注釋之間以空格分開,樣本圖如下所示:
3.5 變數注釋規範
1> 定義變數時需添加變數注釋,用以說明變數的用途。
2> Class級變數應以採用 /// 形式自動產生XML標籤格式的注釋,樣本圖如下所示:
3> 方法級的變數注釋可以放在變數聲明語句的後面,與前後行變數聲明的注釋靠左對齊,注釋與代碼間以Tab隔開。
4 命名規則
4.1 命名的基本約定
1> 要使用可以準確說明變數/欄位/類的完整的英文描述符,如firstName。對一些作用顯而易見的變數可以採用簡單的命名,如在迴圈裡的遞增(減)變數就可以 被命名為 “i”。
2> 要盡量採用項目所涉及領域的術語。
3> 要採用大小寫混合,提高名字的可讀性。為區分一個標識符中的多個單詞,把標識符中的每個單詞的首字母大寫。不採用底線作分隔字元的寫法。
有兩種適合的書寫方法,適應於不同類型的標識符:
PasalCasing:標識符的第一個單詞的字母大寫;
camelCasing:標識符的第一個單詞的字母小寫。
4> 下表描述了不同類型標識符的大小寫規則:
標識符
大小寫
樣本
命名空間
Pascal
namespace Com.Techstar.ProductionCenter
類型
Pascal
public class DevsList
介面
Pascal
public interface ITableModel
方法
Pascal
public void UpdateData()
屬性
Pascal
Public int Length{…}
事件
Pascal
public event EventHandler Changed;
私人欄位
Camel
private string fieldName;
非私人欄位
Pascal
public string FieldName;
枚舉值
Pascal
FileMode{Append}
參數
Camel
public void UpdateData(string fieldName)
局部變數
Camel
string fieldName;
5> 避免使用縮寫,如果一定要使用,就謹慎使用。同時,應該保留一個標準縮寫的列表,並且在使用時保持一致。
6> 對常見縮減詞,兩個字母的縮寫要採用統一大小寫方式(樣本:ioStream, getIOStream);多字母縮寫採用首字母大寫,其他字母小寫方式(樣本: getHtmlTag);
7> 避免使用長名字(最好不超過 15 個字母)。
8> 避免使用相似或者僅在大小寫上有區別的名字。
4.2 各種標示符類型的命名規範
1> 程式集命名
實驗室名稱(Lab)+ 項目名稱 + 模組名稱(可選),例如:
中心伺服器程式集:Lab.SeverCenter;
中心伺服器商務邏輯程式集:Lab.SeverCenter.Business;
2> 命名空間命名
採用和程式集命名相同的方式:實驗室名稱(Lab)+ 項目名稱 + 模組名稱。 另外,一般情況下建議命名空間和目錄結構相同。例如:
中心伺服器:Lab.SeverCenter;
中心伺服器下的使用者控制項:Lab.SeverCenter.UserControl;
中心伺服器商務邏輯:Lab.SeverCenter.Business;
中心伺服器資料訪問:Lab.SeverCenter.Data;
3> 程式集和DLL
l 大多數情況下,程式集包含全部或部分可重用庫,且它包含在單個動態連結程式庫(DLL) 中。
l 一個程式集可拆分到多個DLL 中,但這非常少見,在此準則中也沒有說明。
l 程式集和DLL 是庫的物理組織,而命名空間是邏輯組織,其構成應與程式集的組織無關。
l 命名空間可以且經常跨越多個程式集。可以考慮如下模式命名DLL:
<Company>.<Component>.dll
例:Lab.SeverCenter.dll
4> 類和介面命名
l 類的名字要用名詞;
l 避免使用單詞的縮寫,除非它的縮寫已經廣為人知,如HTTP。
l 介面的名字要以字母I開頭。保證對介面的標準實現名字只相差一個“I”首碼,例如對IComponent介面的標準實現為Component;
l 泛型型別參數的命名:命名要為T或者以T開頭的描述性名字,例如:
public class List<T>
public class MyClass<Tsession>
l 對同一項目的不同命名空間中的類,命名避免重複。避免引用時的衝突和混淆;
5> 方法命名
l 第一個單詞一般是動詞;
l 如果方法返回一個成員變數的值,方法名一般為Get+成員變數名,如若返回的值 是bool變數,一般以Is作為首碼。另外,如果必要,考慮用屬性來替代方法;
l 如果方法修改一個成員變數的值,方法名一般為:Set + 成員變數名。同上,考慮 用屬性來替代方法。
6> 變數命名
l 按照使用範圍來分,我們代碼中的變數的基本上有以下幾種類型,類的公有變數;類的私人變數(受保護同公有);方法的參數變數;方法內部使用的局部變數。 這些變數的命名規則基本相同,見標識符大小寫對照表。區別如下:
a) 類的公有變數按通常的方式命名,無特殊要求;
b) 類的私人變數採用兩種方式均可:採用加“m”首碼,例如mWorkerName;
c) 方法的參數變數採用camalString,例如workerName;
l 方法內部的局部變數採用camalString,例如workerName。
l 不要用_或&作為第一個字母;
l 盡量要使用短而且具有意義的單詞;
l 單字元的變數名一般只用於生命期非常短暫的變數:i,j,k,m,n一般用於integer;c,d,e 一般用於characters;s用於string
l 如果變數是集合,則變數名要用複數。例如表格的行數,命名應為:RowsCount;
l 命名組件要採用匈牙利命名法,所有首碼均應遵循同一個組件名稱縮寫列表
4.3 組件名稱縮寫列表
縮寫的基本原則是取組件類名各單詞的第一個字母,如果只有一個單詞,則去掉其中的母音,留下輔音。縮寫全部為小寫。
組件類型
縮寫
例子
Label
Lbl
lblNote
TextBox
Txt
txtName
Button
Btn
btnOK
ImageButton
Ib
ibOK
LinkButton
Lb
lbJump
HyperLink
Hl
hlJump
DropDownList
Ddl
ddlList
CheckBox
Cb
cbChoice
CheckBoxList
Cbl
cblGroup
RadioButton
Rb
rbChoice
RadioButtonList
Rbl
rblGroup
Image
Img
imgBeauty
Panel
Pnl
pnlTree
TreeView
Tv
tvUnit
WebComTable
Wct
wctBasic
ImageDateTimeInput
Dti
dtiStart
ComboBox
Cb
cbList
MyImageButton
Mib
mibOK
WebComm.TreeView
Tv
tvUnit
PageBar
Pb
pbMaster
5 其它規範
5.1 編程風格
1> 變數聲明:
為了保持更好的閱讀習慣,請不要把多個變數聲明寫在一行中,即一行只聲明一個變數。
例如:
String strTest1, strTest2;
應寫成:
String strTest1;
String strTest2;
2> 代碼縮排:
l 一致的代碼縮排風格,有利於代碼的結構層次的表達,使代碼更容易閱讀和傳閱;
l 代碼縮排使用Tab鍵實現,最好不要使用空格,為保證在不同機器上使代碼縮排保持一致,特此規定C#的Tab鍵寬度為4個字元,設定介面如下(工具–選項):
l 避免方法中有超過5個參數的情況,一般以2,3個為宜。如果超過了,則應使用struct來傳遞多個參數。
l 為了更容易閱讀,程式碼請不要太長,最好的寬度是螢幕寬度(根據不同的顯示分辯率其可見寬度也不同)。請不要超過您正在使用的螢幕寬度。(每行代碼不要 超過80個字元。)
l 程式中不應使用goto語句。
l 在switch語句中總是要default子句來顯示資訊。
l 方法參數多於8個時採用結構體或類方式傳遞
l 操作符/運算子左右空一個半形空格
l 所有塊的{}號分別放置一行,並嵌套對齊,不要放在同一行上
3> 空白:
l 空行將邏輯相關的程式碼片段分隔開,以提高可讀性。
l 下列情況應該總是使用兩個空行:
a) 一個源檔案的兩個片段(section)之間。
b) 類聲明和介面聲明之間。
l 下列情況應該總是使用一個空行:
a) 兩個方法之間。
b) 方法內的局部變數和方法的第一條語句之間。
c) 塊注釋(參見"5.1.1")或單行注釋(參見"5.1.2")之前。
d) 一個方法內的兩個邏輯段之間,用以提高可讀性。
l 下列情況應該總是使用空格:
a) 空白應該位於參數列表中逗號的後面,如:
void UpdateData(int a, int b)
b) 所有的二元運算子,除了".",應該使用空格將之與運算元分開。一元操作符和運算元之間不因該加空格,比如:負號("-")、自增("++")和自減("--")。例 如:
a += c + d;
d++;
c) for 語句中的運算式應該被空格分開,例如:
for (expr1; expr2; expr3)
d) 強制轉型後應該跟一個空格,例如:
char c;
int a = 1;
c = (char) a;
5.2 資源釋放
所有外部資源都必須顯式釋放。例如:資料庫連接對象、IO對象等。
5.3 錯誤處理
1> 不要“捕捉了異常卻什麼也不做“。如果隱藏了一個異常,你將永遠不知道異常到底發生了沒有。
2> 發生異常時,給出友好的訊息給使用者,但要精確記錄錯誤的所有可能細節,包括髮生的時間,和相關方法,類名等。
3> 只捕捉特定的異常,而不是一般的異常。
正確做法:
錯誤做法:
5.4 其它
1> 一個方法只完成一個任務。不要把多個工作群組合到一個方法中,即使那些任務非常小。
2> 使用C#的特有類型,而不是System命名空間中定義的別名資料型別。
3> 別在程式中使用固定數值,用常量代替。
4> 避免使用很多成員變數。聲明局部變數,並傳遞給方法。不要在方法間共用成員變數。如果在幾個方法間共用一個成員變數,那就很難知道是哪個方法在什麼 時候修改了它的值。
5> 別把成員變數聲明為 public 或 protected。都聲明為 private 而使用 public/protected 的屬性
6> 不在代碼中使用具體的路徑和磁碟機名。 使用相對路徑,並使路徑可程式化。
7> 應用程式啟動時作些“自檢”並確保所需檔案和附件在指定的位置。必要時檢查資料庫連接。出現任何問題給使用者一個友好的提示。
8> 如果需要的設定檔找不到,應用程式需能自己建立使用預設值的一份。
9> 如果在設定檔中發現錯誤值,應用程式要拋出錯誤,給出提示訊息告訴使用者正確值。
10> DataColumn取其列時要用欄位名,不要用索引號。
例: 正確DataColumn[“Name”]
不好 DataColumn[0]
11> 在一個類中,欄位定義全部統一放在class的頭部、所有方法或屬性的前面。
12> 在一個類中,所有的屬性全部定義在一個屬性塊中:
Version:1.0.0
Date:2012.8.30
c#編碼規範(轉載)