2011年8月10日 星期三

The Elements of C# Style

C#編程風格(英漢對照)/微軟技術系列/圖靈程序設計叢書


Bear在這裡買的
amazon的參考
-----------------------------------------------------------
作者:(美)鮑德溫//格雷//米斯費爾特|譯者:韓磊
出版社:人民郵電
ISBN:9787115184382
出版日期:2008/10/01
頁數:214
人民幣:RMB 29 元
-----------------------------------------------------------

第1章 一般原則

01.保持原有風格
02.堅持最小驚奇原則
03.第一次就做對
04.記錄所有非規範行為
05.考慮採用代碼檢查工具強制遵循編碼標準

第2章 格式

2.1 空白

06.使用空白
07.使用編進的語句塊
08.編進標記後的語句
09.不用硬製表符(Do Not Use "Hard" Tab)
10.切分長語句為多行語句

2.2 花括弧
11.按同一風格放置花括號

P.23
12.在流程控制結構中始終使用語句塊。
Bear:即所有的if..else, for, while, do..while等都一定要用{}包起來,就算只有一行也一樣。

2.3 類的組織

P.25
13.在源文件開始分組放置using指示符
如果源文件中使用了using指示符,在文件開始分組放置這些指示符。先依字母順序列出系統定義的命名空間,後面加一個空行,然後依字母順序列出第三方命名空間,後面加一個空行,最後再依字母順序列出用戶定義的命名空間。

using System;
using System.IO;
using System.Xml;

using CenterSpace.NMath.Core;
using CenterSpace.NMath.Stats;

using MyOrganization.BusinessUtilities;

14.將源代碼組織到不同區域中
使用#region...#endregion結構將源文件組織為有意義的區域。許多開發環境(例如Microsoft Visual Studio)中,用戶能折疊代碼區域,可以更方便地查看較大的源文件。

為開發團隊制訂代碼區域的固定列表和順序,例如,可以採用類似以下的列表(摘自MSDN文檔):
公共構造函數
公共屬性
公共方法
事件處理函數
私有字段
私有方法

P.27
15.依可訪問性排列類元素
在源文件中,依據可訪問性修飾符排列聲明:
public
protected
internal
private

16.單獨聲明每個變量和特性
一行中只聲明一個變量。

第3章 命名

3.1 一般原則

17.使用有意義的名稱
18.根據含意而非類型來命名
19.使用熟悉的名稱
20.不要用大小寫來區分名稱
21.避免使用過長的名稱

P.33
22.加上元音-使用完整的單詞

如果只為了縮短名稱而去除元音,那麼需要考慮一下原來的名稱是否合適。

3.2 縮略形式

23.除非全稱太長,否則不用縮略形式
24.像普通詞一樣書寫縮略詞

3.3 預處理器符號

25.用大寫字母和底線表示預處理器符號
26.給預處理器名稱添加唯一前綴

3.4 類型和常量

27.使用Pascal寫法給命名空間、類、結構、枚舉、常量及函數命名
28.使用名詞命名複合類型
29.用複數形式書寫集合名稱
30.給抽象基類加上"Base"後綴
31.給實現一種設計模示的類添加模式名稱
32.使用單個大寫字母命名泛型參數

3.5 枚舉

33.用單數形式為枚舉命名
34.用複數形式給位域命名

3.6 介面

35.用大寫字母"I"作為接口名稱的前綴
36.使用名詞或形容詞給接命名

3.7 屬性

37.依取值或賦值項給屬性命名
38.避免冗長的屬性名稱
39.用能體現布林特性的名稱給布林屬性命名

P.41.
如果某個屬產返回一個布林值,給其名稱加上"is"、"has"、"are"前綴。

3.8 方法

40.使用Pascal寫法為方法命名
41.用動詞命名方法
42.避免冗長的方法名

3.9 變數和參數

43.使用Camel寫法給變量和方法參數命名
44.用名詞命名變量
45.給成員變量名稱加上前綴或後綴,使之與其他變量區分開

Bear: 且一定要用this._xxxx方式調用(by 小朱)

46.依所賦值的字段名稱給構造函數和屬性參數命名
47.用一系列標準名稱為"一次性"變量和參數命名

3.10 特性

48.給自定義特性實現加上"Attribute"後綴

3.11 命名空間

49.用機構名稱給根命名空間命名,加上項目、產品或小組名來縮小範圍

3.12 事件處理

50.使用適當的名稱清晰區分事件處理部份

3.13 異常

51.給自定義異常類型添加"Exception"後綴

第4章 文檔

