C# 语言规范
????????????
?
??????? C# 語言規范
?
??????????????????????????????? Trump Liu
?
?
?
第一章 概述
?
規范制定原則
?1 方便代碼的交流和維護。
?? 2 不影響編碼的效率,不與大眾習慣沖突。
?? 3 使代碼更美觀、閱讀更方便。
?? 4 使代碼的邏輯更清晰、更易于理解。
術語定義
Pascal 大小寫
????? 將標識符的首字母和后面連接的每個單詞的首字母都大寫。可以對三字符或更多字符的標識符使用Pascal 大小寫。例如
?????????????? BackColor
Camel 大小寫
標識符的首字母小寫,而每個后面連接的單詞的首字母都大寫。例如:
??????????????? backColor
?
文件命名
1 文件名遵從Pascal命名法,無特殊情況,擴展名小寫。
2 使用統一而又通用的文件擴展名: ClassName.cs
文件注釋
? 1 在每個文件頭必須包含以下注釋說明
??????????? /*----------------------------------------------------------------
??????????? // Copyright (C) chinasoftinc
??? // 版權所有
??????????? //
??????????? // 文件名:
??????????? // 文件功能描述:
??????????? //
??????????? //
??????????? // 創建標識:
??????????? //
??????????? // 修改標識:
??????????? // 修改描述:
??????????? //
??????????? // 修改標識:
??????????? // 修改描述:
??? //----------------------------------------------------------------*/
?
文件功能描述只需簡述,具體詳情在類的注釋中描述。
創建標識和修改標識由創建或修改人員的拼音或英文名加日期組成。如:
?
??? Trump 20120816
?
一天內有多個修改的只需做一個在注釋說明中做一個修改標識就夠了。
在所有的代碼修改處加上修改標識的注釋。
?
第二章?? 代碼組織與風格
列寬
??? 代碼列寬控制在110字符左右。
??? (大概這么寬)
??? public static SccmGridItem GetReportItem(SccmConsole adminConsole, string name, bool ignoreCase)
?
換行
????? 當表達式超出或即將超出規定的列寬,遵循以下規則進行換行
1、?????? 在逗號后換行。
public static SccmGridItem GetReportItem(SccmConsole adminConsole, string name, string balabala,
??????????????????????????????????????????? ?? bool ignoreCase)
2、?????? 在操作符前換行。
string test = "babalabalababalabalalabalababalabalababalabalababalabalababalabalababalabala" +
?????????? ?????????????? adminConsole.ToString();
?
????????? 3、規則1優先于規則2。
???? 當以上規則會導致代碼混亂的時候自己采取更靈活的換行規則。
縮進
???? 縮進應該是每行一個Tab(4個空格),不要在代碼中使用Tab字符。
空行
空行是為了將邏輯上相關聯的代碼分塊,以便提高代碼的可閱讀性。
??? 在以下情況下使用兩個空行
??? 1、接口和類的定義之間。
??? 2、枚舉和類的定義之間。
??? 3、類與類的定義之間。???????
????
??? 在以下情況下使用一個空行
???????? 1、方法與方法、屬性與屬性之間。
???????? 2、方法中變量聲明與語句之間。
???????? 3、方法中不同的邏輯塊之間。
????? 4、方法中的返回語句與其他的語句之間。
???????? 5、屬性與方法、屬性與字段、方法與字段之間。
???????? 6、注釋與它注釋的語句間不空行,但與其他的語句間空一行。
? ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? ? ? ? ?
函數長度
′ 每個函數有效代碼(不包括注釋和空行)長度不要超過50行。
空格
在以下情況中要使用到空格
??????? 1、 關鍵字和左括符 “(” 應該用空格隔開。如
?
?????????? while (true)???
?
2、?? 多個參數用逗號隔開,每個逗號后都應加一個空格。
3、?? 除了 . 之外,所有的二元操作符都應用空格與它們的操作數隔開。一元操作符、++及--與操作??? 數間不需要空格。如
?
??????????? ?a? +=? c? +? d;
?????????? a? =? (a? +? b)?? /?? (c? *? d);
?
??????????????? while? (d++? ==? s++)
??????????????? {
??????????????????? n++;
??????????????? }
?
4、 語句中的表達式之間用空格隔開。如
?
?????? for? (expr1;? expr2;? expr3)
5、強制類型轉換時,在類型和變量之間要加一空格。如 (int) i
括號 - ()
????? 1、 左括號“(” 不要緊靠關鍵字,中間用一個空格隔開。
????? 2、 左括號“(”? 與方法名之間不要添加任何空格。
????? 3、 沒有必要的話不要在返回語句中使用()。如
??
??????? if (condition)
??????????? return (a + b)
?
花括號 - {}
?????? 1、 左花括號 “{” 放于關鍵字或方法名的下一行并與之對齊。如
?
???????????? if (condition)
???????????? {
???????????? }
?
???????????? public int Add(int x, int y)
???????????? {
??????? ?????}
?
?????????????????????????? 2、 左花括號 “{” 要與相應的右花括號 “}”對齊。
?????? 3、 通常情況下左花括號 “{”單獨成行,不與任何語句并列一行。
?????? 4、 if、while、do、foreach等語句后一定要使用{},即使{}號中為空或只有一條語句。如
?
???????????? if (somevalue == 1)
???????????? {
???????????????? somevalue = 2;
???????????? }
?
5、 右花括號 “}” 后建議加一個注釋以便于方便的找到與之相應的 {。如
?
?????????????? while? (1)
?????????????? {
?????????????????? if? (valid)
?????????????????? {
?????????????????? } // if valid
?????????????????? else
?????????????????? {
?????????????????? } // not valid
??????????????? } // end forever
第三章 程序注釋
注釋概述
1、修改代碼時,總是使代碼周圍的注釋保持最新。
2、在每個例程的開始,提供標準的注釋樣本以指示例程的用途、假設和限制很有幫助。注釋樣本應該是解釋它為什么存在和可以做什么的簡短介紹.
3、避免在代碼行的末尾添加注釋;行尾注釋使代碼更難閱讀。不過在批注變量聲明時,行尾注釋是合適的;在這種情況下,將所有行尾注釋在公共制表位處對齊。
4 、避免雜亂的注釋,如一整行星號。而是應該使用空白將注釋同代碼分開。
5 、避免在塊注釋的周圍加上印刷框。這樣看起來可能很漂亮,但是難于維護。
6 、在部署發布之前,移除所有臨時或無關的注釋,以避免在日后的維護工作中產生混亂。
7 、如果需要用注釋來解釋復雜的代碼節,請檢查此代碼以確定是否應該重寫它。盡一切可能不注釋難以理解的代碼,而應該重寫它。盡管一般不應該為了使代碼更簡單以便于人們使用而犧牲性能,但必須保持性能和可維護性之間的平衡。
8 、在編寫注釋時使用完整的句子。注釋應該闡明代碼,而不應該增加多義性。
9 、在編寫代碼時就注釋,因為以后很可能沒有時間這樣做。另外,如果有機會復查已編寫的代碼,在今天看來很明顯的東西六周以后或許就不明顯了。
10 、避免多余的或不適當的注釋,如幽默的不主要的備注。
11、 使用注釋來解釋代碼的意圖。它們不應作為代碼的聯機翻譯。
12、 注釋代碼中不十分明顯的任何內容。
13 、為了防止問題反復出現,對錯誤修復和解決方法代碼總是使用注釋,尤其是在團隊環境中。
14 、對由循環和邏輯分支組成的代碼使用注釋。這些是幫助源代碼讀者的主要方面。
15 、在整個應用程序中,使用具有一致的標點和結構的統一樣式來構造注釋。
16 、用空白將注釋同注釋分隔符分開。在沒有顏色提示的情況下查看注釋時,這樣做會使注釋很明顯且容易被找到。
17 、在所有的代碼修改處加上修改標識的注釋。
18 、為了是層次清晰,在閉合的右花括號后注釋該閉合所對應的起點。
19、保持注釋的簡潔,不是任何代碼都需要注釋的,過多的注釋反而會影響代碼的可讀性。
20、注釋不要包括其他的特殊字符。
21、在VS2005環境中通過配置工程編譯時輸出XML文檔文件可以檢查注釋的完整情況,如果注釋不完整會報告編譯警告;
?
??? namespace Langchao.Procument.Web
{
} //end namespace Langchao.Procument.Web
?
文檔注釋
?該類注釋采用.Net已定義好的Xml標簽來標記,在聲明接口、類、方法、屬性、字段都應該使用該類注釋,以便代碼完成后直接生成代碼文檔,讓別人更好的了解代碼的實現和接口。如
?
? /// <summary>
??????? /// TestMethod2
??????? /// </summary>
??????? /// <param name="var1">description for var1</param>
??????? /// <param name="var2">description for var1</param>
??????? /// <returns>if balabala return balabala</returns>
??????? public int TestMethod2(string var1, string var2)
??????? {
???????? ??? //balabala
}
文檔注釋標簽
????
| 標簽 | 用法 | 作用 |
| <c> | c>text</c> ? text 希望將其指示為代碼的文本。 | 為您提供了一種將說明中的文本標記為代碼的方法。使用 <code> 將多行指示為代碼 |
| <para> | <para>content</para> content段落文本。 | 用于諸如 <remarks> 或 <returns> 等標記內,使您得以將結構添加到文本中。 |
| <param> | <param name='name'>description</param> name 為方法參數名。將此名稱用單引號括起來 (' ')。 | 應當用于方法聲明的注釋中,以描述方法的一個參數。 |
| <paramref> ? | <paramref ? name="name"/> ? name 要引用的參數名。將此名稱用雙引號括起來 ? (" ")。 | <paramref> 標記為您提供了一種指示詞為參數的方法。可以處理 XML 文件,從而用某種獨特的方法格式化該參數。 |
| <see> | <see cref="member"/> ? cref = "member" ? 對可以通過當前編譯環境進行調用的成員或字段的引用。編譯器檢查到給定代碼元素存在后,將 member 傳遞給輸出 XML 中的元素名。必須將 member 括在雙引號 ? (" ") 中。 | 使您得以從文本內指定鏈接。使用 <seealso> 指示希望在“請參閱”一節中出現的文本。 |
| <seealso> | <seealso cref="member"/> ? cref = "member" ? 對可以通過當前編譯環境進行調用的成員或字段的引用。編譯器檢查到給定代碼元素存在后,將 member 傳遞給輸出 XML 中的元素名。必須將 member 括在雙引號 ? (" ") 中 | 使您得以指定希望在“請參閱”一節中出現的文本。使用 <see> 從文本 |
| <example> | <example>description</example> ? description 代碼示例的說明。 | 使用 <example> 標記可以指定使用方法或其他庫成員的示例。一般情況下,這將涉及到 <code> 標記的使用。 |
| <code> | <code>content</code> ? content 為希望將其標記為代碼的文本。 ? | 記為您提供了一種將多行指示為代碼的方法。使用 <c> 指示應將說明中的文本標記為代碼 |
| <summary> | <summary>description</summary> ? 此處description 為對象的摘要。 | 應當用于描述類型成員。使用 <remarks> 以提供有關類型本身的信息。 |
| <exception> | <exception cref="member">description</exception> cref = "member" 對可從當前編譯環境中獲取的異常的引用。編譯器檢查到給定異常存在后,將 member 轉換為輸出 XML 中的規范化元素名。必須將 member 括在雙引號 (" ") 中。 description 說明。 | <exception> 標記使您可以指定類能夠引發的異常。 |
| <include> | <include file='filename' path='tagpath[@name="id"]' /> filename 包含文檔的文件名。該文件名可用路徑加以限定。將 filename 括在單引號中 (' ')。 Tagpath:filename 中指向標記名的標記路徑。將此路徑括在單引號中 (' ? ')。 name 注釋前邊的標記中的名稱說明符;名稱具有一個 id。 id 位于注釋之前的標記的 id。將此 id 括在雙引號中 (" ")。 | <include> 標記使您得以引用描述源代碼中類型和成員的另一文件中的注釋。這是除了將文檔注釋直接置于源代碼文件中之外的另一種可選方法。 <include> 標記使用 XML XPath 語法。有關自定義 <include> 使用的方法,請參閱 XPath 文檔。 |
| <list> | <list ? type="bullet" | "number" | "table"> ?? <listheader> ????? <term>term</term> ????? ? <description>description</description> ?? </listheader> ?? <item> ????? <term>term</term> ????? <description>description</description> ?? </item> </list> ? term? 定義的項,該項將在 text 中定義。 ? description? 目符號列表或編號列表中的項或者 term 的定義。 | <listheader> 塊用于定義表或定義列表中的標題行。定義表時,只需為標題中的項提供一個項。 列表中的每一項用 <item> 塊指定。創建定義列表時,既需要指定 term 也需要指定 text。但是,對于表、項目符號列表或編號列表,只需為 text 提供一個項。 列表或表所擁有的 <item> 塊數可以根據需要而定。 |
| <permission> | <permission cref="member">description</permission> ? cref = "member" 對可以通過當前編譯環境進行調用的成員或字段的引用。編譯器檢查到給定代碼元素存在后,將 member 轉換為輸出 XML 中的規范化元素名。必須將 member 括在雙引號 (" ") 中。 ? ? description? 成員的訪問的說明。 | <permission> 標記使您得以將成員的訪問記入文檔。System.Security.PermissionSet 使您得以指定對成員的訪問。 |
| <remarks> | <remarks>description</remarks> ? description 成員的說明。 | <remarks> 標記是可以指定有關類或其他類型的概述信息的位置。<summary> 是可以描述該類型的成員的位置。 |
| <returns> | <returns>description</returns> ? description 返回值的說明。 | <returns> 標記應當用于方法聲明的注釋,以描述返回值。 |
| <value> | <value>property-description</value> ? property-description 屬性的說明。 | <value> 標記使您得以描述屬性。請注意,當在 Visual Studio .NET 開發環境中通過代碼向導添加屬性時,它將會為新屬性添加 <summary> 標記。然后,應該手動添加 <value> 標記以描述該屬性所表示的值。 |
| ? | ? | ? |
?
第四章 聲明
每行聲明數
一行只建議作一個聲明,并按字母順序排列。如
?
????????? int level;?? //推薦
????????? int size;??? //推薦
????????? int x, y;??? //不推薦
?
初始化
????? 建議在變量聲明時就對其做初始化。???????
?
位置
????? 變量建議置于塊的開始處,不要總是在第一次使用它們的地方做聲明。如
?
???????? void MyMethod()
????????? {
?????????? ???int int1 = 0;???????? // beginning of method block
if (condition)
{
?????? ???????????int int2 = 0;???? // beginning of "if" block
????????? ????????...
????????? ????}
????????? }
??????? 不過也有一個例外
???????
??????????????? for (int i = 0; i < maxLoops; i++)
??????????????? {
??????????????????? ...
??????????????? }
?
??????? 應避免不同層次間的變量重名,如
?
??????????? int count;
??????????? ...
void MyMethod()
{
??????????????? if (condition)
??????????????? {
??????????????????? int count = 0;???? // 避免
???????????????????? ...
???????????????? }
??????????????? ?...
}
?
類和接口的聲明
????? 1 在方法名與其后的左括號間沒有任何空格。
????? 2 左花括號 “{” 出現在聲明的下行并與之對齊,單獨成行。
????? 3 方法間用一個空行隔開。
????
字段的聲明
不要使用是 public 或 protected 的實例字段。如果避免將字段直接公開給開發人員,可以更輕松地對類進行版本控制,原因是在維護二進制兼容性時字段不能被更改為屬性。考慮為字段提供 get 和set 屬性訪問器,而不是使它們成為公共的。 get 和 set 屬性訪問器中可執行代碼的存在使得可以進行后續改進,如在使用屬性或者得到屬性更改通知時根據需要創建對象。下面的代碼示例闡釋帶有get 和 set 屬性訪問器的私有實例字段的正確使用。 示例:
??????????? public class Control: Component
??????????? {
??????????? ???private int handle;
??????????? ???public? int Handle
??????????? ???{
??????????? ??????get
??????????? ??????{
??????????? ?????????return handle;
??????????? ??????}
??????????? ???}
????????? }
?
第五章 命名規范
?
命名概述
名稱應該說明“什么”而不是“如何”。通過避免使用公開基礎實現(它們會發生改變)的名稱,可以保留簡化復雜性的抽象層。例如,可以使用 GetNextStudent(),而不是 GetNextArrayElement()。
命名原則是:
選擇正確名稱時的困難可能表明需要進一步分析或定義項的目的。使名稱足夠長以便有一定的意義,并且足夠短以避免冗長。唯一名稱在編程上僅用于將各項區分開。表現力強的名稱是為了幫助人們閱讀;因此,提供人們可以理解的名稱是有意義的。不過,請確保選擇的名稱符合適用語言的規則和標準。
以下幾點是推薦的命名方法。
1、避免容易被主觀解釋的難懂的名稱,如方面名 AnalyzeThis(),或者屬性名 xxK8。這樣的名稱會導致多義性。
2、在類屬性的名稱中包含類名是多余的,如 Book.BookTitle。而是應該使用 Book.Title。
3、只要合適,在變量名的末尾或開頭加計算限定符(Avg、Sum、Min、Max、Index)。
4、在變量名中使用互補對,如 min/max、begin/end 和 open/close。
5、布爾變量名應該包含 Is,這意味著 Yes/No 或 True/False 值,如 fileIsFound。
6、在命名狀態變量時,避免使用諸如 Flag 的術語。狀態變量不同于布爾變量的地方是它可以具有兩個以上的可能值。不是使用 documentFlag,而是使用更具描述性的名稱,如 documentFormatType。 (此項只供參考)
7、即使對于可能僅出現在幾個代碼行中的生存期很短的變量,仍然使用有意義的名稱。僅對于短循環索引使用單字母變量名,如 i 或 j 可能的情況下,盡量不要使用原義數字或原義字符串,如
For i = 1 To 7而是使用命名常數,如 For i = 1 To NUM_DAYS_IN_WEEK 以便于維護和理解。
?????? 8、避免使用長名字(最好不超過 15 個字母)。
′?? ?9、避免使用相似或者僅在大小寫上有區別的名字。
?
大小寫規則
大寫
標識符中的所有字母都大寫。僅對于由兩個或者更少字母組成的標識符使用該約定。例如:
?
System.IO
System.Web.UI
?
下表匯總了大寫規則,并提供了不同類型的標識符的示例。
?
| 標識符 | 大小寫 | 示例 |
| 類 | Pascal | AppDomain |
| 枚舉類型 | Pascal | ErrorLevel |
| 枚舉值 | Pascal | FatalError |
| 委托 | Pascal | ValueChangeEventHandle 注意 總是以 EventHandle 后綴結尾 |
| 事件 | Pascal | ValueChange 注意 委托去掉EventHandle |
| 異常類 | Pascal | WebException 注意 總是以 Exception 后綴結尾。 |
| 只讀的靜態字段 | Pascal | RedValue |
| 接口 | Pascal | IDisposable 注意 總是以 I 前綴開始。 |
| 方法 | Pascal | ToString |
| 命名空間 | Pascal | System.Drawing |
| 屬性 | Pascal | BackColor |
| 公共實例字段 | Pascal | RedValue 注意 很少使用。屬性優于使用公共實例字段。 |
| 受保護的實例字段 | Camel | redValue 注意 很少使用。屬性優于使用受保護的實例字段。 |
| 私有的實例字段 | Camel | redValue |
| 參數 | Camel | typeName |
| 方法內的變量 | Camel | backColor |
?
?
縮寫
????? 為了避免混淆和保證跨語言交互操作,請遵循有關區縮寫的使用的下列規則:
????? 1 不要將縮寫或縮略形式用作標識符名稱的組成部分。例如,使用 GetWindow,而不要使用 GetWin。
????? 2 不要使用計算機領域中未被普遍接受的縮寫。
3 在適當的時候,使用眾所周知的縮寫替換冗長的詞組名稱。例如,用 UI 作為 User Interface 縮
寫,用 OLAP 作為 On-line Analytical Processing 的縮寫。
4在使用縮寫時,對于超過兩個字符長度的縮寫請使用 Pascal 大小寫或 Camel 大小寫。例如,使用 HtmlButton 或 HTMLButton。但是,應當大寫僅有兩個字符的縮寫,如,System.IO,而不是 System.Io。
5 不要在標識符或參數名稱中使用縮寫。如果必須使用縮寫,對于由多于兩個字符所組成的縮寫請
使用Camel 大小寫,雖然這和單詞的標準縮寫相沖突。
?
命名空間
????? 1、命名命名空間時的一般性規則是使用公司名稱,后跟技術名稱和可選的功能與設計,如下所示。
????? ??????CompanyName.TechnologyName[.Feature][.Design]
??????? 例如:
??????? namespace Chinasoft.Procurement????????????
???????? namespace Chinasoft.Procurement.DataRules??
?
????? 2、命名空間使用Pascal大小寫,用逗號分隔開。
???? 3、TechnologyName 指的是該項目的英文縮寫,或軟件名。
???? 4、命名空間和類不能使用同樣的名字。例如,有一個類被命名為Debug后,就不要再使用Debug作為一個名稱空間名。
?? 5、避免過深的命名空間;
′?6、避免太多的命名空間;
?
??
類
1、使用 Pascal 大小寫。
2、用名詞或名詞短語命名類。
3、使用全稱避免縮寫,除非縮寫已是一種公認的約定,如URL、HTML???
4 、不要使用類型前綴,如在類名稱上對類使用 C 前綴。例如,使用類名稱 FileStream,而不是
CFileStream。
5 、不要使用下劃線字符 (_)。
6 、有時候需要提供以字母 I 開始的類名稱,雖然該類不是接口。只要 I 是作為類名稱組成部分的整個單詞的第一個字母,這便是適當的。例如,類名稱 IdentityStore 是適當的。在適當的地方,使用復合單詞命名派生的類。派生類名稱的第二個部分應當是基類的名稱。例如,ApplicationException 對于從名為 Exception 的類派生的類是適當的名稱,原因ApplicationException 是一種Exception。請在應用該規則時進行合理的判斷。例如,Button 對于從 Control 派生的類是適當的名稱。盡管按鈕是一種控件,但是將 Control 作為類名稱的一部分將使名稱不必要地加長。
?
??????????? public class FileStream
??????????? public class Button
??????????? public class String
?
???
接口
????? 以下規則概述接口的命名指南:
????? 1、用名詞或名詞短語,或者描述行為的形容詞命名接口。例如,接口名稱 IComponent 使用描述性
名詞。接口名稱 ICustomAttributeProvider 使用名詞短語。名稱 IPersistable 使用形容詞。
2、使用 Pascal 大小寫。
????? 3、少用縮寫。
4、給接口名稱加上字母 I 前綴,以指示該類型為接口。在定義類/接口對(其中類是接口的標準
實現)時使用相似的名稱。兩個名稱的區別應該只是接口名稱上有字母 I 前綴。
?
5、不要使用下劃線字符 (_)。
6、當類是接口的標準執行時,定義這一對類/接口組合就要使用相似的名稱。兩個名稱的不同之處
只是接口名前有一個I前綴。
?
????????? 以下是正確命名的接口的示例。
?
??????????????? public interface IServiceProvider
??????????????? public interface IFormatable
?
????????? 以下代碼示例闡釋如何定義 IComponent 接口及其標準實現 Component 類。
?
?????????????? public interface IComponent
?????????????? {
?????????????????? // Implementation code goes here.
?????????????? }
??????????????
????? ?????????public class Component: IComponent
?????????????? {
?????????????????? // Implementation code goes here.
}
?
?
特性(Attribute)
應該總是將后綴 Attribute 添加到自定義特性類。以下是正確命名的屬性類的示例。
?
????????? public class ObsoleteAttribute
????????? {
}??
?
枚舉 (Enum)
?????? 枚舉 (Enum) 值類型從 Enum 類繼承。以下規則概述枚舉的命名指南:
?????????? 1 對于 Enum 類型和值名稱使用 Pascal 大小寫。
?????????? 2 少用縮寫。
?????????? 3 不要在 Enum 類型名稱上使用 Enum 后綴。
?????????? 4 對大多數 Enum 類型使用單數名稱,但是對作為位域的 Enum 類型使用復數名稱。
?????????? 5 總是將 FlagsAttribute 添加到位域 Enum 類型。
[Flags]
??????? public enum Week
??????? {
??????????? Monday,
??????????? Tuesday,
??????????? Wednesday,
??????????? Thursday,
??????????? Friday,
??????????? Saturday,
??????????? Sunday
??????? }
參數
?????? 以下規則概述參數的命名指南:
?????????? 1、使用描述性參數名稱。參數名稱應當具有足夠的描述性,以便參數的名稱及其類型可用于在大多數情況下確定它的含義。
?????? 2、對參數名稱使用 Camel 大小寫。
?????????? 3、 使用描述參數的含義的名稱,而不要使用描述參數的類型的名稱。開發工具將提供有關參數的類型的有意義的信息。因此, 通過描述意義,可以更好地使用參數的名稱。少用基于類型(弱類型)的參數名稱,僅在適合使用它們的地方使用它們。
?????????? 4、不要使用保留的參數。保留的參數是專用參數,如果需要,可以在未來的版本中公開它們。相反,如果在類庫的未來版本中需要更多的數據,請為方法添加新的重載。
?????????? 5、不要給參數名稱加匈牙利語類型表示法的前綴。
?????? 以下是正確命名的參數的示例。
?
?????????????? Type GetType(string typeName)
?
?
方法
?????? 以下規則概述方法的命名指南:
?????????? 1 使用動詞或動詞短語命名方法。
?????????? 2 使用 Pascal 大小寫。
?????????? 3 以下是正確命名的方法的實例。
?
????????????? RemoveAll()
????????????? GetCharArray()
Invoke()
?
?
屬性 (property)
??????? 以下規則概述屬性的命名指南:
??????????? 1 使用名詞或名詞短語命名屬性。
??????????? 2 使用 Pascal 大小寫。
??????????? 3 不要使用匈牙利語表示法。
?????????? 4 考慮用與屬性的基礎類型相同的名稱創建屬性。例如,如果聲明名為 Color 的屬性,則屬
???????????? 性的類型同樣應該是 Color。請參閱本主題中后面的示例。
?
????????? 以下代碼示例闡釋正確的屬性命名。
?
???????????????? public class SampleClass
???????????????? {
????????????????????? public Color BackColor
????????????????????? {
?????????????????????????? // Code for Get and Set accessors goes here.
?????????????????????? }
????????????????? }
?
??????????? 以下代碼示例闡釋提供其名稱與類型相同的屬性。
?
???????????????? public enum Color
???????????????? {
????????????????? ???// Insert code for Enum here.
????????????????? }
?
?
????????????????? public class Control
{
???????????????????? ??public Color Color
????????????????? ?????{
get
{
// Insert code here.
}
set
{
// Insert code here.
}
????????????????? ??????}
?????????????????? }
?
?????????? 以下代碼示例不正確,原因是 Color 屬性是 Integer 類型的。
??????????????? public enum Color
{
// Insert code for Enum here.
}
??????????????? public class Control
??????????????? {
???????????????? ???public int Color
???????????????? ???{
????????????????? ??????// Insert code here
???????????????????? }
??????????????? }
?
事件
??????? 以下規則概述事件的命名指南:
??????????? 1、對事件處理程序名稱使用 EventHandler 后綴(delegate)。
2、指定兩個名為 sender 和 e 的參數。sender 參數表示引發事件的對象。sender 參數始
終是object 類型的,即使在可以使用更為特定的類型時也如此。與事件相關聯的狀態封裝
在名為 e 的事件類的實例中。對 e 參數類型使用適當而特定的事件類。
3、用 EventArgs 后綴命名事件參數類。
??? 4、考慮用動詞命名事件。
5、使用動名詞(動詞的“ing”形式)創建表示事件前的概念的事件名稱,用過去式表示事
件后。例如,可以取消的 Close 事件應當具有 Closing 事件和 Closed 事件。不要使用
BeforeXxx/AfterXxx 命名模式。
??????????? 6、不要在類型的事件聲明上使用前綴或者后綴。例如,使用 Close,而不要使用 OnClose。
7、通常情況下,對于可以在派生類中重寫的事件,應在類型上提供一個受保護的方法(稱為
OnXxx)。此方法只應具有事件參數 e,因為發送方總是類型的實例。
?
??? 以下示例闡釋具有適當名稱和參數的事件處理程序。
?
?????????? ?public delegate void MouseEventHandler(object sender, MouseEventArgs e);
?
????? 以下示例闡釋正確命名的事件參數類。
?
??? ????????????public class MouseEventArgs : EventArgs
????? ??????????{
????? ?????????????int x;
????? ?????????int y;
?
??????????? ??????public MouseEventArgs(int x, int y)
????? ????????????{
this.x = x;
this.y = y;
}
?
????? ????????????public int X
????? ????????????{
????????????????????? get
????????????????????? {
????? ????????????????????return x;
??????????? ??????????}
????? ????????????}
?
????? ????????????public int Y
????? ????????????{
??? ?????????????get
??????????????? ???????{
????? ?????????????????????return y;
????? ?????????????????}
????? ????????????}
????? ??????????}
?
常量 (const)
??????? 以下規則概述常量的命名指南:
??????? 所有單詞大寫,多個單詞之間用 "_" 隔開。 如
?
???????????????? public const string PAGE_TITLE = "Welcome";
??????????
?
字段
??????? 以下規則概述字段的命名指南:
??????????? 1、private、protected 使用 Camel 大小寫。
??????????? 2、public 使用 Pascal 大小寫(不推薦使用public 字段)。
?????????? 3、拼寫出字段名稱中使用的所有單詞。僅在開發人員一般都能理解時使用縮寫。字段名稱不
???????????????? 要使用大寫字母。下面是正確命名的字段的示例。
?
??????????????? class SampleClass
??????????????? {
??????????? ??????????????string url;
?????????? ??string destinationUrl;
???? }
?
??????????? 4、不要對字段名使用匈牙利語表示法。好的名稱描述語義,而非類型。
?????????? 5、不要對字段名或靜態字段名應用前綴。具體說來,不要對字段名稱應用前綴來區分靜態和非靜態字段。例如,應用 g_ 或 s_ 前綴是不正確的。
?????????? 6、不要用_或&作為第一個字母;盡量要使用短而且具有意義的單詞;
?
靜態字段
?????? 以下規則概述靜態字段的命名指南:
?????????? 1、使用名詞、名詞短語或者名詞的縮寫命名靜態字段。
?????????? 2、使用 Pascal 大小寫。
?????????? 3、對靜態字段名稱使用匈牙利語表示法前綴。
?????????? 4、建議盡可能使用靜態屬性而不是公共靜態字段。
?
例如 : ????? static readonly int G_StudentCount;
?
??????? public static int StudentCount
??????? {
??????????? get
??????????? {
??????????????? return G_StudentCount;
??????????? }
??????? }
?
集合
???? 集合是一組組合在一起的類似的類型化對象,如哈希表、查詢、堆棧、字典和列表,集合的命名
建議用復數。
比如: List<Student> students;
??? DateRow dateRows;
泛型類型參數
的命名:命名要為T或者以T開頭的描述性名字,例如:
public class List<T>
public class MyClass<TSession>
?
措詞
避免使用與常用的 .NET 框架命名空間重復的類名稱。例如,不要將以下任何名稱用作類名稱:
System、Collections、Forms 或 UI。有關 .NET 框架命名空間的列表,請參閱類庫。
另外,避免使用和以下關鍵字沖突的標識符。
| AddHandler | AddressOf | Alias | And | Ansi |
| As | Assembly | Auto | Base | Boolean |
| ByRef | Byte | ByVal | Call | Case |
| Catch | CBool | CByte | Cchar | CDate |
| CDec | CDbl | Char | Cint | Class |
| CLng | CObj | Const | Cshort | CSng |
| CStr | CType | Date | Decimal | Declare |
| Default | Delegate | Dim | Do | Double |
| Each | Else | ElseIf | End | Enum |
| Erase | Error | Event | Exit | ExternalSource |
| False | Finalize | Finally ? | Float | For |
| Friend | Function | Get | GetType | Goto |
| Handles | If | Implements | Imports | In |
| Inherits | Integer | Interface | Is | Let |
| Lib | Like | Long | Loop | Me |
| Mod | Module | MustInherit | MustOverride | MyBase |
| MyClass | Namespace | New | Next | Not |
| Nothing | NotInheritable | NotOverridable | Object | On |
| Option | Optional | Or | Overloads | Overridable |
| Overrides | ParamArray | Preserve | Private | Property |
| Protected | Public | RaiseEvent | ReadOnly | ReDim |
| Region | REM | RemoveHandler | Resume | Return |
| Select | Set | Shadows | Shared | Short |
| Single | Static | Step | Stop | String |
| Structure | Sub | SyncLock | Then | Throw |
| To | True | Try | TypeOf | Unicode |
| Until | volatile | When | While | With |
| WithEvents | WriteOnly | Xor | Eval | extends |
| instanceof | package | var | ??? | ??? |
第六章 語句
每行一個語句
???????? 每行最多包含一個語句。如
???????????? a++;?????? //推薦
???????????? b--;?????? //推薦
a++; b--;? //不推薦
?
復合語句
復合語句是指包含"父語句{子語句;子語句;}"的語句,使用復合語句應遵循以下幾點
??????????? 1 子語句要縮進。
2 左花括號“{” 在復合語句父語句的下一行并與之對齊,單獨成行。
3 即使只有一條子語句要不要省略花括號“ {}”。 如
? ????????????????while? (d + =? s++)
???????????? ?????{
??????? ??????????????n++;
?? ?????????????????}
?????
return 語句
??????? return語句中不使用括號。如
?
?? ???????????return;
????? ????????return myDisk.size();
???????? ?????return (size == 1 ? size : defaultSize); //不推薦
?
if、 if-else、if else-if 語句
??????? if、 if-else、if else-if 語句使用格式
?
?? ?????????if (condition)
????? ??????{
???????? ???????statements;
?? ?????????}
?? ?????????if (condition)
????? ??????{
?? ?????????????statements;
?? ?????????}
?? ?????????else
?? ?????????{
????? ??????????statements;
???????? ???}
?
?? ?????????if (condition)
??????????? {
????? ??????????statements;
???????? ???}
?? ?????????else if (condition)
?? ?????????{
????? ??????????statements;
???????? ???}
?? ?????????else
?? ?????????{
????? ??????????statements;
???????? ???}
????????
?
for、foreach 語句
??????? for 語句使用格式
?
?? ?????????for (initialization; condition; update)
?? ?????????{
?? ?????????????statements;
?? ?????????}
?
?????? 空的 for 語句(所有的操作都在initialization、condition 或 update中實現)使用格式
?
????????????? for (initialization; condition; update);??? // update user id
???????
?????? foreach 語句使用格式
?
????????????? foreach (object obj in array)
????????????? {
????????????????? statements;
}
?
???????? ?? 注意1在循環過程中不要修改循環計數器。
?????????? 2對每個空循環體給出確認性注釋。
?????
while 語句
??????? while 語句使用格式
?
??????????? while (condition)
??????????? {
??????????????? statements;
??????????? }
?
???????? 空的 while 語句使用格式
???
????????????? while (condition);
???????????????
do - while 語句
???????? do - while 語句使用格式
????????????? do
????????????? {
?????????????? ???statements;
????????????? } while (condition);???????
???????
switch - case 語句
??? ?????switch - case? 語句使用格式
????????????? switch (condition)
????????????? {
???????????????????? case 1:
???????????????????????? statements;
???????????????????????? break;
?
???????????????????? case 2:
???????????????????????? statements;
???????????????????????? break;
?
???????????????????? default:
???????????????????????? statements;
???????????????????????? break;
???????????????? }
?
?????????? 注意:
?????????????? 1、語句switch中的每個case各占一行。
?????????????? 2、語句switch中的case按字母順序排列。
?????????????? 3、為所有switch語句提供default分支。
?????????????? 4、所有的非空 case 語句必須用 break; 語句結束。
?
try - catch 語句 ?????
????????? try - catch? 語句使用格式
????????????? try
????????????? {
????????????????? statements;
????????????? }
????????????? catch (ExceptionClass e)
????????????? {
????????????????? statements;
????????????? }
????????????? finally
????????????? {
??????????????? statements;
????????????? }
???
using 塊語句 ?????
???????? using 塊語句使用格式
???????????? using (object)
???????????? {
???????????????? statements;
???????????? }
?
goto 語句 ?????
? goto 語句使用格式
???????????? goto Label1:
???????????????? statements;
????????????? Lable1:
????????????????? statements;
//非不得已,強烈不建議使用goto語句
?
第七章????????????? 控件命名規則
命名方法
控件名簡寫+英文描述,英文描述首字母大寫
主要控件名簡寫對照表
| 組件類型 | 縮寫 | 例子 |
| 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 |
?
第八章????? 類型設計規范
類型和命名空間
?
?要用命名空間把類型組織成相關域的層次結構。例如:
界面層:Techstar.ProductionCenter;
業務邏輯層:Techstar.ProductionCenter.Business;
數據訪問層:Techstar.ProductionCenter.Data;
′
類型和接口的選擇
要優先采用類而不是接口。
接口的缺點在于語義變化時改變困難。注意接口并不是協定,把協定和實現分開并非一 定用接口實現,用基類和抽象類同樣可以表達;
建議使用抽象類而不是接口來解除協定與實現間的偶合;
要定義接口,來實現類似多重繼承的效果;
精心定義接口的標志是一個接口只做一件事情。關鍵是接口的協定需要保持不變, 如果一個接口包含太多功能,那么這個胖接口產生變化的機會就會大得多。
抽象類設計
′ 不要在抽象類中定義公有的或內部受保護的構造函數。因為抽象類無法實例化,所以這 種設計會誤導用戶;
? 要為抽象類定義受保護的構造函數或內部構造函數;
?? public abstract class TestClass
??? {
??????? protected TestClass()
??????? {
??????? }
??? }
?
靜態類設計
?
靜態類是一個只包含靜態成員的類,它提供了一種純面向對象設計和簡單性之間的一個權衡,廣泛用來提供類似于全局變量或一些通用功能。
要少用靜態類。靜態類應該僅用作輔助類;
′ 避免把靜態類當作雜物箱。每個靜態類都應該有其明確目的;
不要在靜態類中聲明或覆蓋實例成員;
枚舉設計
?
要用枚舉來加強那些表示值的集合的參數,屬性以及返回值的類型性;
要優先使用枚舉而不是靜態常量。例如:
//不好的寫法
public static class Color
{
public static int Red = 0;
public static int Green = 1;
public static int Blue = 2;
}
//好的寫法
public enum Color
{
Red,
Green,
Blue
}
枚舉最后一個值不要加逗號;
枚舉中不要提供為了今后使用而保留的枚舉值;
第九章????? 成員設計規范
方法,屬性,事件,構造函數以及字段等統稱為成員。
方法的重載規范
?避免在重載中隨意的給參數命名。如果兩個重載中的某個參數表示相同的輸入,那么該參數的名字應該相同。例如:
public class String
{
//好的寫法
public int IndexOf(string value) { ...}
public int IndexOf(string value, int startIndex) { ...}
//不好的寫法
public int IndexOf(string value) { ...}
public int IndexOf(string str, int startIndex) { ...}
}
′?避免使重載成員的參數順序不一致。在所有的重載中,同名參數應該出現在相同的位置。 例如:
public class EventLog
{
public EventLog();
public EventLog(string logName);
public EventLog(string logName, string machineName);
public EventLog(string logName, string machineName, string source);
}
較短的重載應該僅僅調用較長的來實現。另外,重載如果需要擴展性,把最長重載 做成虛函數。例如:
public class String
{
public int IndexOf(string s)
{
//調用
return IndexOf(s, 0);
}
public int IndexOf(string s, int startIndex)
{
//調用
return IndexOf(s, startIndex, s.Length);
}
public virtual int IndexOf(string s, int startIndex, int Count)
{
//實際的代碼
}
}
?要允許可選參選為null。這樣做是為了避免調用者調用之前需要檢查參數是否null。例 如:
//允許為null時的調用
DrawGeometry(brush, pen, geometry);
//不允許為null時的調用
if (geometry == null)
{
???? ?DrawGeometry(brush, pen);
}
else
{
??? ?DrawGeometry(brush, pen, geometry);
}
?
屬性和方法的選擇
?
基本原則是方法表示操作,屬性表示數據。如果其他各方面都一樣,優先使用屬性而不 是方法。
要使用屬性,如果該成員表示類型的邏輯attribue
如果屬性的值存儲在內存中,而提供屬性的目的僅僅是為了訪問該值,要使用屬性而不 要使用方法
如果該操作每次返回的結果不同,那么要使用方法。
如果該操作比訪問字段慢一個或多個數量級,要使用方法。
如果該操作有嚴重的副作用,要使用方法。
屬性的設計規范
如果不應該讓調用方法改變屬性值,要創建只讀屬性;
′?不要提供只寫屬性;
要為所有的屬性提供合理的默認值,這樣可以確保默認值不會導致漏洞或效率低的代 碼;
?要允許用戶以任何順序來設置屬性的值;
避免在屬性的獲取方法拋出異常。
屬性的獲取方法應該是個簡單的操作,不應該有任何的條件。如果一個獲取方法會拋出 異常,按么可能它更應該設計為方法。
構造函數的設計規范
?建議提供簡單的構造函數,最好是默認構造函數。簡單的構造函數增強易用性;
?考慮擴展性,如果構造函數設計的不自然,建議用靜態的工廠方法來替代構造函數;
?要把構造函數的參數用作設置主要屬性的便捷方法。如果構造函數參數僅用來設置屬 性,應和屬性名稱相同。僅有大小寫的區別;
?要在構造函數中做最少的工作。任何其他處理應該推遲到需要的時候;
?要在類中顯示的聲明公用的默認構造函數,如果這樣的構造函數是必須的。
?如果沒有顯示默認構造函數,填加有參數構造函數時往往會破壞已有使用默認構造函數 的代碼;
?避免在對象的構造函數內部調用虛成員。這樣在擴展設計的時候會導致難以理解的現 象;
字段設計規范
′?不要提供公有的或受保護的字段。代之以屬性來訪問字段;
?要只用常量字段來表示永遠不會改變的量。否則會導致兼容性問題。下面是正確的例子:
public struct Int32
{
public const int MaxValue = 0x7fffffff;
public const int MinValue = unchecked((int)0x80000000);
}
?要用公有的靜態只讀字段來定義預定義的對象實例。例如:
public struct Color
{
public static readonly Color Red = new Color(0x0000FF);
}
參數的設計規范
?要用類結構層次中最接近基類類型來作為參數的類型,同時要保證該類型能夠提供成員 所需的功能。例如:
要設計一個集合遍歷的方法,那么參數應該是IEnbumerable為參數,而不應該是IList, 這樣方法具有更強的適應性。
′?不要使用保留參數。如果將來需要更多的參數,那么可以增加重載成員。例如:
//不好的寫法
public void Method(string reserved, SomeOption option);
//好的寫法
public void Method(SomeOption option);
//將來填加
public void Method(SomeOption option, string path);
?
參數設計中枚舉和布爾參數的選擇規范
?
要用枚舉。在代碼閱讀,書寫中,枚舉都比布爾的可讀性好很多。例如:
//使用布爾型,閱讀的時候不會輕易了解參數的含義
FileStream f = File.Open(“1.txt”, true, false);
//使用枚舉型
FileStream f = File.Open(“1.txt”,CasingOptions.CaseSenstive, FileMode.Open);
′?不要使用布爾參數,除非百分之百肯定絕對不需要兩個以上的值。即使此時,采用枚舉 往往也可以提供更好的可讀性,如上例。
? 考慮在構造函數中,對確實只有兩種狀態值的參數以及用來初始化布爾屬性的參數使用 布爾類型;
?
參數驗證的規范:
要驗證傳給公有的,受保護的或顯示成員的參數是否合法。如果驗證失敗,應該拋出 System.ArgutmentException或其子類;
要拋出System.ArgutmentNullException,如果傳入的null,而該成員不支持null;
?
參數傳遞的規范
避免使用輸出參數或引用參數
第十章????? 異常處理規范
異常的思想是只對錯誤采用異常處理:邏輯和編程錯誤,設置錯誤,被破壞的數據,資源耗盡,等等。通常的法則是系統在正常狀態下以及無重載和硬件失效狀態下,不應產生任何異常。異常處理時可以采用適當的日志機制來報告異常,包括異常發生的時刻;
′ 一般情況下不要使用異常實現來控制程序流程結構;
′?使用異常而不要用錯誤代碼來報告錯誤;
??要通過拋出異常的方式來報告操作失敗。如果成員無法成功地完成它應該做的任務,那么應該拋出異常;
異常類型選擇規范
??優先考慮使用System命名空間中已有的異常,而不是自己創建新的異常類型;
??要使用最合理,最具針對性的異常。例如,對參數為空,應拋出?System.ArgutmentNullException,而不是System.ArgutmentException
異常處理規范
′ 不是百分之百確定的情況,不要吞掉異常;
??建議捕獲特定類型的異常,如果理解該異常在具體環境當中產生的原因;
′?不要捕獲不應該捕獲的異常,通常應該允許異常沿著調用棧傳遞;
? 進行清理工作時要用try-finally,避免使用try-catch;
??要在捕獲并重新拋出異常時使用空的throw語句,這是保持調用棧的最好方法
標準異常類的使用:
Exception與SystemException
′?不要拋出這兩種類型的異常;
′?避免捕獲這兩種異常,除非是在頂層的異常處理器中;
InvalidOperationException
? 對象處于不正確狀態時拋出;
ArgumentException,ArgumentNullException,ArgumentOutOfRangeException
? 如果傳入的是無效參數,要拋出參數異常,盡可能使用位于繼承層次末尾的類型;
??要在拋出異常時設置ParaName屬性;
NullRefernceException,IndexOutOfRangeException,AccessViolationException
′?不要顯示拋出或捕獲;
StackOverflowException:
′?不要顯示拋出或捕獲;
OutOfMemoryException:
′?不要顯示拋出或捕獲;
自定義異常類型設計規則:
′?避免太深的繼承層次;
??要從已有的異常基類繼承;
? 異常類要以“Exception”做為后綴;
??要使異常可序列化,使其能跨應用程序域和遠程邊界仍能正常使用;
??要把與安全性有關的信息保存在私有的異常狀態中
異常與性能
? 如果在普通場景都會拋出異常,要采用先效驗合法性的方式來避免拋出異常引起的性能 問題;
?
第十一章??????? 其他
?
表達式
1 避免在表達式中用賦值語句
3 避免對浮點類型做等于或不等于判斷
?
類型轉換
1盡量避免強制類型轉換。
2如果不得不做類型轉換,盡量用顯式方式。
參考文檔
附錄一: 匈牙利命名法
匈牙利命名法是一名匈牙利程序員發明的,而且他在微軟工作了多年。此命名法就是通過微軟的各種產品和文檔傳出來的。多數有經驗的程序員,不管他們用的是哪門兒語言,都或多或少在使用它。
這種命名法的基本原則是:
變量名=屬性+類型+對象描述
即一個變量名是由三部分信息組成,這樣,程序員很容易理解變量的類型、用途,而且便于記憶。
下邊是一些推薦使用的規則例子,你可以挑選使用,也可以根據個人喜好作些修改再用之。
⑴屬性部分:
全局變量: g_
常量 : c_
類成員變量: m_
⑵類型部分:
指針: p
句柄: h
布爾型: b
浮點型: f
無符號: u
⑶描述部分:
初始化: Init
臨時變量: Tmp
目的對象: Dst
源對象: Src
窗口: Wnd
下邊舉例說明:
hwnd: h表示句柄,wnd表示窗口,合起來為“窗口句柄”。
m_bFlag: m表示成員變量,b表示布爾,合起來為:“某個類的成員變量,布爾型,是一個狀態標志”。參考文檔
附錄二: 參考文檔
http://www.cnblogs.com/moss_tan_jun/archive/2010/10/10/1847380.html
網上流傳的 東軟集團 C# 編程規范 Version2
?
轉載于:https://www.cnblogs.com/kakaliush/archive/2013/03/17/2964143.html
總結
- 上一篇: 达州市电力集团书记是什么级别
- 下一篇: 煮好的毛蛋可以冷冻吗?