編寫高質量代碼:改善C#程式的157個建議 ( 簡體 字) |
作者:陸敏技 | 類別:1. -> 程式設計 -> .NET -> C# |
譯者: |
出版社:機械工業出版社 | 3dWoo書號: 31188 詢問書籍請說出此書號!【缺書】 【不接受訂購】 |
出版日:9/1/2011 |
頁數:347 |
光碟數:0 |
|
站長推薦:  |
印刷:黑白印刷 | 語系: ( 簡體 版 ) |
|
【不接受訂購】 |
ISBN:9787111356493 |
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 序 |
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證) |
作者序: |
譯者序: |
前言:為什么寫這本書
事實上,我在寫本書之前就一直在思考一個問題:到底什么樣的編程書籍能夠幫助入門者快速進階?所謂“入門者”指的是已經可以使用一門語言編寫程序,但是不明白如何編寫高質量代碼的人。于是我開始回憶自己在開發生涯中的入門階段,那時候,我常常被以下三類問題所困擾。第一類來自于語言本身,如:
如何格式化字符串才是最高效的?
基本類型間或其他CLR類型間的轉換怎樣才算是最高效的?
for和foreach有什么區別,何時該用for,何時該用foreach?
什么是Dispose模式,為什么要釋放資源,如何釋放資源?
多線程應選擇何種方式來開啟和結束,各線程之間為什么要同步,如何同步,如何鎖定資源?
第二類來自于設計架構,如果你對編碼充滿熱情,相信你的大腦里很快就會充滿以下這些問題:
使用單例模式還是靜態類,為什么有了靜態類還需要單例模式?
該使用靜態方法還是實例方法,它們的本質區別是什么?
如何使用異常才是最正確的,什么時候拋出異常,什么時候“吃掉”異常,為什么需要自定義異常?
如何避免過多的條件判斷分支?
如何保證程序的數據安全和通信安全?
第三類問題最常見,可能來自于編碼習慣和編程思想,我在入門階段經常會問自己下面這些問題:
一個文件只包含一個類比較好,還是一個文件可以包含多個類?
如何命名才是專業級別的?
應該使用抽象類還是接口?
到底什么才是真正的面向對象編碼,我這樣編程夠面向對象嗎?
什么是單元測試,如何編寫單元測試?
如果你也曾經問過自己類似的問題,說明你已經為成為專業程序員做好了準備;如果你還苦于找不到問題的答案,那么本書正是為你準備的。本書為那些普遍存在于初級開發者腦海中的問題給出了經驗性的解決方案。我盡可能多地羅列問題并給出解決方法(同時給出錯誤的方法和正確的方法,以及好的方法和更好的方法,并進行分析和比較)和建議,并且盡量覆蓋.NET 4.0中C#的新特性。我已經用Visual Studio 2010編寫并調試和運行(在Release狀態下)了書中所有的代碼,我期望你也這樣做。相信當你調試完書中所有的示例時,你會對.NET和C#有更深入的認識,同時你也會對自己的代碼更加有自信:沒錯,這就是我想要的代碼,它規范,并且優雅而穩定。
如何閱讀本書
本書適合那些有一定C#基礎,并希望在技術上得到大幅提升的程序員。
本書并沒有講述C#中的基礎概念,而是將使用C#過程中可能遇到的疑問或障礙一一羅列,并給出了建議。書中的大多數建議實戰性很強,要完全理解其中的奧妙,首先應該動手寫一寫示例程序,或許在調試程序的過程中就會得到啟發。
本書的每一個章節都比較獨立,下一章的閱讀并不需要前面章節作為鋪墊。本書更像一本工具書,根據知識點對各個建議進行了分類,方便隨時查閱。
資源及勘誤
通常情況下,一個問題的解決方案往往不止一種,你可能會不同意本書中的一些觀點,甚至會強烈反對。 沒有關系,你可以通過luminji@hotmail.com(E-mail)與我分享你的寶貴意見,同時也可以在http://www.cnblogs.com/luminji下載書中的源碼。我也經常在那里發表博客。當然,你一定也會在書中找到一些錯誤,我已經在博客上放置了一篇勘誤表,我會在第一時間公布這些勘誤。
致謝
最后,我想說的是,寫作是一項耗時的工程,它不但壓縮了我的工作時間,也完全耗掉了我的午休時間。首先要感謝我的同事,因為我時常因為思考本書的內容而工作不在狀態,或者總在飯桌上討論書中的一些技術細節。他們不但沒有抱怨,反而提出了很多好的意見,他們是:胡昌俊、于文廣、肖昌、樊鑫、王文壯、來偉、粟志輝、趙中海、王領軍,還有其他很多朋友不再一一列出。他們是如此優秀和寬容,能和他們一起工作是我莫大的榮幸。
在漫長的寫作過程中,難免讓我情緒波動,是機械工業出版社華章公司的楊福川先生和楊繡國女士給我一如既往的支持與鼓勵。當我想要偷懶的時候,是你們的敦促讓我對寫作時刻保持著熱情。同時還要強調一下,沒有福川,本書不會出版。另外,沒有白宇女士的編輯工作,本書的文字看上去不會像現在這樣流暢。
還要感謝我的家人,尤其是我的父母和妻子胡忠華。在過去這段時間里,我總是一回到家就打開電腦。陪妻子散步的時間沒有了,聊天少了,家務活兒也很少做了。妻子的寬容讓我有了更多的時間去寫作。難得的是,中文系畢業的你在寫作方面給我提出了很多好的建議。你的第一標準是:“如果我都看不懂,你還寫什么書。”沒有你的支持,本書不會誕生。
陸敏技
2011年7月 |
內容簡介:本書是C#程序員進階修煉的必讀之作,所有建議都是C#編碼的最佳實踐,從語言本身、程序的設計和架構、編碼規范和編程習慣三大方面對C#程序員遇到的經典問題給出了經驗性的解決方案,為C#程序員提供了157條極為寶貴的建議。對于每一個問題,不僅以建議的方式給出了被實踐證明為十分優秀的解決方案,而且還給出了經常被誤用或被錯誤理解的反例,從正反兩個方面進行分析和對比。
全書一共三個部分,第一部分專注于C#語言本身,一共89條建議,涵蓋了C#語言基本要素、集合、LINQ、泛型、委托、事件、資源管理、序列化、異常處理、異步、多線程、任務和并行編程等與C#語法相關的核心內容;第二部分重點講解了C#程序的設計和架構,一共32條建議,涉及成員設計、面向對象的類型設計、安全性設計等重要方面的內容;第三部分探討了C#的編碼規范及編程習慣,一共36條建議,包含C#命名規范、如何使代碼更整潔以及如何規范開發行為等方面的內容。
本書是一本關于如何編寫高質量C#代碼的工具書,列舉的問題非常典型,給出的建議也非常實用,其中的每一條建議都有可能在我們編寫下一行代碼的時候用到。你可以將此書擱置在案頭,以便有需要的時候隨時查閱。 |
目錄:前 言
第一部分 語言篇
第1章 基本語言要素 / 2
建議1:正確操作字符串 / 2
建議2:使用默認轉型方法 / 6
建議3:區別對待強制轉型與as和is / 9
建議4:TryParse比Parse好 / 12
建議5:使用int?來確保值類型也可以為null / 15
建議6:區別readonly和const的使用方法 / 16
建議7:將0值作為枚舉的默認值 / 19
建議8:避免給枚舉類型的元素提供顯式的值 / 20
建議9:習慣重載運算符 / 22
建議10:創建對象時需要考慮是否實現比較器 / 23
建議11:區別對待==和Equals / 27
建議12:重寫Equals時也要重寫GetHashCode / 29
建議13:為類型輸出格式化字符串 / 32
建議14:正確實現淺拷貝和深拷貝 / 36
建議15:使用dynamic來簡化反射實現 / 40
第2章 集合和LINQ / 43
建議16:元素數量可變的情況下不應使用數組 / 43
建議17:多數情況下使用foreach進行循環遍歷 / 45
建議18:foreach不能代替for / 51
建議19:使用更有效的對象和集合初始化 / 53
建議20:使用泛型集合代替非泛型集合 / 54
建議21:選擇正確的集合 / 57
建議22:確保集合的線程安全 / 61
建議23:避免將List作為自定義集合類的基類 / 64
建議24:迭代器應該是只讀的 / 67
建議25:謹慎集合屬性的可寫操作 / 68
建議26:使用匿名類型存儲LINQ查詢結果 / 70
建議27:在查詢中使用Lambda表達式 / 73
建議28:理解延遲求值和主動求值之間的區別 / 75
建議29:區別LINQ查詢中的IEnumerable和IQueryable / 78
建議30:使用LINQ取代集合中的比較器和迭代器 / 80
建議31:在LINQ查詢中避免不必要的迭代 / 83
第3章 泛型、委托和事件 / 86
建議32:總是優先考慮泛型 / 86
建議33:避免在泛型類型中聲明靜態成員 / 88
建議34:為泛型參數設定約束 / 90
建議35:使用default為泛型類型變量指定初始值 / 92
建議36:使用FCL中的委托聲明 / 94
建議37:使用Lambda表達式代替方法和匿名方法 / 96
建議38:小心閉包中的陷阱 / 99
建議39:了解委托的實質 / 103
建議40:使用event關鍵字為委托施加保護 / 106
建議41:實現標準的事件模型 / 108
建議42:使用泛型參數兼容泛型接口的不可變性 / 109
建議43:讓接口中的泛型參數支持協變 / 111
建議44:理解委托中的協變 / 112
建議45:為泛型類型參數指定逆變 / 114
第4章 資源管理和序列化 / 116
建議46:顯式釋放資源需繼承接口IDisposable / 116
建議47:即使提供了顯式釋放方法,也應該在終結器中提供隱式清理 / 119
建議48:Dispose方法應允許被多次調用 / 120
建議49:在Dispose模式中應提取一個受保護的虛方法 / 121
建議50:在Dispose模式中應區別對待托管資源和非托管資源 / 123
建議51:具有可釋放字段的類型或擁有本機資源的類型應該是可釋放的 / 124
建議52:及時釋放資源 / 125
建議53:必要時應將不再使用的對象引用賦值為null / 127
建議54:為無用字段標注不可序列化 / 131
建議55:利用定制特性減少可序列化的字段 / 136
建議56:使用繼承ISerializable接口更靈活地控制序列化過程 / 137
建議57:實現ISerializable的子類型應負責父類的序列化 / 140
第5章 異常與自定義異常 / 144
建議58:用拋出異常代替返回錯誤代碼 / 144
建議59:不要在不恰當的場合下引發異常 / 147
建議60:重新引發異常時使用Inner Exception / 150
建議61:避免在finally內撰寫無效代碼 / 151
建議62:避免嵌套異常 / 157
建議63:避免“吃掉”異常 / 160
建議64:為循環增加Tester-Doer模式而不是將try-catch置于循環內 / 161
建議65:總是處理未捕獲的異常 / 162
建議66:正確捕獲多線程中的異常 / 166
建議67:慎用自定義異常 / 168
建議68:從System.Exception或其他常見的基本異常中派生異常 / 170
建議69:應使用finally避免資源泄漏 / 172
建議70:避免在調用棧較低的位置記錄異常 / 175
第6章 異步、多線程、任務和并行 / 177
建議71:區分異步和多線程應用場景 / 177
建議72:在線程同步中使用信號量 / 180
建議73:避免鎖定不恰當的同步對象 / 184
建議74:警惕線程的IsBackground / 188
建議75:警惕線程不會立即啟動 / 189
建議76:警惕線程的優先級 / 191
建議77:正確停止線程 / 193
建議78:應避免線程數量過多 / 194
建議79:使用ThreadPool或BackgroundWorker代替Thread / 196
建議80:用Task代替ThreadPool / 198
建議81:使用Parallel簡化同步狀態下Task的使用 / 202
建議82:Parallel簡化但不等同于Task默認行為 / 204
建議83:小心Parallel中的陷阱 / 205
建議84:使用PLINQ / 208
建議85:Task中的異常處理 / 209
建議86:Parallel中的異常處理 / 214
建議87:區分WPF和WinForm的線程模型 / 216
建議88:并行并不總是速度更快 / 220
建議89:在并行方法體中謹慎使用鎖 / 222
第二部分 架構篇
第7章 成員設計 / 226
建議90:不要為抽象類提供公開的構造方法 / 226
建議91:可見字段應該重構為屬性 / 226
建議92:謹慎將數組或集合作為屬性 / 227
建議93:構造方法應初始化主要屬性和字段 / 228
建議94:區別對待override和new / 229
建議95:避免在構造方法中調用虛成員 / 235
建議96:成員應優先考慮公開基類型或接口 / 236
建議97:優先考慮將基類型或接口作為參數傳遞 / 237
建議98:用params減少重復參數 / 237
建議99:重寫時不應使用子類參數 / 238
建議100:靜態方法和實例方法沒有區別 / 239
建議101:使用擴展方法,向現有類型“添加”方法 / 240
第8章 類型設計 / 243
建議102:區分接口和抽象類的應用場合 / 243
建議103:區分組合和繼承的應用場合 / 245
建議104:用多態代替條件語句 / 248
建議105:使用私有構造函數強化單例 / 251
建議106:為靜態類添加靜態構造函數 / 253
建議107:區分靜態類和單例 / 255
建議108:將類型標識為sealed / 255
建議109:謹慎使用嵌套類 / 256
建議110:用類來代替enum / 257
建議111:避免雙向耦合 / 260
建議112:將現實世界中的對象抽象為類,將可復用對象圈起來就是命名空間 / 262
第9章 安全性設計 / 264
建議113:聲明變量前考慮最大值 / 264
建議114:MD5不再安全 / 265
建議115:通過HASH來驗證文件是否被篡改 / 268
建議116:避免用非對稱算法加密文件 / 269
建議117:使用SSL確保通信中的數據安全 / 273
建議118:使用SecureString保存密鑰等機密字符串 / 284
建議119:不要使用自己的加密算法 / 289
建議120:為程序集指定強名稱 / 289
建議121:為應用程序設定運行權限 / 291
第三部分 編碼規范及習慣
第10章 命名規范 / 296
建議122:以.為命名空間命名 / 296
建議123:程序集不必與命名空間同名 / 296
建議124:考慮在命名空間中使用復數 / 297
建議125:避免用FCL的類型名稱命名自己的類型 / / 297
建議126:用名詞和名詞組給類型命名 / 298
建議127:用形容詞組給接口命名 / 299
建議128:考慮讓派生類的名字以基類名字作為后綴 / 300
建議129:泛型類型參數要以T作為前綴 / 300
建議130:以復數命名枚舉類型,以單數命名枚舉元素 / 301
建議131:用PascalCasing命名公開元素 / 302
建議132:考慮用類名作為屬性名 / 302
建議133:用camelCasing命名私有字段和局部變量 / 303
建議134:有條件地使用前綴 / 304
建議135: 考慮使用肯定性的短語命名布爾屬性 / 305
建議136:優先使用后綴表示已有類型的新版本 / 306
建議137:委托和事件類型應添加上級后綴 / 307
建議138:事件和委托變量使用動詞或形容詞短語命名 / 308
建議139:事件處理器命名采用組合方式 / 309
第11章 代碼整潔 / 311
建議140:使用默認的訪問修飾符 / 311
建議141:不知道該不該用大括號時,就用 / 312
建議142:總是提供有意義的命名 / 314
建議143:方法抽象級別應在同一層次 / 315
建議144:一個方法只做一件事 / 316
建議145:避免過長的方法和過長的類 / 317
建議146:只對外公布必要的操作 / 318
建議147:重構多個相關屬性為一個類 / 319
建議148:不重復代碼 / 320
建議149:使用表驅動法避免過長的if和switch分支 / 321
建議150:使用匿名方法、Lambda表達式代替方法 / 324
建議151:使用事件訪問器替換公開的事件成員變量 / 325
建議152:最少,甚至是不要注釋 / 326
建議153:若拋出異常,則必須要注釋 / 326
第12章 規范開發行為 / 327
建議154:不要過度設計,在敏捷中體會重構的樂趣 / 327
建議155:隨生產代碼一起提交單元測試代碼 / 336
建議156:利用特性為應用程序提供多個版本 / 342
建議157:從寫第一個界面開始,就進行自動化測試 / 344 |
序: |