陳年的文檔,不過(guò)很不錯(cuò)整理出來(lái)發(fā)到博客上,還有更多的朋友需要。 10.1. 成員設(shè)計(jì)的一般規(guī)范 17 10.2. 屬性的設(shè)計(jì)規(guī)范: 19 10.3. 構(gòu)造函數(shù)的設(shè)計(jì)規(guī)范 20 10.5. 參數(shù)的設(shè)計(jì)規(guī)范 21 10.5.1. 參數(shù)設(shè)計(jì)中枚舉和布爾參數(shù)的選擇規(guī)范 21 10.5.2. 參數(shù)驗(yàn)證的規(guī)范: 22 11. 擴(kuò)展性設(shè)計(jì)規(guī)范 22 12.3. 標(biāo)準(zhǔn)異常類的使用: 23 12.3.1. Exception與SystemException 23 12.3.2. InvalidOperationException 24 12.3.3. ArgumentException,ArgumentNullException,ArgumentOutOfRangeException 24 12.3.4. NullRefernceException,IndexOutOfRangeException,AccessViolationException 24 12.3.5. StackOverflowException: 24 12.3.6. OutOfMemoryException: 24 12.4. 自定義異常類型設(shè)計(jì)規(guī)則: 24
1. 簡(jiǎn)介本規(guī)范為一套編寫高效可靠的 C# 代碼的標(biāo)準(zhǔn)、約定和指南。它以安全可靠的軟件工程原則為基礎(chǔ),使代碼易于理解、維護(hù)和增強(qiáng),提高生產(chǎn)效率。同時(shí),將帶來(lái)更大的一致性,使軟件開(kāi)發(fā)團(tuán)隊(duì)的效率明顯提高。 2. 適用范圍本規(guī)范適用于公司所有的C#源代碼,為詳細(xì)設(shè)計(jì),代碼編寫和代碼審核提供參考和依據(jù)。 3. 文體本規(guī)范中的建議分為四種:要,建議,避免,不要,表示需要遵循的級(jí)別。文檔中會(huì)以粗體表示。對(duì)于應(yīng)遵循的規(guī)范,前面會(huì)以“?”來(lái)表示,對(duì)不好的做法前面會(huì)以“′”來(lái)表示: 要:描述必須遵循的規(guī)范。例如: 異常類要以“Exception”做為后綴; 建議:描述在一般情況下應(yīng)該遵循的規(guī)范,但如果完全理解規(guī)范背后的道理,并有很好的理由不遵循它時(shí),也不畏懼打破常規(guī)。例如: 強(qiáng)制類型轉(zhuǎn)換時(shí),在類型和變量之間建議加一空格。 不要:描述一些幾乎絕對(duì)絕不應(yīng)該違反的規(guī)范。例如: ′ 每個(gè)函數(shù)有效代碼(不包括注釋和空行)長(zhǎng)度不要超過(guò)50行。 避免:與建議相對(duì),一般情況下應(yīng)該遵循,但有很好的理由時(shí)也可以打破。例如: ′ 避免塊內(nèi)部的變量與它外部的變量名相同。 對(duì)一些規(guī)范內(nèi)容一并提供了示例代碼。 4. 代碼組織與風(fēng)格4.1. Tab要使一個(gè)Tab為4個(gè)空格長(zhǎng)。 4.2. 縮進(jìn)要使一個(gè)代碼塊內(nèi)的代碼都統(tǒng)一縮進(jìn)一個(gè)Tab長(zhǎng)度。 4.3. 空行建議適當(dāng)?shù)脑黾涌招?,?lái)增加代碼的可讀性。 在在類,接口以及彼此之間要有兩行空行: 在下列情況之間要有一行空行: 方法之間; 局部變量和它后邊的語(yǔ)句之間; 方法內(nèi)的功能邏輯部分之間; 4.4. 函數(shù)長(zhǎng)度′ 每個(gè)函數(shù)有效代碼(不包括注釋和空行)長(zhǎng)度不要超過(guò)50行。 4.5. {”,“}”開(kāi)括號(hào)“{”要放在塊的所有者的下一行,單起一行; 閉括號(hào)“}”要單獨(dú)放在代碼塊的最后一行,單起一行。 4.6. 行寬′ 每行代碼和注釋不要超過(guò)70個(gè)字符或屏幕的寬度,如超過(guò)則應(yīng)換行,換行后的代碼應(yīng)該縮進(jìn)一個(gè)Tab。 4.7. 空格′ 括號(hào)和它里面的字符之間不要出現(xiàn)空格。括號(hào)應(yīng)該和它前邊的關(guān)鍵詞留有空格,如:while (true) {}; ′ 但是方法名和左括號(hào)之間不要有空格。 參數(shù)之間的逗號(hào)后要加一空格。如:method1(int i1, int i2) for語(yǔ)句里的表達(dá)式之間要加一空格。如:for (expr1; expr2; expr3) 二元操作符和操作數(shù)之間要用空格隔開(kāi)。如:i + c; 強(qiáng)制類型轉(zhuǎn)換時(shí),在類型和變量之間要加一空格。如:(int) i ; 5. 注釋5.1. 注釋的基本約定注釋應(yīng)該增加代碼的清晰度; 保持注釋的簡(jiǎn)潔,不是任何代碼都需要注釋的,過(guò)多的注釋反而會(huì)影響代碼的可讀性。 ′ 注釋不要包括其他的特殊字符。 建議先寫注釋,后寫代碼,注釋和代碼一起完成 如果語(yǔ)句塊(比如循環(huán)和條件分枝的代碼塊)代碼太長(zhǎng),嵌套太多,則在其結(jié)束“}”要加上注釋,標(biāo)志對(duì)應(yīng)的開(kāi)始語(yǔ)句。如果分支條件邏輯比較復(fù)雜,也要加上注釋。 在VS2005環(huán)境中通過(guò)配置工程編譯時(shí)輸出XML文檔文件可以檢查注釋的完整情況,如果注釋不完整會(huì)報(bào)告編譯警告; 5.2. 注釋類型5.2.1. 塊注釋主要用來(lái)描述文件,類,方法,算法等,放在所描述對(duì)象的前邊。具體格式以IDE編輯器輸入“///”自動(dòng)生成的格式為準(zhǔn),另外再附加我們自定義的格式,如下所列: /// <Remark>作者,創(chuàng)建日期,修改日期</ Remark > 對(duì)類和接口的注釋必須加上上述標(biāo)記,對(duì)方法可以視情況考慮 5.2.2. 行注釋主要用在方法內(nèi)部,對(duì)代碼,變量,流程等進(jìn)行說(shuō)明。整個(gè)注釋占據(jù)一行。 5.2.3. 尾隨注釋與行注釋功能相似,放在代碼的同行,但是要與代碼之間有足夠的空間,便于分清。例: int m = 4 ; // 注釋 如果一個(gè)程序塊內(nèi)有多個(gè)尾隨注釋,每個(gè)注釋的縮進(jìn)要保持一致。 5.3. 注釋哪些部分
5.4. 程序修改注釋新增代碼行的前后要有注釋行說(shuō)明,對(duì)具體格式不作要求,但必須包含作者,新增時(shí)間,新增目的。在新增代碼的最后必須加上結(jié)束標(biāo)志; 刪除代碼行的前后要用注釋行說(shuō)明,刪除代碼用注釋原有代碼的方法。注釋方法和內(nèi)容同新增;刪除的代碼行建議用#region XXX #endregion 代碼段折疊,保持代碼文件干凈整潔 修改代碼行建議以刪除代碼行后再新增代碼行的方式進(jìn)行(針對(duì)別人的代碼進(jìn)行修改時(shí),必須標(biāo)明,對(duì)于自己的代碼進(jìn)行修改時(shí),酌情進(jìn)行)。注釋方法和內(nèi)容同新增; 6. 命名6.1. 命名的基本約定要使用可以準(zhǔn)確說(shuō)明變量/字段/類的完整的英文描述符,如firstName。對(duì)一些作用顯而易見(jiàn)的變量可以采用簡(jiǎn)單的命名,如在循環(huán)里的遞增(減)變量就可以被命名為 ” i ”。 要盡量采用項(xiàng)目所涉及領(lǐng)域的術(shù)語(yǔ)。 要采用大小寫混合,提高名字的可讀性。為區(qū)分一個(gè)標(biāo)識(shí)符中的多個(gè)單詞,把標(biāo)識(shí)符中的每個(gè)單詞的首字母大寫。不采用下劃線作分隔字符的寫法。有兩種適合的書寫方法,適應(yīng)于不同類型的標(biāo)識(shí)符: PasalCasing:標(biāo)識(shí)符的第一個(gè)單詞的字母大寫; camelCasing:標(biāo)識(shí)符的第一個(gè)單詞的字母小寫。 下表描述了不同類型標(biāo)識(shí)符的大小寫規(guī)則:
′ 避免使用縮寫,如果一定要使用,就謹(jǐn)慎使用。同時(shí),應(yīng)該保留一個(gè)標(biāo)準(zhǔn)縮寫的列表,并且在使用時(shí)保持一致。 對(duì)常見(jiàn)縮略詞,兩個(gè)字母的縮寫要采用統(tǒng)一大小寫的方式(示例:ioStream,getIOStream);多字母縮寫采用首字母大寫,其他字母小寫的方式(示例:getHtmlTag); ′ 避免使用長(zhǎng)名字(最好不超過(guò) 15 個(gè)字母)。 ′ 避免使用相似或者僅在大小寫上有區(qū)別的名字。 6.2. 各種標(biāo)示符類型的命名約定6.2.1. 程序集命名公司域名(Techstar)+ 項(xiàng)目名稱 + 模塊名稱(可選),例如: 中心系統(tǒng)程序集:Techstar.ProductionCenter; 中心系統(tǒng)業(yè)務(wù)邏輯程序集:Techstar. ProductionCenter.Business; 6.2.2. 命名空間命名采用和程序集命名相同的方式:公司域名(Techstar)+ 項(xiàng)目名稱 + 模塊名稱。 另外,一般情況下建議命名空間和目錄結(jié)構(gòu)相同。例如: 中心系統(tǒng):Techstar.ProductionCenter; 中心系統(tǒng)下的用戶控件:Techstar.ProductionCenter.UserControl; 中心系統(tǒng)業(yè)務(wù)邏輯:Techstar. ProductionCenter.Business; 中心系統(tǒng)數(shù)據(jù)訪問(wèn):Techstar. ProductionCenter.Data; 6.2.3. 類和接口命名類的名字要用名詞; ′ 避免使用單詞的縮寫,除非它的縮寫已經(jīng)廣為人知,如HTTP。 接口的名字要以字母I開(kāi)頭。保證對(duì)接口的標(biāo)準(zhǔn)實(shí)現(xiàn)名字只相差一個(gè)“I”前綴,例如對(duì)IComponent的標(biāo)準(zhǔn)實(shí)現(xiàn)為Component; 泛型類型參數(shù)的命名:命名要為T或者以T開(kāi)頭的描述性名字,例如: public class List<T> public class MyClass<TSession> ′ 對(duì)同一項(xiàng)目的不同命名空間中的類,命名避免重復(fù)。避免引用時(shí)的沖突和混淆; 6.2.4. 方法命名第一個(gè)單詞一般是動(dòng)詞 如果方法返回一個(gè)成員變量的值,方法名一般為Get+成員變量名,如若返回的值 是bool變量,一般以Is作為前綴。另外,如果必要,考慮用屬性來(lái)替代方法,具 體建議見(jiàn)10.1.2節(jié); 如果方法修改一個(gè)成員變量的值,方法名一般為:Set + 成員變量名。同上,考慮 用屬性來(lái)替代方法; 6.2.5. 變量命名按照使用范圍來(lái)分,我們代碼中的變量的基本上有以下幾種類型,類的公有變量;類的私有變量(受保護(hù)同公有);方法的參數(shù)變量;方法內(nèi)部使用的局部變量。這些變量的命名規(guī)則基本相同,見(jiàn)標(biāo)識(shí)符大小寫對(duì)照表。區(qū)別如下: i. 類的公有變量按通常的方式命名,無(wú)特殊要求; ii. 類的私有變量采用兩種方式均可:采用加“m”前綴,例如mWorkerName; iii. 方法的參數(shù)變量采用camalString,例如workerName; iv. 方法內(nèi)部的局部變量采用camalString,例如workerName; ′ 不要用_或&作為第一個(gè)字母; 盡量要使用短而且具有意義的單詞; 單字符的變量名一般只用于生命期非常短暫的變量。i,j,k,m,n一般用于integer;c,d,e 一般用于characters;s用于string 如果變量是集合,則變量名要用復(fù)數(shù)。例如表格的行數(shù),命名應(yīng)為:RowsCount; 命名組件要采用匈牙利命名法,所有前綴均應(yīng)遵循同一個(gè)組件名稱縮寫列表 6.3. 組件名稱縮寫列表縮寫的基本原則是取組件類名各單詞的第一個(gè)字母,如果只有一個(gè)單詞,則去掉其中的元音,留下輔音??s寫全部為小寫。
7. 聲明每行要只有一個(gè)聲明,如果是聲明i,j,k之類的簡(jiǎn)單變量可以放在一行; 除了for循環(huán)外,聲明要放在塊的最開(kāi)始部分。for循環(huán)中的變量聲明可以放在for語(yǔ)句中。如:for(int i = 0; I < 10; i++) 。 ′ 避免塊內(nèi)部的變量與它外部的變量名相同。 8. 表達(dá)式和語(yǔ)句每行建議只有一條語(yǔ)句。 if-else,if-elseif語(yǔ)句,任何情況下,都應(yīng)該有“{”,“}”,格式如下: if (condition) { statements; } else if (condition) { statements; } else { statements; } for語(yǔ)句格式如下: for (initialization; condition; update) { statements; } 如果語(yǔ)句為空: for (initialization; condition; update) ; while語(yǔ)句格式如下: while (condition) { statements; } 如果語(yǔ)句為空: while (condition); do-while語(yǔ)句格式如下: do { statements; } while (condition); switch語(yǔ)句,每個(gè)switch里都應(yīng)包含default子語(yǔ)句,格式如下: switch (condition) { case ABC: statements; /* falls through */ case DEF: statements; break; case XYZ: statements; break; default: statements; break; } try-catch語(yǔ)句格式如下: try { statements; } catch (ExceptionClass e) { statements; } finally { statements; } 9. 類型設(shè)計(jì)規(guī)范要確保每個(gè)類型由一組定義明確,相互關(guān)聯(lián)的成員組成,而不僅僅是一些無(wú)關(guān)功能的隨 機(jī)集合; 9.1. 類型和命名空間要用命名空間把類型組織成相關(guān)域的層次結(jié)構(gòu)。例如: 界面層:Techstar.ProductionCenter; 業(yè)務(wù)邏輯層:Techstar.ProductionCenter.Business; 數(shù)據(jù)訪問(wèn)層:Techstar.ProductionCenter.Data; ′ 避免過(guò)深的命名空間; ′ 避免太多的命名空間; 9.2. 類型和接口的選擇要優(yōu)先采用類而不是接口。 接口的缺點(diǎn)在于語(yǔ)義變化時(shí)改變困難。注意接口并不是協(xié)定,把協(xié)定和實(shí)現(xiàn)分開(kāi)并非一 定用接口實(shí)現(xiàn),用基類和抽象類同樣可以表達(dá); 建議使用抽象類而不是接口來(lái)解除協(xié)定與實(shí)現(xiàn)間的偶合; 要定義接口,來(lái)實(shí)現(xiàn)類似多重繼承的效果; 精心定義接口的標(biāo)志是一個(gè)接口只做一件事情。關(guān)鍵是接口的協(xié)定需要保持不變, 如果一個(gè)接口包含太多功能,那么這個(gè)胖接口產(chǎn)生變化的機(jī)會(huì)就會(huì)大得多。 9.3. 抽象類設(shè)計(jì):′ 不要在抽象類中定義公有的或內(nèi)部受保護(hù)的構(gòu)造函數(shù)。因?yàn)槌橄箢悷o(wú)法實(shí)例化,所以這 種設(shè)計(jì)會(huì)誤導(dǎo)用戶; 要為抽象類定義受保護(hù)的構(gòu)造函數(shù)或內(nèi)部構(gòu)造函數(shù); 9.4. 靜態(tài)類設(shè)計(jì)靜態(tài)類是一個(gè)只包含靜態(tài)成員的類,它提供了一種純面向?qū)ο笤O(shè)計(jì)和簡(jiǎn)單性之間的一個(gè)權(quán)衡,廣泛用來(lái)提供類似于全局變量或一些通用功能。 要少用靜態(tài)類。靜態(tài)類應(yīng)該僅用作輔助類; ′ 避免把靜態(tài)類當(dāng)作雜物箱。每個(gè)靜態(tài)類都應(yīng)該有其明確目的; 不要在靜態(tài)類中聲明或覆蓋實(shí)例成員; 9.5. 枚舉設(shè)計(jì)要用枚舉來(lái)加強(qiáng)那些表示值的集合的參數(shù),屬性以及返回值的類型性; 要優(yōu)先使用枚舉而不是靜態(tài)常量。例如: //不好的寫法 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 } ′ 不要把枚舉用于開(kāi)放的場(chǎng)合,例如操作系統(tǒng)的版本,朋友的名字等; ′ 枚舉最后一個(gè)值不要加逗號(hào); ′ 枚舉中不要提供為了今后使用而保留的枚舉值; 10. 成員設(shè)計(jì)規(guī)范方法,屬性,事件,構(gòu)造函數(shù)以及字段等統(tǒng)稱為成員。 10.1. 成員設(shè)計(jì)的一般規(guī)范10.2. 方法的重載規(guī)范;′ 避免在重載中隨意的給參數(shù)命名。如果兩個(gè)重載中的某個(gè)參數(shù)表示相同的輸入,那么該參數(shù)的名字應(yīng)該相同。例如: 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) { ...} } ′ 避免使重載成員的參數(shù)順序不一致。在所有的重載中,同名參數(shù)應(yīng)該出現(xiàn)在相同的位置。 例如: public class EventLog { public EventLog(); public EventLog(string logName); public EventLog(string logName, string machineName); public EventLog(string logName, string machineName, string source); } 較短的重載應(yīng)該僅僅調(diào)用較長(zhǎng)的來(lái)實(shí)現(xiàn)。另外,重載如果需要擴(kuò)展性,把最長(zhǎng)重載 做成虛函數(shù)。例如: public class String { public int IndexOf(string s) { //調(diào)用 return IndexOf(s, 0); } public int IndexOf(string s, int startIndex) { //調(diào)用 return IndexOf(s, startIndex, s.Length); } public virtual int IndexOf(string s, int startIndex, int Count) { //實(shí)際的代碼 } } 要允許可選參選為null。這樣做是為了避免調(diào)用者調(diào)用之前需要檢查參數(shù)是否null。例 如: //允許為null時(shí)的調(diào)用 DrawGeometry(brush, pen, geometry); //不允許為null時(shí)的調(diào)用 if (geometry == null) DrawGeometry(brush, pen); else DrawGeometry(brush, pen, geometry); 10.3. 屬性和方法的選擇基本原則是方法表示操作,屬性表示數(shù)據(jù)。如果其他各方面都一樣,優(yōu)先使用屬性而不 是方法。 要使用屬性,如果該成員表示類型的邏輯attribue 如果屬性的值存儲(chǔ)在內(nèi)存中,而提供屬性的目的僅僅是為了訪問(wèn)該值,要使用屬性而不 要使用方法 如果該操作每次返回的結(jié)果不同,那么要使用方法。例如來(lái)自于.net framework的例子: //好的寫法 Guid.NewGuid(); //不好的寫法 DateTime.Now; 如果該操作比訪問(wèn)字段慢一個(gè)或多個(gè)數(shù)量級(jí),要使用方法。 如果該操作有嚴(yán)重的副作用,要使用方法。 10.4. 屬性的設(shè)計(jì)規(guī)范:如果不應(yīng)該讓調(diào)用方法改變屬性值,要創(chuàng)建只讀屬性; ′ 不要提供只寫屬性; 要為所有的屬性提供合理的默認(rèn)值,這樣可以確保默認(rèn)值不會(huì)導(dǎo)致漏洞或效率低的代 碼; 要允許用戶以任何順序來(lái)設(shè)置屬性的值; 避免在屬性的獲取方法拋出異常。 屬性的獲取方法應(yīng)該是個(gè)簡(jiǎn)單的操作,不應(yīng)該有任何的條件。如果一個(gè)獲取方法會(huì)拋出 異常,按么可能它更應(yīng)該設(shè)計(jì)為方法。 10.5. 構(gòu)造函數(shù)的設(shè)計(jì)規(guī)范建議提供簡(jiǎn)單的構(gòu)造函數(shù),最好是默認(rèn)構(gòu)造函數(shù)。簡(jiǎn)單的構(gòu)造函數(shù)增強(qiáng)易用性; 考慮擴(kuò)展性,如果構(gòu)造函數(shù)設(shè)計(jì)的不自然,建議用靜態(tài)的工廠方法來(lái)替代構(gòu)造函數(shù); 要把構(gòu)造函數(shù)的參數(shù)用作設(shè)置主要屬性的便捷方法。如果構(gòu)造函數(shù)參數(shù)僅用來(lái)設(shè)置屬 性,應(yīng)和屬性名稱相同。僅有大小寫的區(qū)別; 要在構(gòu)造函數(shù)中做最少的工作。任何其他處理應(yīng)該推遲到需要的時(shí)候; 要在類中顯示的聲明公用的默認(rèn)構(gòu)造函數(shù),如果這樣的構(gòu)造函數(shù)是必須的。 如果沒(méi)有顯示默認(rèn)構(gòu)造函數(shù),填加有參數(shù)構(gòu)造函數(shù)時(shí)往往會(huì)破壞已有使用默認(rèn)構(gòu)造函數(shù) 的代碼; ′ 避免在對(duì)象的構(gòu)造函數(shù)內(nèi)部調(diào)用虛成員。這樣在擴(kuò)展設(shè)計(jì)的時(shí)候會(huì)導(dǎo)致難以理解的現(xiàn) 象; 10.6. 字段設(shè)計(jì)規(guī)范′ 不要提供公有的或受保護(hù)的字段。代之以屬性來(lái)訪問(wèn)字段; 要只用常量字段來(lái)表示永遠(yuǎn)不會(huì)改變的量。否則會(huì)導(dǎo)致兼容性問(wèn)題。下面是正確的例子: public struct Int32 { public const int MaxValue = 0x7fffffff; public const int MinValue = unchecked((int)0x80000000); } 要用公有的靜態(tài)只讀字段來(lái)定義預(yù)定義的對(duì)象實(shí)例。例如: public struct Color { public static readonly Color Red = new Color(0x0000FF); } 10.7. 參數(shù)的設(shè)計(jì)規(guī)范要用類結(jié)構(gòu)層次中最接近基類類型來(lái)作為參數(shù)的類型,同時(shí)要保證該類型能夠提供成員 所需的功能。例如: 要設(shè)計(jì)一個(gè)集合遍歷的方法,那么參數(shù)應(yīng)該是IEnbumerable為參數(shù),而不應(yīng)該是IList, 這樣方法具有更強(qiáng)的適應(yīng)性。 ′ 不要使用保留參數(shù)。如果將來(lái)需要更多的參數(shù),那么可以增加重載成員。例如: //不好的寫法 public void Method(string reserved, SomeOption option); //好的寫法 public void Method(SomeOption option); //將來(lái)填加 public void Method(SomeOption option, string path); 10.7.1. 參數(shù)設(shè)計(jì)中枚舉和布爾參數(shù)的選擇規(guī)范要用枚舉。在代碼閱讀,書寫中,枚舉都比布爾的可讀性好很多。例如: //使用布爾型,閱讀的時(shí)候不會(huì)輕易了解參數(shù)的含義 FileStream f = File.Open(“1.txt”, true, false); //使用枚舉型 FileStream f = File.Open(“1.txt”,CasingOptions.CaseSenstive, FileMode.Open); ′ 不要使用布爾參數(shù),除非百分之百肯定絕對(duì)不需要兩個(gè)以上的值。即使此時(shí),采用枚舉 往往也可以提供更好的可讀性,如上例。 考慮在構(gòu)造函數(shù)中,對(duì)確實(shí)只有兩種狀態(tài)值的參數(shù)以及用來(lái)初始化布爾屬性的參數(shù)使用 布爾類型; 10.7.2. 參數(shù)驗(yàn)證的規(guī)范:要驗(yàn)證傳給公有的,受保護(hù)的或顯示成員的參數(shù)是否合法。如果驗(yàn)證失敗,應(yīng)該拋出 System.ArgutmentException或其子類; 要拋出System.ArgutmentNullException,如果傳入的null,而該成員不支持null; 10.7.3. 參數(shù)傳遞的規(guī)范:′ 避免使用輸出參數(shù)或引用參數(shù); 11. 擴(kuò)展性設(shè)計(jì)規(guī)范′ 如果沒(méi)有恰當(dāng)理由,不要把類密封起來(lái)。這些理由包括: A)類為靜態(tài)類; B)類的受保護(hù)成員保存了高度機(jī)密信息; C)類繼承了許多虛成員,逐個(gè)密封的代價(jià)太高,不如密封整個(gè)類; D)不要在密封類中聲明保護(hù)成員或虛成員,因?yàn)闊o(wú)法覆蓋其實(shí)現(xiàn); 建議用保護(hù)成員用于高級(jí)定制。它提供了擴(kuò)展性,同時(shí)也避免了公用接口過(guò)于復(fù)雜; ′ 不要使用虛成員,除非有合適的理由; 建議只有在絕對(duì)必須的時(shí)候才用虛成員提供擴(kuò)展性,并使用Template Method模式; 要優(yōu)先使用受保護(hù)的虛成員,而不是公有虛成員。公有成員通用調(diào)用受保護(hù)的虛成員的方式來(lái)提供擴(kuò)展性; 12. 異常處理規(guī)范異常的思想是只對(duì)錯(cuò)誤采用異常處理:邏輯和編程錯(cuò)誤,設(shè)置錯(cuò)誤,被破壞的數(shù)據(jù),資源耗盡,等等。通常的法則是系統(tǒng)在正常狀態(tài)下以及無(wú)重載和硬件失效狀態(tài)下,不應(yīng)產(chǎn)生任何異常。異常處理時(shí)可以采用適當(dāng)?shù)娜罩緳C(jī)制來(lái)報(bào)告異常,包括異常發(fā)生的時(shí)刻; ′ 一般情況下不要使用異常實(shí)現(xiàn)來(lái)控制程序流程結(jié)構(gòu); ′ 使用異常而不要用錯(cuò)誤代碼來(lái)報(bào)告錯(cuò)誤; 要通過(guò)拋出異常的方式來(lái)報(bào)告操作失敗。如果成員無(wú)法成功地完成它應(yīng)該做的任務(wù),那么應(yīng)該拋出異常; 12.1. 異常類型選擇規(guī)范優(yōu)先考慮使用System命名空間中已有的異常,而不是自己創(chuàng)建新的異常類型; 要使用最合理,最具針對(duì)性的異常。例如,對(duì)參數(shù)為空,應(yīng)拋出 System.ArgutmentNullException,而不是System.ArgutmentException 12.2. 異常處理規(guī)范′ 不是百分之百確定的情況,不要吞掉異常; 建議捕獲特定類型的異常,如果理解該異常在具體環(huán)境當(dāng)中產(chǎn)生的原因; ′ 不要捕獲不應(yīng)該捕獲的異常,通常應(yīng)該允許異常沿著調(diào)用棧傳遞; 進(jìn)行清理工作時(shí)要用try-finally,避免使用try-catch; 要在捕獲并重新拋出異常時(shí)使用空的throw語(yǔ)句,這是保持調(diào)用棧的最好方法 12.3. 標(biāo)準(zhǔn)異常類的使用:12.3.1. Exception與SystemException′ 不要拋出這兩種類型的異常; ′ 避免捕獲這兩種異常,除非是在頂層的異常處理器中; 12.3.2. InvalidOperationException對(duì)象處于不正確狀態(tài)時(shí)拋出; 12.3.3. ArgumentException,ArgumentNullException,ArgumentOutOfRangeException如果傳入的是無(wú)效參數(shù),要拋出參數(shù)異常,盡可能使用位于繼承層次末尾的類型; 要在拋出異常時(shí)設(shè)置ParaName屬性; 12.3.4. NullRefernceException,IndexOutOfRangeException,AccessViolationException′ 不要顯示拋出或捕獲; 12.3.5. StackOverflowException:′ 不要顯示拋出或捕獲; 12.3.6. OutOfMemoryException:′ 不要顯示拋出或捕獲; 12.4. 自定義異常類型設(shè)計(jì)規(guī)則:′ 避免太深的繼承層次; 要從已有的異?;惱^承; 異常類要以“Exception”做為后綴; 要使異??尚蛄谢蛊淠芸鐟?yīng)用程序域和遠(yuǎn)程邊界仍能正常使用; 要把與安全性有關(guān)的信息保存在私有的異常狀態(tài)中 12.5. 異常與性能如果在普通場(chǎng)景都會(huì)拋出異常,要采用先效驗(yàn)合法性的方式來(lái)避免拋出異常引起的性能 問(wèn)題; 13. 其他規(guī)定為避免頻繁改動(dòng)代碼,代碼中只寫比較簡(jiǎn)單的和不會(huì)經(jīng)常發(fā)生變化的SQL,如果SQL 經(jīng)常發(fā)生變化或是比較復(fù)雜,存到SysMisc中,比如統(tǒng)計(jì)用到的SQL; 在VS2005開(kāi)發(fā)環(huán)境中,采用代碼分析工具來(lái)做自動(dòng)化的代碼分析,以保證代碼質(zhì)量, 具體的使用建議如下: A)啟用代碼分析,并設(shè)置當(dāng)風(fēng)格不符合要求時(shí)為錯(cuò)誤而不是警告; B)如果不是做代碼審核,此開(kāi)關(guān)應(yīng)關(guān)閉。加上了這個(gè)選項(xiàng)的時(shí)候編譯很慢; C)詳設(shè)的時(shí)候打開(kāi)開(kāi)關(guān),檢查詳設(shè)是否符合編程規(guī)范; D)所有的選項(xiàng)都應(yīng)當(dāng)打開(kāi)。以下內(nèi)容需要單獨(dú)設(shè)置:
14. 參考文檔1,《.NET設(shè)計(jì)規(guī)范》,本規(guī)范很多內(nèi)容都參考了這本書,書中對(duì)規(guī)范背后的背景和原則做了深入討論; <逆水行舟,不進(jìn)則退> |
|