養(yǎng)成良好的編碼風(fēng)格是極其必要的,誰也不愿意看到一堆雜亂無章的代碼,將來你或者別人在維護(hù)的時(shí)候是多么的痛苦,所以,從現(xiàn)在開始,養(yǎng)成良好的編碼習(xí)慣,包括變量命名,注釋,代碼縮進(jìn) ....
1?.利用Pascal的方式定義類型、方法名和常量??
public?class?SomeClass?
?{
? const?int?DefaultSize=100;?
? public?SomeMethod()
? {
? }
}
?
2. 對(duì)于局部變量和方法的參數(shù)使用駱駝命名法
int?number; ?
void?MyMethod(int?someNumber) ?
{}
?
3. 接口的名稱前加上 I
interface?ImyInterface ??
{…}
?
4. 在私有成員變量前面加上 m_ 。對(duì)于 m_ 后面的變量名使用駱駝命名方法
public?class?SomeClass ??
{ ?
private?int?m_Number; ??
}
?
5.對(duì)自定義的屬性類加上后綴Attribute
?
6.對(duì)自定義的異常類加上后綴Exception
?
7.方法的命名使用動(dòng)詞----對(duì)象對(duì),例如ShowDialog()
?
8.有返回值的方法的命名中要有返回值的描述,例如GetObjectState()
?
9. 使用帶有說明性的變量名
a)?避免單字符的變量名,例如I或t等。使用類似于index或temp這樣有意義的名字。
b)?對(duì)于public或protected類型的變量避免使用匈牙利表示法。
c)? 不要縮寫單詞(例如用 num 取代 number )。
?
10 .總是使用 C# 預(yù)定義而不要使用 System 名稱空間中的別名,例如:
使用object而不是Object
使用string而不是String
使用int而不是int32
?
11. 在使用泛型的時(shí)候,類型的首字母要大寫。當(dāng)處理 .NET 中的 Type 類型的時(shí)候,保留 Type 后綴。 (C#2.0 新特性 )
//正確??
public?class?LinkedList<K,T> ??
{…} ??
?
//避免??
public?class?LinkedList<KeyType,DataType> ??
{….}
?
12. 使用有意義的名字定義名稱空間,例如產(chǎn)品名或者公司名
?
13. 避免通過全限定方式使用類型名稱,使用 using 關(guān)鍵字。
?
14. 避免在一個(gè)名稱空間中使用 using 關(guān)鍵字
?
15. 把所有系統(tǒng)框架提供的名稱空間組織到一起,把第三方提供的名稱空間放到系統(tǒng)名稱空間的下面
using?System; ??
using?System.Collection.Generic; ??
using?System.ComponentModel; ??
using?System.Data; ?
using?MyCompany; ?
using?MyControls;
?
16. 使用代理推導(dǎo)而不要顯式的實(shí)例化一個(gè)化代理( C#2.0 新特性)
delegate?void?SomeDelegate(); ??
public?void?SomeMethod() ??
{…} ??
SomeDelegate?someDelegate=SomeMethod;
?
17. 維護(hù)嚴(yán)格的代碼縮進(jìn)。不要使用 tabs 或非標(biāo)準(zhǔn)的縮進(jìn),例如一個(gè)空格。推薦的縮進(jìn)是 3 4 個(gè)空格。
?
18. 在和你的代碼縮進(jìn)處于同一個(gè)級(jí)別處為該行代碼添加注釋。
?
19. 所有的注釋都應(yīng)該通過拼寫檢查。注釋中的錯(cuò)誤拼寫意味著開發(fā)進(jìn)度的延緩。
?
20. 所有的類成員變量應(yīng)該被聲明在類的頂部,并用一個(gè)空行把它們和方法以及屬性的聲明區(qū)分開
public?class?MyClass ??
{ ??? ??
int?m_Number; ??
string?m_Name; ??
public?void?SomeMethod1(); ??
public?void?SomeMethod2(); ??
}
?
21. 在最靠近一個(gè)局部變量被使用的地方聲明該局部變量。
?
22. 一個(gè)文件名應(yīng)該能夠反映它所對(duì)應(yīng)的類名
?
23. 當(dāng)使用一個(gè)部分類并把該類分布到不同的文件中時(shí),在每一個(gè)文件名末尾都加上該文件實(shí)現(xiàn)的部分在類整體中扮演的作用。 例如:
//?In?MyClass.cs ??
public?partial?class?MyClass ??
{…} ??
//In?MyClass.Designer.cs ??
public?partial?class?MyClass ??
{…}
?
24. 總是要把花括號(hào)“ {” 放在新的一行
?
編碼實(shí)踐 :
1.? 避免在同一個(gè)文件中放置多個(gè)類
2.? 一個(gè)文件應(yīng)該只向在一個(gè)名稱空間內(nèi)定義類型。避免在一個(gè)文件中使用多個(gè)名稱空間
3.? 避免在一個(gè)文件內(nèi)寫多于 500 行的代碼(機(jī)器自動(dòng)生成的代碼除外)
4.? 避免寫超過 25 行代碼的方法
5.? 避免寫超過 5 個(gè)參數(shù)的方法。如果要傳遞多個(gè)參數(shù),使用結(jié)構(gòu)。
6.? 一行不要超過 80 個(gè)字符
7.? 不要手動(dòng)去修改任何機(jī)器生成的代碼
a)? 如果修改了機(jī)器生成的代碼,修改你的編碼方式來適應(yīng)這個(gè)編碼標(biāo)準(zhǔn)
b)? 盡可能使用 partial?classes 特性,以提高可維護(hù)性。 (C#2.0 新特性 )
8.? 避免對(duì)那些很直觀的內(nèi)容作注釋。代碼本身應(yīng)該能夠解釋其本身的含義。由可讀的變量名和方法名構(gòu)成的優(yōu)質(zhì)代碼應(yīng)該不需要注釋。
9.? 注釋應(yīng)該只說明操作的一些前提假設(shè)、算法的內(nèi)部信息等內(nèi)容。
10.? 避免對(duì)方法進(jìn)行注釋
a)? 使用充足的外部文檔對(duì) API 進(jìn)行說明
b)? 只有對(duì)那些其他開發(fā)者的提示信息才有必要放到方法級(jí)的注釋中來
11.? 除了 0 1 ,絕對(duì)不要對(duì)數(shù)值進(jìn)行硬編碼,通過聲明一個(gè)常量來代替該數(shù)值
12.? 只對(duì)那些亙古不變的數(shù)值使用 const 關(guān)鍵字,例如一周的天數(shù)。
13.?避免對(duì)只讀(read-only)的變量使用const關(guān)鍵字。在這種情況下,直接使用readonly關(guān)鍵字
public?class?MyClass ??
{ ??
public?const?int?DaysInWeek=7; ??
pubic?readonly?int?Number; ??
public?MyClass(int?someValue) ??
{ ??
Number=someValue; ??
} ??
}
14.?對(duì)每一個(gè)假設(shè)進(jìn)行斷言。平均起來,每5行應(yīng)有一個(gè)斷言。
using?System.Diagnostics; ??
object?GetObject() ??
{…} ??
object?someObject=GetObject(); ??
Debug.assert(someObject!=null);
15.? 每一行代碼都應(yīng)該以白盒測(cè)試的方式進(jìn)行審讀。
16.? 只捕捉那些你自己能夠顯式處理的異常。
17.? 如果在 catch 語句塊中需要拋出異常,則只拋出該 catch 所捕捉到的異常(或基于該異常而創(chuàng)建的其他異常),這樣可以維護(hù)原始錯(cuò)誤所在的堆棧位置。
catch(Exception?exception) ??
{ ??
MessageBox.Show(exception.Message); ??
throw;//或throw?exception; ??
}
18.? 避免利用返回值作為函數(shù)的錯(cuò)誤代碼。
19.? 避免自定義異常類。
20.? 當(dāng)自定義異常類的時(shí)候:
a)?讓你自定義的異常類從Exception類繼承
b)? 提供自定義的串行化機(jī)制
21.?避免在一個(gè)程序集中(assembly)中定義多個(gè)Main()方法。
22.?只把那些絕對(duì)需要的方法定義成public,而其它的方法定義成internal。
23.?避免friend?assemblies,因?yàn)檫@會(huì)增加程序集之間的耦合性。
24.? 避免讓你的代碼依賴于運(yùn)行在某個(gè)特定地方的程序集。
25.?在application?assembly(EXE?client?assemblies)中最小化代碼量。使用類庫來包含業(yè)務(wù)邏輯。
26.? 避免顯式指定枚舉的值
//正確??
public?enum?Color ??
{ ??
Red,Green,Blue ??
}
?
//避免 ??
public?enum?Color ??
{ ??
Red=1,Green=2,Blue=3 ??
}
27.? 避免為枚舉指定一個(gè)類型
//避免??
public?enum?Color:long ??
{ ??
Red,Green,Blue ??
}
28.? 對(duì)于 if 語句,總使用一對(duì) {} 把下面的語句塊包含起來,哪怕只有一條語句也是如此。
29.? 避免使用三元條件操作符。
30.? 避免利用函數(shù)返回的 Boolean 值作為條件語句。把返回值賦給一個(gè)局部變量,然后再檢測(cè)。
Bool?IsEverythingOK() ??
{…} ??
?
//避免??
if(IsEverythingOk()) ??
{…} ??
?
//正確??
bool?ok=IsEverythingOK(); ??
if?(ok) ??
{…}
31.? 總是使用以零為基數(shù)的數(shù)組。
32.? 總是使用一個(gè) for 循環(huán)顯式的初始化一個(gè)引用成員的數(shù)組:
public?class?MyClass
{}
const?int?ArraySize=100; ??
MyClass[]?array=new?MyClass[ArraySize]; ??
For?(int?index=0;index<array.Length;index++) ??
{
array[index]=new?MyClass(); ??
}
33.?使用屬性來替代public或protected類型的成員變量。
34.?不要使用繼承下來的new操作符,使用override關(guān)鍵字覆寫new的實(shí)現(xiàn)。
35.?在一個(gè)非密封(non-sealed)類中,總是把那些public和protected的方法定義成virtual。
36.?除非為了和其它語言進(jìn)行互動(dòng),否則絕不要使用不安(unsafe)的代碼。
37.? 避免顯示類型轉(zhuǎn)換。使用 as 關(guān)鍵字安全的轉(zhuǎn)換到另一個(gè)類型。
Dog?dog=new?GermanShepherd(); ??
GermanShepherd?shepherd=dog?as?GermanShepherd; ?
if?(shepherd!=null) ??
{…}
38.? 在調(diào)用一個(gè)代理前,總是檢查它是否為 null
39.?不要提供public的事件成員變量。改用Event?Accessor。
Public?class?MyPublisher ??
{ ??
MyDelegate?m_SomeEvent; ??
Public?event?MyDelegate?SomeEvent ??
{ ??
add ??
{ ??
m_SomeEvent+=value; ??
} ??
remove ??
{ ??
m_SomeEvent-=value; ??
} ??
} ??
}
40.? 避免定義事件處理代理。 使用EventHandler<T>或者GenericEventHandler。
41.? 避免顯示觸發(fā)事件。使用 EventsHelper 安全的發(fā)布事件。
42.? 總是使用接口。
43.? 接口和類中方法和屬性的比應(yīng)該在 2:1 左右。
44.? 避免只有一個(gè)成員的接口。
45.? 努力保證一個(gè)接口有 3~5 個(gè)成員。
46.? 不要讓一個(gè)接口中成員的數(shù)量超過 20 ,而 12 則是更為實(shí)際的限制。
47.?避免在接口中包含事件。
48.? 當(dāng)使用抽象類的時(shí)候,提供一個(gè)接口。
49.? 在類繼承結(jié)構(gòu)中暴露接口。
50.? 推薦使用顯式接口實(shí)現(xiàn)。
51.? 從來不要假設(shè)一個(gè)類型支持某個(gè)接口。在使用前總是要詢問一下。
SomeType?obj1; ??
ImyInterface?obj2; ??? ??
/*Some?code?to?initialize?obj1,then:*/ ??
obj2=obj1?as?ImyInterface; ??
if(obj2!=null) ??
{ ??
obj2.Method1(); ?
} ?
else ?
{ ?
//Handle?erro?in?expected?interface ??
}
52.? 不要硬編碼向用戶顯示的字符串。要使用資源。
53.? 不要硬編碼那些可能會(huì)隨發(fā)布環(huán)境變化而變化的字符串,例如數(shù)據(jù)庫連接字符串。
54.?使用String.Empty取代””
//避免??
string?name=””; ??
//正確??
string?name=String.Empty;
55.?使用一個(gè)長字符串的時(shí)候,使用StringBuilder代替string。
56.?避免在結(jié)構(gòu)中提供方法
a)?參數(shù)化的構(gòu)造函數(shù)是鼓勵(lì)使用的
b)? 可以重載運(yùn)行符
57.? 當(dāng)聲明了表態(tài)成員的時(shí)候,總是要提供一個(gè)表態(tài)構(gòu)造函數(shù)。
58.?當(dāng)早綁定(early-binding)可能的時(shí)候就盡量不要使用遲綁定(late-binding)。
59.?讓你的應(yīng)用程序支持跟蹤和日志。
60.? 除了要在 switch 語句塊中實(shí)現(xiàn)代碼跳轉(zhuǎn),不要使用 goto 關(guān)鍵字。
61.?總在switch語句的default情形提供一個(gè)斷言。
int?number=SomeMethod(); ??
swith(number) ??
{ ??
case?1:
???trace.WriteLine(“Case?1:”) ??
break; ??
case?2: ??
trace.Writeline(“Case?2:”);
break;??
default: ??
debug.Assert(false); ??
break; ??
}
62.? 除了在一個(gè)構(gòu)造函數(shù)中調(diào)用其它的構(gòu)造函數(shù)之外,不要使用 this 關(guān)鍵字。
//Example?of?proper?use?of?‘this’ ??
public?class?MyClass ??
{ ??
public?MyClass(string?message) ??
{ ??} ??
public?MyClass():this(“Hello”) ??
{ ??}
}
63.? 不要使用 base 關(guān)鍵字訪問基類的成員,除非你在調(diào)用一個(gè)基類構(gòu)造函數(shù)的時(shí)候要決議一個(gè)子類的名稱沖突
//Example?of?proper?use?of?‘base’ ??
public?class?Dog ??
{ ??
public?Dog(string?name) ??
{ ?} ??
virtual?public?void?Bark(int?howlong) ??
{ ??} ??
}?
public?class?GermanShepherd:Dog ??
{ ??
?public?GermanShepherd(string?name):base(name) ??
{ ??} ??
override?public?void?Bark(int?howLong) ??
{ ??
base.Bark(howLong) ??
} ??
}
64.?不要使用GC.AddMemoryPressure()
65.?不要依賴HandleCollector
66.?基于《Programming?.NET?components》2/e中第四章的內(nèi)容實(shí)現(xiàn)Disponse()和Finalize()方法。
67.?總是在unchecked狀態(tài)下運(yùn)行代碼(出于性能的原因),但是為了防止溢出或下溢操作,要果斷地使用checked模式。
Int?CalcPower(int?number,int?power) ??
{ ??
int?result=1; ??
for?(int?count=1;count<=power;count++) ??
{ ??
checked ??
{ ??
result*=number; ??
} ??
} ??
return?result; ??
}
68.?使用條件方法來取代顯式進(jìn)行方法調(diào)用排除的代碼(#if…#endif)
public?class?MyClass
{ ??
[Conditional(“MySpecialCondition”)] ??
public?void?MyMethod() ??
{} ??
}
69.? 不要在泛型接口中定義約束。接口級(jí)的約束通常可以利用強(qiáng)類型來替代。
Public?class?Customer ??
{} ??
//避免: ??
public?interface?Ilist<T>?where?T:Customer ??
{} ??
?
//正確: ??
public?interface?IcustomerList:Ilist<Customer>
70.? 不要在接口上定義方法相關(guān)的約束。
71.? 不要在代理上定義約束。
72.? 如果一個(gè)類或方法提供了泛型和非泛型版本,那么優(yōu)先選擇泛型版本