4.1 一般原則

52.為使用接口的人編寫軟件接口文檔
53.為維護者編寫代碼實現文檔
54.保持注釋和代碼同步
55.盡早編寫軟件元素的文檔
56.考慮全世界的讀者
57.在每個文件的開始添加版權、授權許可和作者信息

4.2 API

58.盡量使用C#語言內建的文檔機制
59.編寫重要前置條件、後置條件和不變條件的文檔
60.編寫線程同步需求
61.編寫已知缺陷和不足
62.使用主動語態描述操作者,使用被動語態描述動作
63.當指稱當前類的實例時,使用"this",而不用"the"

4.3 內部代碼

64.只在需要幫助別人理解代碼的時候才添加內部注釋
65.解釋代碼為什麼要這麼做
66.避免使用C風格的注釋塊
67.使用單行注釋描述實現細節
68.避免使用行末來注釋
69.在多重嵌套控結構中標出結束花括號
70.使用關鍵詞標出待完成工作、未解決問題、錯誤和缺陷修正。
71.標出空語句

P.67
當在while 或 for 循環之類控制結構中設計了空語句時,添加一行注釋,指出這是作者本意。
// 消除開頭空格
while((c=reader.read()) == ' ');

第5章 設計
5.1 工程

72.別怕做工程
73.簡潔優於優雅
74.了解重用的代價
75.按約編程
76.選用適宜的工程方法
77.分隔不同的編程層

5.2 類的設計

78.讓類保持簡單
79.定義派生類,使其可以用在任何可以使用其祖先類的地方
80.對於"is-a"關係使用繼承,對於"has-a"關係使用包含
81.對於"is-a"關係使用抽象基類,對於"實現"關係使用接口

5.3 線程安全和併發

82.設計可重入的方案
83.只在合適的地方使用線程
84.避免不必要的同步

5.4 效率

85.使用懶惰求值和懶惰初始化
86.重用對象以避免再次分配
87.最後再優化

P.95~P.96
優化的第一原則: 不要優化。
優化的第二原則(只對專家有效): 還是不要優化。
在確認要做優化之前,不要花時間做優化。
採用80-20原則,系統中20%的代碼使用80%的資源(平均而言)。如果要做優化,確認從那20%的代碼開始。

88.避免創建不必要的對象
89.讓CLR處理垃圾回收

第6章 編程
6.1 類型

90.使用內建的C#數據型別名
91.避免使用內聯字面量
92.避免不必要的值類型裝箱
93.使用標準形式書寫浮點字面量
94.為"值"語義使用結構
95.考慮在結構中覆蓋等同方法和操作符
96.使用"@"前綴轉義整個字符串
97.避免代價昂貴的隱藏字符串分配
98.採用有效的空字符串檢測方法

P.105
類似下面的代碼需要創建一個新的空字符串:
if(str.Equals(""))
而檢測長度則不必創建字符串:
if(str.Length==0)
另外,.NET 2.0引入了靜態方法 String.IsNullOrEmpty() ,用一次高效測試就能檢測空引用和空字符串。

99.只在必要時使用可空值
100.僅為支持機器生成代碼使用部份類型

6.2 語句和表達式

101.在複雜表達式中不要依賴操作符優先級

使用括號定義和控制子表達式求值會讓代碼易於理解和維護。

// 試著得到60
int j = 10 * 2 << 1 + 20; // 不好,j==41943040
// 添加圓括號
int j = (10 * (2 << 1)) + 20; // 好,j==60

102.不用true 或 flase 測試相等

P.107-108
沒必要用true 或 flase 比較布林值

bool b = false;
if(b==false) {....}
直接使用布林值
bool b = false;
if(!b) {....}

103.用等價方法替換重覆出現的非普通表達式
104.在三元條件判斷中避免使用複雜語句
105.使用Object.Equals()測試引用類型的對象等同

6.3 控制流程

P.111
每個代碼塊都有唯一的入口和出口。

106.避免在循環語句中使用 break 和 continue 語句
107.在方法中避免使用多個return語句
108.不要使用goto
109.不要使用try...throw...catch來管理控制流程
110.在for語句內部聲明循環變量
111.給所有 switch 語句的結尾添加 default 標記

6.4 類

112.定義小類和小方法
113.從標準類型構造基礎類
114.避免在用戶可擴展的類層次結構中使用虛基類
115.聲明所有成員的訪問級別

P.117
不要假設別人會記得預設的訪問級別。只要有可能,就把同等訪問級別的聲明放到同一組裡面。許多程序員循以下順序放置聲明: public 然後是 protected, 跟著是 private。

