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