Effective C#:改善C#代碼的50個(gè)有效方法(原書(shū)第3版)
定 價(jià):79 元
叢書(shū)名:Effective系列叢書(shū)
- 作者:[美]比爾·瓦格納(Bill Wagner)
- 出版時(shí)間:2018/5/1
- ISBN:9787111597193
- 出 版 社:機(jī)械工業(yè)出版社
- 中圖法分類:TP312C
- 頁(yè)碼:251
- 紙張:膠版紙
- 版次:1
- 開(kāi)本:16開(kāi)
本書(shū)分為5個(gè)章節(jié),第1章介紹一些常見(jiàn)的語(yǔ)言結(jié)構(gòu),它們是開(kāi)發(fā)者手頭必備的工具,無(wú)論創(chuàng)建什么樣的類型與算法,都離不開(kāi)它們;第2章介紹一些設(shè)計(jì)習(xí)慣,告訴你應(yīng)該怎樣把代碼寫(xiě)得與托管環(huán)境相協(xié)調(diào);第3章講解怎樣用泛型取代System.Object以及強(qiáng)制類型轉(zhuǎn)換,并討論一些高級(jí)技術(shù),如約束、泛型特化、方法約束以及向后兼容等;第4章講解LINQ、查詢語(yǔ)法以及與之相關(guān)的語(yǔ)言特性,包括什么時(shí)候運(yùn)用擴(kuò)展方法把協(xié)定與實(shí)現(xiàn)相分離、怎樣有效地使用閉包以及如何編寫(xiě)匿名類型等;第5章指引你把C#程序中的異常與錯(cuò)誤處理好。
Preface 前 言本書(shū)第1版于2004年出版,到了2016年,C#開(kāi)發(fā)社群的情況已經(jīng)有了很大的變化。使用這門語(yǔ)言編寫(xiě)程序的人越來(lái)越多,很多人現(xiàn)在都把C#當(dāng)作首選的工作語(yǔ)言,并且不會(huì)再按照使用其他語(yǔ)言時(shí)所形成的那些習(xí)慣來(lái)使用這門語(yǔ)言。此外,C# 開(kāi)發(fā)者所具備的經(jīng)驗(yàn)各不相同,從剛畢業(yè)的學(xué)生到擁有數(shù)十年經(jīng)驗(yàn)的專業(yè)開(kāi)發(fā)者,都有人在用C#寫(xiě)程序,而且 C# 所支持的平臺(tái)也比原來(lái)更加廣泛。你可以用它架設(shè)服務(wù)器或制作網(wǎng)站,也可以為各種操作系統(tǒng)開(kāi)發(fā)桌面版本或移動(dòng)版本的應(yīng)用程序。
這次升級(jí)的第3版既考慮到C#語(yǔ)言本身的變化,也考慮到使用這門語(yǔ)言的人(或者說(shuō) C# 開(kāi)發(fā)社群)所發(fā)生的變化。筆者并不打算講述C#語(yǔ)言的演變歷程,而是關(guān)注怎樣用好當(dāng)前版本的 C# 語(yǔ)言。舊版的某些條目已經(jīng)與當(dāng)今的 C# 語(yǔ)言或 C# 應(yīng)用程序脫節(jié)了,這些內(nèi)容不會(huì)出現(xiàn)在新版中。新版中會(huì)添加一些條目,以講述 C# 語(yǔ)言的新特性與 .NET 框架的新功能,這些內(nèi)容是從軟件產(chǎn)品的開(kāi)發(fā)過(guò)程中提煉出來(lái)的,許多C#開(kāi)發(fā)者采用這些特性開(kāi)發(fā)了多個(gè)版本的軟件?催^(guò)《More Effective C#》第1版的讀者稍后可能會(huì)發(fā)現(xiàn),那本書(shū)里的某些內(nèi)容已經(jīng)移到了本書(shū)中。在本書(shū)第3版中,筆者重新編排《More Effective C#》的內(nèi)容,刪除了原有的許多條目,以便在那本書(shū)的第2版中添加其他一些條目?傊,這本書(shū)里的 50 個(gè)條目都是一些編程建議,可以幫助你更為高效地使用 C# 語(yǔ)言,從而成為更加專業(yè)的開(kāi)發(fā)者。
本書(shū)預(yù)設(shè)的語(yǔ)境是 6.0 版本的 C#,然而筆者并不會(huì)把該版本的功能全都拿出來(lái)講。與Effective Software Development系列的其他書(shū)一樣,這本書(shū)所關(guān)注的也是怎樣用語(yǔ)言特性來(lái)解決日常工作中可能遇到的問(wèn)題,并提供實(shí)用的建議。在 C# 6.0 版的這些特性中,筆者會(huì)特意挑出一些來(lái)講,因?yàn)槠渲械哪承┨匦阅軌蚴归_(kāi)發(fā)者以更好的方式來(lái)編寫(xiě)常用的代碼。網(wǎng)上搜到的寫(xiě)法可能是針對(duì)許多年前的C#版本而寫(xiě)的,有了新版C#所引入的特性之后,開(kāi)發(fā)者就可以用更好的寫(xiě)法來(lái)完成那些任務(wù)了,對(duì)于此類情況,筆者會(huì)專門指出。
書(shū)中的很多建議都可以用Roslyn平臺(tái)的Analyzer及Code Fix加以體現(xiàn),從而驗(yàn)證開(kāi)發(fā)者所寫(xiě)的代碼是否符合這些建議。筆者把相關(guān)的Analyzer放在了這里:https://github.com/BillWagner/EffectiveCSharpAnalyzers。你可以提交 issue,以表達(dá)自己的看法,或是發(fā)送 pull request為項(xiàng)目添加新的內(nèi)容。
讀者對(duì)象本書(shū)面向的是那些使用 C# 來(lái)完成日常工作的職業(yè)開(kāi)發(fā)者。由于本書(shū)假設(shè)讀者已經(jīng)熟悉了 C# 的語(yǔ)法及語(yǔ)言特性,因此,并不會(huì)按部就班地講解這些特性,而是會(huì)告訴你應(yīng)該怎樣把當(dāng)前這一版 C# 語(yǔ)言所擁有的各種特性融入日常的開(kāi)發(fā)工作中。
除了要熟悉語(yǔ)言本身的特性之外,還應(yīng)該對(duì) CLR(Common Language Runtime,公共語(yǔ)言運(yùn)行時(shí))及 JIT(Just-In-Time,即時(shí))編譯器有所了解。
內(nèi)容提要有一些語(yǔ)言結(jié)構(gòu)是每次寫(xiě) C# 程序時(shí)幾乎都會(huì)用到的,這些常見(jiàn)的寫(xiě)法出現(xiàn)在本書(shū)的第1章中,它們是開(kāi)發(fā)者手頭必備的工具,無(wú)論創(chuàng)建什么樣的類型與算法,都離不開(kāi)這些工具。
盡管 C# 程序運(yùn)行在托管環(huán)境中,但并不是說(shuō)開(kāi)發(fā)者什么事情都不用操心。要想令程序的性能滿足需求,就必須編寫(xiě)出能夠與托管環(huán)境相協(xié)調(diào)的代碼,這不是單靠性能測(cè)試與性能調(diào)整就可以實(shí)現(xiàn)的。因此,第2章會(huì)介紹一些設(shè)計(jì)習(xí)慣,告訴你應(yīng)該怎樣把代碼寫(xiě)得與托管環(huán)境相協(xié)調(diào)。以良好的設(shè)計(jì)風(fēng)格為基礎(chǔ),可以更加有效地優(yōu)化細(xì)節(jié)問(wèn)題。
自C# 2.0以來(lái)所引入的很多新技術(shù)都是以泛型為依托的。第3章講解怎樣用泛型取代System.Object以及強(qiáng)制類型轉(zhuǎn)換,然后,筆者會(huì)討論一些高級(jí)技術(shù),例如約束、泛型特化、方法約束以及向后兼容等。讀完本章之后,你會(huì)學(xué)到很多泛型技巧,從而能夠更加順暢地表達(dá)出自己的設(shè)計(jì)思路。
第4章會(huì)講解 LINQ、查詢語(yǔ)法以及與之相關(guān)的語(yǔ)言特性。你會(huì)了解到在哪些情況下應(yīng)該運(yùn)用擴(kuò)展方法把協(xié)定與實(shí)現(xiàn)相分離,還會(huì)學(xué)到應(yīng)該怎樣有效地使用閉包以及如何編寫(xiě)匿名類型。此外,筆者還會(huì)解釋編譯器怎樣把查詢關(guān)鍵字映射成方法調(diào)用、如何區(qū)分委托與表達(dá)式樹(shù)以及必要時(shí)怎樣在二者之間轉(zhuǎn)換,以及如何對(duì)查詢做出轉(zhuǎn)義以獲取純量形式的結(jié)果。
第 5 章會(huì)指引你把 C# 程序中的異常與錯(cuò)誤處理好。筆者要講解怎樣確保程序中的錯(cuò)誤能夠得到適當(dāng)?shù)膮R報(bào),以及如何令程序的狀態(tài)在出錯(cuò)之后依然保持穩(wěn)定,甚至與出錯(cuò)之前一樣。此外,你還會(huì)學(xué)到怎樣給使用代碼的人提供便利,令他們能夠更加順暢地調(diào)試你所編寫(xiě)的程序。
代碼約定要想把范例代碼印在書(shū)中,就必須在保持清晰的前提下顧及篇幅。筆者盡量把代碼寫(xiě)得簡(jiǎn)短,以凸顯其中最關(guān)鍵的部分,并把類或方法中的其他部分省掉。有時(shí)為了節(jié)省篇幅,還會(huì)把錯(cuò)誤恢復(fù)代碼也省掉。public 方法自然應(yīng)該驗(yàn)證其參數(shù)以及外界輸入給它的數(shù)據(jù),但考慮到篇幅,筆者通常會(huì)把這些代碼去掉。此外,很多復(fù)雜的算法還會(huì)對(duì)方法調(diào)用做出核查,而且會(huì)包含try/finally子句,這些代碼也因同樣的理由而刪去。
常見(jiàn)的命名空間就不再寫(xiě)出了。你可以認(rèn)為每一份范例代碼前面都寫(xiě)有下面幾條 using語(yǔ)句:
提供反饋意見(jiàn)筆者與本書(shū)的審閱者都盡力確保書(shū)中的內(nèi)容正確無(wú)誤,盡管如此,本書(shū)與范例代碼里面可能還是會(huì)有一些錯(cuò)誤,讀者如果發(fā)現(xiàn)某個(gè)地方寫(xiě)錯(cuò)了,請(qǐng)發(fā)郵件至bill@thebillwagner.com,或通過(guò)Twitter號(hào)碼@billwagner聯(lián)系我?闭`表將會(huì)發(fā)布至http://thebillwagner.com/Resources/Effectivecs。書(shū)中的很多條目是筆者在與其他C#開(kāi)發(fā)者通過(guò)電子郵件及Twitter討論之后寫(xiě)出的,讀者若對(duì)這些編程建議有疑問(wèn)或意見(jiàn),也請(qǐng)聯(lián)系筆者。更為一般的話題可參見(jiàn)筆者博客:http://thebillwagner.com/blog。
致謝我要感謝為本書(shū)做出貢獻(xiàn)的諸多人士。很榮幸能在這些年里與大家一起使用 C# 語(yǔ)言。C# Insiders 郵件列表中的每位朋友(無(wú)論身處 Microsoft 公司之內(nèi)或之外)都為本書(shū)提供了創(chuàng)意,并且愿意與我交流,使我能把這本書(shū)寫(xiě)得更好。
必須特別感謝下面這幾位 C# 開(kāi)發(fā)者:Jon Skeet、Dustin Campbell、Kevin Pilch-Bisson、Jared Parsons、Scott Allen 以及 Mads Torgersen。感謝你們與我溝通、向我提供意見(jiàn),并將其轉(zhuǎn)變?yōu)榫唧w的成果。這一版的很多新想法都是根據(jù)諸位的意見(jiàn)而形成的。
這一版的技術(shù)評(píng)審團(tuán)隊(duì)同樣很出色。Jason Bock、Mark Michaelis 與 Eric Lippert 仔細(xì)閱讀了文稿與范例代碼,以確保讀者能拿到一本優(yōu)質(zhì)的書(shū)籍。他們的水平相當(dāng)高,不僅全面而徹底地審閱了本書(shū),而且還提供了一些建議,幫助我把其中的很多話題解釋得更為清楚。
我與Addison-Wesley出版社的編輯團(tuán)隊(duì)合作得相當(dāng)愉快。Trina Macdonald 是一位優(yōu)秀的編輯,總能督促我把書(shū)寫(xiě)好。Mark Renfro 與 Olivia Basegio 是她的得力幫手,我依靠他們完成了很多工作,這本書(shū)的定稿能夠達(dá)到現(xiàn)在這樣的質(zhì)量,與他們的努力有很大關(guān)系,從頭到尾的每一頁(yè)內(nèi)容都是如此。Curt Johnson 致力于發(fā)售這本技術(shù)圖書(shū),無(wú)論是哪種格式都有他的一份心力在里面。
感謝Scott Meyers再度將本書(shū)收入 Effective 書(shū)系,他閱讀了整部文稿,并提出了一些改進(jìn)建議。Meyers 雖然不是做 C# 的,但卻有著豐富的軟件開(kāi)發(fā)經(jīng)驗(yàn),能夠把文稿中沒(méi)有解釋清楚的地方找出來(lái),而且能指出其中有哪些技巧還不足以總結(jié)成心得推薦給大家使用。他的意見(jiàn),給我?guī)?lái)了很大的幫助。
感謝家人留出時(shí)間,令我可以寫(xiě)完這本書(shū)。我花了很長(zhǎng)時(shí)間撰寫(xiě)書(shū)稿并制作范例代碼,妻子 Marlene 總是給予我支持。有她的鼓勵(lì),我才能把這本書(shū)和其他的書(shū)寫(xiě)好。
Contents 目 錄
本書(shū)贊譽(yù)
譯者序
前言
第1章 C#語(yǔ)言的編程習(xí)慣1
第1條:優(yōu)先使用隱式類型的局部變量1
第2條:考慮用readonly代替const8
第3條:優(yōu)先考慮is或as運(yùn)算符,盡量少用強(qiáng)制類型轉(zhuǎn)換12
第4條:用內(nèi)插字符串取代string.Format()20
第5條:用FormattableString取代專門為特定區(qū)域而寫(xiě)的字符串24
第6條:不要用表示符號(hào)名稱的硬字符串來(lái)調(diào)用 API26
第7條:用委托表示回調(diào)28
第8條:用null條件運(yùn)算符調(diào)用事件處理程序31
第9條:盡量避免裝箱與取消裝箱這兩種操作34
第10條:只有在應(yīng)對(duì)新版基類與現(xiàn)有子類之間的沖突時(shí)才應(yīng)該使用 new修飾符38
第2章 .NET的資源管理42
第11條:理解并善用 .NET的資源管理機(jī)制42
第12條:聲明字段時(shí),盡量直接為其設(shè)定初始值47
第13條:用適當(dāng)?shù)姆绞匠跏蓟愔械撵o態(tài)成員50
第14條:盡量刪減重復(fù)的初始化邏輯52
第15條:不要?jiǎng)?chuàng)建無(wú)謂的對(duì)象60
第16條:絕對(duì)不要在構(gòu)造函數(shù)里面調(diào)用虛函數(shù)64
第17條:實(shí)現(xiàn)標(biāo)準(zhǔn)的dispose 模式67
第3章 合理地運(yùn)用泛型74
第18條:只定義剛好夠用的約束條件76
第19條:通過(guò)運(yùn)行期類型檢查實(shí)現(xiàn)特定的泛型算法82
第20條:通過(guò)IComparable及IComparer定義順序關(guān)系88
第21條:創(chuàng)建泛型類時(shí),總是應(yīng)該給實(shí)現(xiàn)了IDisposable的類型參數(shù)提供支持95
第22條:考慮支持泛型協(xié)變與逆變98
第23條:用委托要求類型參數(shù)必須
提供某種方法104
第24條:如果有泛型方法,就不要
再創(chuàng)建針對(duì)基類或接口的
重載版本110
第25條:如果不需要把類型參數(shù)所
表示的對(duì)象設(shè)為實(shí)例字段,
那么應(yīng)該優(yōu)先考慮創(chuàng)建泛
型方法,而不是泛型類114
第26條:實(shí)現(xiàn)泛型接口的同時(shí),還
應(yīng)該實(shí)現(xiàn)非泛型接口118
第27條:只把必備的契約定義在接
口中,把其他功能留給擴(kuò)
展方法去實(shí)現(xiàn)124
第28條:考慮通過(guò)擴(kuò)展方法增強(qiáng)已
構(gòu)造類型的功能128
第4章 合理地運(yùn)用LINQ131
第29條:優(yōu)先考慮提供迭代器方法,
而不要返回集合131
第30條:優(yōu)先考慮通過(guò)查詢語(yǔ)句來(lái)
編寫(xiě)代碼,而不要使用循環(huán)
語(yǔ)句137
第31條:把針對(duì)序列的API設(shè)計(jì)得
更加易于拼接142
第32條:將迭代邏輯與操作、謂詞
及函數(shù)解耦149
第33條:等真正用到序列中的元素
時(shí)再去生成153
第34條:考慮通過(guò)函數(shù)參數(shù)來(lái)放松
耦合關(guān)系155
第35條:絕對(duì)不要重載擴(kuò)展方法162
第36條:理解查詢表達(dá)式與方法調(diào)
用之間的映射關(guān)系165
第37條:盡量采用惰性求值的方式
來(lái)查詢,而不要及早求值177
第38條:考慮用lambda表達(dá)式來(lái)
代替方法182
第39條:不要在Func與Action中
拋出異常186
第40條:掌握盡早執(zhí)行與延遲執(zhí)行
之間的區(qū)別188
第41條:不要把開(kāi)銷較大的資源捕
獲到閉包中193
第42條:注意IEnumerable與
IQueryable形式的數(shù)據(jù)
源之間的區(qū)別206
第43條:用Single()及First()
來(lái)明確地驗(yàn)證你對(duì)查詢結(jié)果
所做的假設(shè)211
第44條:不要修改綁定變量214
第5章 合理地運(yùn)用異常220
第45條:考慮在方法約定遭到違背
時(shí)拋出異常220
第46條:利用using與try/finally
來(lái)清理資源224
第47條:專門針對(duì)應(yīng)用程序創(chuàng)建異常231
第48條:優(yōu)先考慮做出強(qiáng)異常保證237
第49條:考慮用異常篩選器來(lái)改寫(xiě)
先捕獲異常再重新拋出的
邏輯244
第50條:合理利用異常篩選器的副
作用來(lái)實(shí)現(xiàn)某些效果248
中英文詞匯對(duì)照表252