116.將類標記為,防止不想要的派生

P.117
如果想禁門從"封閉"類派生新類,就使用sealed關鍵字。所有訪問修飾符都應為 public 或 private : 在這種情況下,protected沒有任何意義。

117.避免使用 internal 聲明

internal 聲明常標誌著不好的設計,因為它繞過了訪問限制,而且隱藏了類和函數之間的依賴關係。只應在需要防止子代護得特定超類方法同時允許特定輔助類、操作符和函數訪問這些方法的情況下使用 internal 聲明。

118.避免使用 new 來隱藏派生類型的成員
119.限制base關鍵字在子類構造函數和覆蓋方法中的使用
120.在覆蓋Equals()方法時也覆蓋Operator== 和 Operator!=
121.在覆蓋 ToString() 方法時,考慮覆蓋隱式文字符串轉換操作符
122.用相反功能的方法來實現方法

6.5 生命周期

123.初始化所有變量
124.總是構造在有效狀態的對象
125.為增加的透明性和COM互操作性聲明顯式預設構造函數
126.聲明構造函數為保護的,禁止直接實例化
127.總是在派生構造函數的初始化列表中列出全部基構造函數

P.125
派生類不應直接初始化父類成員-初始化父類成員是父類構造函數的職責。反之,應在初始化列表中包括合適的父類構造函數,即便它是預設構造函數也應如此。

128.使用嵌套的構造函數消除冗余代碼
129.在引用外部資源的類中實現IDisposable

6.6 欄位和屬性

130.聲明所有字段為私有訪問級別,使用屬性提供訪問
131.只為簡單、低成本、與順序無關的訪問使用屬性

6.7 方法

132.避免傳遞過多參數
133.檢驗數值有效性

6.8 特性

134.使用System.ObsoleteAttribute棄用API
135.考慮新類是否可被序列化
136.使用 System.FlagAttribute 指明位域

6.9 泛型

137.泛型類型勝過未指定類型或強類型類

6.10 枚舉

138.使用枚舉而非布林型來改善參數可讀性
139.使用枚舉值而非整數常數
140.創建0值枚舉元素表示未初始化、無效、未指定或預設的狀態
141.驗證枚舉值

P.141
不要假定enum值總會在定義範圍之內,而且將整數值轉為enum類型也是合法的,即使該整數沒有對應枚舉中的任何值。例如,
enum Color
{
None = 0,
Red = 1.
Green = 2,
Blue = 3
};
盡管下面的代碼不是我們期望的,但卻是合法的宣告。
Color c = (Color) 42;

6.11 類型安全、強制轉換與轉換

142.避免強制轉換,並且不要強迫別人使用強制轉換
143.as操作符勝過直接強制轉換
144.使用多態而不頻繁使用is 或 as

P.143
????

6.12 錯誤處理和調試

145.使用返回碼報告預期的狀態改變
146.使用異常強迫護得編程契約
147.不要靜默地接受或忽略非預期的運行時錯誤

P.145

148.使用斷言或異常報告非預期的或未處理的運行時錯誤
149.使用異常來報告可恢複錯誤
150.使用 try...finally 代碼塊或 using 語句管理資源
151.盡可能拋出最具體的異常
152.只捕護你能處理的異常
153.如果在代碼塊中拋出新異常,不要丟棄異常信息
154.依異常類型特殊性級別排列 catch 塊
155.不要在 finally 塊中拋出異常
156.僅在認為調用者會做特別處理時才創建自定義異常
157.從 ApplicationException 而不是 Exception 派生自定義異常
158.使用內建的調試類調試代碼

6.13 事件、委託和線程

159.使用 lock() 而不是 Monitor.Enter()
160.只鎖定私有對象

第7章 打包

7.1 文件

161.在單個文件中放置命名空間作用域內的每個元素
162.用元素名作為文件名

7.2 命名空間

163.不要污染框架命名空間
164.為每個命名空間創建單獨的目錄
165.將常被共同使用、修改和發布或互相依賴的類型放到同一個命名空間下
166.在分開的程序集中隔離不穩定的類
167.最大化抽象以最大化穩定性
168.將高級設計和架構捕獲為穩定抽象,組織到穩定命名空間中

7.3 程序集

169.讓程序集和命名空間的名字保持一致
170.避免讓難以修改的程序集依賴於易於修改的程序集
171.手工增加程序集版本號
172.只把單個類暴露給COM,不暴露給整個程序集
173.將有不安全代碼的類放到單獨程序集中
174.靜態鍵接本地代碼