C#語言簡潔優(yōu)雅,精妙強大,是當今編程語言的集大成者,功能不斷推陳出新,受到眾多開發(fā)人員的推崇。本書是C#領(lǐng)域不可多得的經(jīng)典著作,新版重磅升級,不僅重新組織了內(nèi)容,還全面更新并細致剖析了C#6和C#7的新增特性,為讀者奉上知識盛宴。作者在詳盡展示C#各個知識點的同時,注重從現(xiàn)象中挖掘本質(zhì),解讀語言背后的設(shè)計思想,深入探究了C#的核心概念和經(jīng)典特性,并將這些特性融入代碼示例,幫助讀者順暢使用C#,享受使用C#編程的樂趣。
C#領(lǐng)域不可多得的經(jīng)典著作,新版重磅升級!
1.知名技術(shù)專家的經(jīng)典之作,在C#和.NET領(lǐng)域享有盛譽。
2.與其他泛泛介紹C#的圖書不同,本書深度探究C#的特性,并結(jié)合技術(shù)發(fā)展,引領(lǐng)讀者深入C#的時空。
3.作者從語言設(shè)計的動機出發(fā),介紹支持這些特性的核心概念;基于C#語言的發(fā)展背景介紹新的語言特性,并用極富實際意義的示例,向讀者展示編寫代碼和設(shè)計解決方案的理想方式。
4.新版重新組織了內(nèi)容,進行了重寫與濃縮,還全面更新并細致剖析了C#6和C#7的新增特性。
5.提供源代碼。
作者將多年的C#開發(fā)經(jīng)驗與讀者分享,讀者可咀其精華、免走彎路,使程序設(shè)計水平更上一層樓。
喬恩·斯基特(Jon Skeet)
谷歌高級軟件工程師,微軟C# MVP,擁有近20年C#項目開發(fā)經(jīng)驗。自2002年來,他一直是C#社區(qū)、新聞組、國際會議和Stack Overflow網(wǎng)站中非;钴S的技術(shù)專家,回答了數(shù)以萬計的C#和.NET相關(guān)問題,是Stack Overflow上的傳奇貢獻者。
目錄
第 一部分 C#背景介紹
第 1章 大浪淘沙 2
1.1 一門與時俱進的語言 2
1.1.1 類型系統(tǒng)——全能型助手 3
1.1.2 代碼更簡潔 4
1.1.3 使用LINQ簡化數(shù)據(jù)訪問 8
1.1.4 異步 8
1.1.5 編碼效率與執(zhí)行效率之間的取舍 9
1.1.6 快速迭代:使用小版本號 10
1.2 一個與時俱進的平臺 11
1.3 一個與時俱進的社區(qū) 12
1.4 一本與時俱進的好書 13
1.4.1 內(nèi)容詳略得當 13
1.4.2 使用Noda Time作為示例 14
1.4.3 術(shù)語選擇 14
1.5 小結(jié) 15
第二部分 從C# 2到C#5
第 2章 C# 2 18
2.1 泛型 18
2.1.1 示例:泛型誕生前的集合 19
2.1.2 泛型降臨 21
2.1.3 泛型的適用范圍 25
2.1.4 方法類型實參的類型推斷 26
2.1.5 類型約束 28
2.1.6 default運算符和typeof運算符 30
2.1.7 泛型類型初始化與狀態(tài) 32
2.2 可空值類型 34
2.2.1 目標:表達信息的缺失 34
2.2.2 CLR和framework的支持:Nullable結(jié)構(gòu)體 35
2.2.3 語言層面支持 38
2.3 簡化委托的創(chuàng)建 43
2.3.1 方法組轉(zhuǎn)換 43
2.3.2 匿名方法 44
2.3.3 委托的兼容性 45
2.4 迭代器 46
2.4.1 迭代器簡介 47
2.4.2 延遲執(zhí)行 48
2.4.3 執(zhí)行yield語句 49
2.4.4 延遲執(zhí)行的重要性 50
2.4.5 處理finally塊 51
2.4.6 處理finally的重要性 53
2.4.7 迭代器實現(xiàn)機制概覽 54
2.5 一些小的特性 58
2.5.1 局部類型 59
2.5.2 靜態(tài)類 60
2.5.3 屬性的getter/setter訪問分離 61
2.5.4 命名空間別名 61
2.5.5 編譯指令 63
2.5.6 固定大小的緩沖區(qū) 64
2.5.7 InternalsVisibleTo 65
2.6 小結(jié) 65
第3章 C# 3:LINQ及相關(guān)特性 66
3.1 自動實現(xiàn)的屬性 66
3.2 隱式類型 67
3.2.1 類型術(shù)語 67
3.2.2 隱式類型的局部變量 68
3.2.3 隱式類型的數(shù)組 69
3.3 對象和集合的初始化 71
3.3.1 對象初始化器和集合初始化器簡介 71
3.3.2 對象初始化器 72
3.3.3 集合初始化器 74
3.3.4 僅用單一表達式就能完成初始化的好處 75
3.4 匿名類型 76
3.4.1 基本語法和行為 76
3.4.2 編譯器生成類型 78
3.4.3 匿名類型的局限性 79
3.5 lambda表達式 80
3.5.1 lambda表達式語法簡介 81
3.5.2 捕獲變量 82
3.5.3 表達式樹 89
3.6 擴展方法 91
3.6.1 聲明擴展方法 91
3.6.2 調(diào)用擴展方法 92
3.6.3 擴展方法的鏈式調(diào)用 93
3.7 查詢表達式 94
3.7.1 從C#到C#的查詢表達式轉(zhuǎn)換 95
3.7.2 范圍變量和隱形標識符 95
3.7.3 選擇使用哪種LINQ語法 96
3.8 終極形態(tài):LINQ 97
3.9 小結(jié) 98
第4章 C# 4:互操作性提升 99
4.1 動態(tài)類型 99
4.1.1 動態(tài)類型介紹 100
4.1.2 超越反射的動態(tài)行為 104
4.1.3 動態(tài)行為機制速覽 108
4.1.4 動態(tài)類型的局限與意外 111
4.1.5 動態(tài)類型的使用建議 115
4.2 可選形參和命名實參 116
4.2.1 帶默認值的形參和帶名字的實參 117
4.2.2 如何決定方法調(diào)用的含義 118
4.2.3 對版本號的影響 119
4.3 COM互操作性提升 121
4.3.1 鏈接主互操作程序集 121
4.3.2 COM組件中的可選形參 123
4.3.3 命名索引器 124
4.4 泛型型變 125
4.4.1 泛型型變示例 125
4.4.2 接口和委托聲明中的變體語法 126
4.4.3 變體的使用限制 127
4.4.4 泛型型變實例 129
4.5 小結(jié) 130
第5章 編寫異步代碼 131
5.1 異步函數(shù)簡介 132
5.1.1 異步問題初體驗 133
5.1.2 拆分第 一個例子 134
5.2 對異步模式的思考 135
5.2.1 關(guān)于異步執(zhí)行本質(zhì)的思考 136
5.2.2 同步上下文 137
5.2.3 異步方法模型 138
5.3 async方法聲明 139
5.3.1 async方法的返回類型 140
5.3.2 async方法的參數(shù) 141
5.4 await表達式 141
5.4.1 可等待模式 142
5.4.2 await表達式的限制條件 144
5.5 返回值的封裝 145
5.6 異步方法執(zhí)行流程 146
5.6.1 await的操作對象與時機 146
5.6.2 await表達式的運算 147
5.6.3 可等待模式成員的使用 150
5.6.4 異常拆封 151
5.6.5 完成方法 152
5.7 異步匿名函數(shù) 156
5.8 C# 7自定義task類型 157
5.8.1 99.9%的情況:ValueTask 158
5.8.2 剩下0.1%的情況:創(chuàng)建自定義task類型 160
5.9 C# 7.1中的異步Main方法 161
5.10 使用建議 162
5.10.1 使用ConfigureAwait避免上下文捕獲(擇機使用) 163
5.10.2 啟動多個獨立task以實現(xiàn)并行 164
5.10.3 避免同步代碼和異步代碼混用 165
5.10.4 根據(jù)需要提供取消機制 165
5.10.5 測試異步模式 165
5.11 小結(jié) 166
第6章 異步原理 167
6.1 生成代碼的結(jié)構(gòu) 168
6.1.1 樁方法:準備和開始第 一步 171
6.1.2 狀態(tài)機的結(jié)構(gòu) 172
6.1.3 MoveNext()方法(整體介紹) 175
6.1.4 SetStateMachine方法以及狀態(tài)機的裝箱事宜 177
6.2 一個簡單的MoveNext()實現(xiàn) 177
6.2.1 一個完整的具體示例 178
6.2.2 MoveNext()方法的通用結(jié)構(gòu) 179
6.2.3 詳探await表達式 181
6.3 控制流如何影響MoveNext() 183
6.3.1 await表達式之間的控制流很簡單 183
6.3.2 在循環(huán)中使用await 184
6.3.3 在try / finally塊中使用await表達式 185
6.4 執(zhí)行上下文和執(zhí)行流程 188
6.5 再探自定義task類型 189
6.6 小結(jié) 190
第7章 C# 5附加特性 191
7.1 在foreach循環(huán)中捕獲變量 191
7.2 調(diào)用方信息attribute 193
7.2.1 基本行為 193
7.2.2 日志 194
7.2.3 簡化INotifyPropertyChanged的實現(xiàn) 195
7.2.4 調(diào)用方信息attribute的小眾使用場景 196
7.2.5 舊版本.NET使用調(diào)用方信息attribute 201
7.3 小結(jié) 202
第三部分 C# 6
第8章 極簡屬性和表達式主體成員 204
8.1 屬性簡史 204
8.2 自動實現(xiàn)屬性的升級 206
8.2.1 只讀的自動實現(xiàn)屬性 206
8.2.2 自動實現(xiàn)屬性的初始化 207
8.2.3 結(jié)構(gòu)體中的自動實現(xiàn)屬性 208
8.3 表達式主體成員 210
8.3.1 簡化只讀屬性的計算 210
8.3.2 表達式主體方法、索引器和運算符 213
8.3.3 C# 6中表達式主體成員的限制 214
8.3.4 表達式主體成員使用指南 216
8.4 小結(jié) 218
第9章 字符串特性 219
9.1 NET中的字符串格式化回顧 219
9.1.1 簡單字符串格式化 219
9.1.2 使用格式化字符串來實現(xiàn)自定義格式化 220
9.1.3 屬地化 221
9.2 內(nèi)插字符串字面量介紹 224
9.2.1 簡單內(nèi)插 224
9.2.2 使用內(nèi)插字符串字面量格式化字符串 225
9.2.3 內(nèi)插原義字符串字面量 225
9.2.4 編譯器對內(nèi)插字符串字面量的處理(第 1部分) 226
9.3 使用FormattableSting實現(xiàn)屬地化 227
9.3.1 編譯器對內(nèi)插字符串字面量的處理(第 2部分) 228
9.3.2 在特定culture下格式化一個FormattableString 229
9.3.3 FormattableString的其他用途 230
9.3.4 在舊版本.NET中使用FormattableString 233
9.4 使用指南和使用限制 234
9.4.1 適合開發(fā)人員和機器,但可能不適合最終用戶 235
9.4.2 關(guān)于內(nèi)插字符串字面量的硬性限制 236
9.4.3 何時可以用但不應(yīng)該用 238
9.5 使用nameof訪問標識符 239
9.5.1 nameof的第 一個例子 239
9.5.2 nameof的一般用法 241
9.5.3 使用nameof的技巧與陷阱 243
9.6 小結(jié) 246
第 10章 簡潔代碼的特性“盛宴” 247
10.1 using static指令 247
10.1.1 引入靜態(tài)成員 247
10.1.2 using static與擴展方法 250
10.2 對象初始化器和集合初始化器特性增強 252
10.2.1 對象初始化器中的索引器 252
10.2.2 在集合初始化器中使用擴展方法 256
10.2.3 測試代碼與產(chǎn)品代碼 259
10.3 空值條件運算符 260
10.3.1 簡單、安全地解引用 260
10.3.2 關(guān)于空值條件運算符的更多細節(jié) 261
10.3.3 處理布爾值比較 262
10.3.4 索引器與空值條件運算符 263
10.3.5 使用空值條件運算符提升編程效率 263
10.3.6 空值條件運算符的局限性 265
10.4 異常過濾器 265
10.4.1 異常過濾器的語法和語義 266
10.4.2 重試操作 270
10.4.3 記錄日志的“副作用” 272
10.4.4 單個、有針對性的日志過濾器 273
10.4.5 為何不直接拋出異!273
10.5 小結(jié) 274
第四部分 C# 7及其后續(xù)版本
第 11章 使用元組進行組合 277
11.1 元組介紹 277
11.2 元組字面量和元組類型 278
11.2.1 語法 278
11.2.2 元組字面量推斷元素名稱(C# 7.1) 280
11.2.3 元組用作變量的容器 281
11.3 元組類型及其轉(zhuǎn)換 285
11.3.1 元組字面量的類型 285
11.3.2 從元組字面量到元組類型的轉(zhuǎn)換 287
11.3.3 元組類型之間的轉(zhuǎn)換 290
11.3.4 類型轉(zhuǎn)換的應(yīng)用 292
11.3.5 繼承時的元素名稱檢查 292
11.3.6 等價運算符與不等價運算符(C# 7.3) 293
11.4 CLR 中的元組 294
11.4.1 引入System.ValueTuple<> 294
11.4.2 處理元素名稱 294
11.4.3 元組類型轉(zhuǎn)換的實現(xiàn) 296
11.4.4 元組的字符串表示 296
11.4.5 一般等價比較和排序比較 297
11.4.6 結(jié)構(gòu)化等價比較和排序比較 298
11.4.7 獨素元組和巨型元組 299
11.4.8 非泛型ValueTuple結(jié)構(gòu)體 300
11.4.9 擴展方法 301
11.5 元組的替代品 301
11.5.1 System.Tuple<> 301
11.5.2 匿名類型 301
11.5.3 命名類型 302
11.6 元組的使用建議 302
11.6.1 非公共API以及易變的代碼 303
11.6.2 局部變量 303
11.6.3 字段 304
11.6.4 元組和動態(tài)類型不太搭調(diào) 305
11.7 小結(jié) 306
第 12章 分解與模式匹配 307
12.1 分解元組 307
12.1.1 分解成新變量 308
12.1.2 通過分解操作為已有變量或者屬性賦值 310
12.1.3 元組字面量分解的細節(jié) 313
12.2 非元組類型的分解操作 314
12.2.1 實例分解方法 314
12.2.2 擴展分解方法與重載 315
12.2.3 編譯器對于Deconstruct調(diào)用的處理 316
12.3 模式匹配簡介 317
12.4 C# 7.0可用的模式 319
12.4.1 常量模式 319
12.4.2 類型模式 320
12.4.3 var模式 323
12.5 模式匹配與is運算符的搭配使用 324
12.6 在switch語句中使用模式 325
12.6.1 哨兵語句 326
12.6.2 case標簽中的模式變量的作用域 328
12.6.3 基于模式的switch語句的運算順序 329
12.7 對模式特性使用的思考 330
12.7.1 發(fā)現(xiàn)分解的時機 330
12.7.2 發(fā)現(xiàn)模式匹配的使用時機 331
12.8 小結(jié) 331
第 13章 引用傳遞提升執(zhí)行效率 332
13.1 回顧:ref知多少 333
13.2 ref局部變量和ref return 336
13.2.1 ref局部變量 336
13.2.2 ref return 341
13.2.3 條件運算符 :和ref值(C# 7.2) 343
13.2.4 ref readonly(C# 7.2) 343
13.3 in參數(shù)(C# 7.2) 345
13.3.1 兼容性考量 346
13.3.2 in參數(shù)驚人的不可變性:外部修改 347
13.3.3 使用in參數(shù)進行方法重載 348
13.3.4 in參數(shù)的使用指導(dǎo) 348
13.4 將結(jié)構(gòu)體聲明為只讀(C# 7.2) 350
13.4.1 背景:只讀變量的隱式復(fù)制 350
13.4.2 結(jié)構(gòu)體的只讀修飾符 352
13.4.3 XML序列化是隱式讀寫屬性 353
13.5 使用ref參數(shù)或者in參數(shù)的擴展方法(C# 7.2) 354
13.5.1 在擴展方法中使用ref/in參數(shù)來規(guī)避復(fù)制 354
13.5.2 ref和in擴展方法的使用限制 355
13.6 類ref結(jié)構(gòu)體(C# 7.2) 357
13.6.1 類ref結(jié)構(gòu)體的規(guī)則 357
13.6.2 Span和棧內(nèi)存分配 358
13.6.3 類ref結(jié)構(gòu)體的IL表示 362
13.7 小結(jié) 362
第 14章 C# 7的代碼簡潔之道 363
14.1 局部方法 363
14.1.1 局部方法中的變量訪問 364
14.1.2 局部方法的實現(xiàn) 367
14.1.3 使用指南 371
14.2 out變量 373
14.2.1 out參數(shù)的內(nèi)聯(lián)變量聲明 374
14.2.2 C# 7.3 關(guān)于out變量和模式變量解除的限制 374
14.3 數(shù)字字面量的改進 375
14.3.1 二進制整型字面量 375
14.3.2 下劃線分隔符 376
14.4 throw表達式 377
14.5 default字面量(C# 7.1) 377
14.6 非尾部命名實參 379
14.7 私有受保護的訪問權(quán)限(C# 7.2) 380
14.8 C# 7.3的一些小改進 380
14.8.1 泛型類型約束 381
14.8.2 重載決議改進 381
14.8.3 字段的attribute支持自動實現(xiàn)的屬性 382
14.9 小結(jié) 383
第 15章 C# 8及其后續(xù) 384
15.1 可空引用類型 384
15.1.1 可空引用類型可以解決什么問題 385
15.1.2 在使用引用類型時改變其含義 385
15.1.3 輸入可空引用類型 387
15.1.4 編譯時和執(zhí)行期的可空引用類型 387
15.1.5 damnit運算符或者bang運算符 389
15.1.6 可空引用類型遷移的經(jīng)驗 391
15.1.7 未來的改進 393
15.2 switch表達式 396
15.3 嵌套模式匹配 398
15.3.1 使用模式來匹配屬性 398
15.3.2 分解模式 399
15.3.3 忽略模式中的類型 399
15.4 index和range 400
15.4.1 index與range類型和字面量 401
15.4.2 應(yīng)用index和range 402
15.5 更多異步集成 403
15.5.1 使用await實現(xiàn)異步資源回收 403
15.5.2 使用foreach await的異步迭代 404
15.5.3 異步迭代器 407
15.6 預(yù)覽版中尚未提供的特性 408
15.6.1 默認接口方法 408
15.6.2 記錄類型 409
15.6.3 更多特性 410
15.7 歡迎加入 412
15.8 小結(jié) 412
附錄 特性與語言版本對照表 413