第Ⅰ部分 C# 语 言
第1章 .NET应用程序体系结构 2
1.1 选择技术 2
1.2 回顾.NET历史 3
1.2.1 C# 1.0 —— 一种新语言 3
1.2.2 带有泛型的C# 2和.NET 2 5
1.2.3 .NET 3.0—— Windows
Presentation Foundation 5
1.2.4 C# 3和.NET 3.5—— LINQ 5
1.2.5 C# 4和.NET 4.0—— dynamic
和TPL 6
1.2.6 C# 5和异步编程 6
1.2.7 C# 6和.NET Core 7
1.2.8 选择技术,继续前进 8
1.3 .NET 2015 8
1.3.1 .NET Framework 4.6 9
1.3.2 .NET Core 1.0 10
1.3.3 程序集 11
1.3.4 NuGet 包 12
1.3.5 公共语言运行库 13
1.3.6 .NET Native 14
1.3.7 Windows 运行库 14
1.4 Hello, World 15
1.5 用.NET 4.6编译 16
1.6 用.NET Core CLI编译 17
1.6.1 设置环境 18
1.6.2 构建应用程序 18
1.6.3 打包和发布应用程序 21
1.7 应用程序类型和技术 22
1.7.1 数据访问 22
1.7.2 Windows桌面应用程序 23
1.7.3 UWP 24
1.7.4 SOAP服务和WCF 24
1.7.5 Web服务和ASP.NET Web
API 24
1.7.6 WebHooks和SignalR 25
1.7.7 Windows服务 25
1.7.8 Web应用程序 25
1.7.9 Microsoft Azure 26
1.8 开发工具 27
1.8.1 Visual Studio Community 27
1.8.2 Visual Studio Professional with
MSDN 27
1.8.3 Visual Studio Enterprise with
MSDN 27
1.8.4 Visual Studio Code 28
1.9 小结 28
第2章 核心C# 29
2.1 C#基础 30
2.2 用Visual Studio创建Hello,
World! 30
2.2.1 创建解决方案 30
2.2.2 创建新项目 31
2.2.3 编译和运行程序 33
2.2.4 代码的详细介绍 35
2.3 变量 36
2.3.1 初始化变量 37
2.3.2 类型推断 38
2.3.3 变量的作用域 39
2.3.4 常量 41
2.4 预定义数据类型 41
2.4.1 值类型和引用类型 42
2.4.2 .NET类型 43
2.4.3 预定义的值类型 43
2.4.4 预定义的引用类型 46
2.5 程序流控制 48
2.5.1 条件语句 48
2.5.2 循环 51
2.5.3 跳转语句 55
2.6 枚举 55
2.7 名称空间 57
2.7.1 using语句 58
2.7.2 名称空间的别名 59
2.8 Main()方法 60
2.9 使用注释 61
2.9.1 源文件中的内部注释 61
2.9.2 XML文档 62
2.10 C#预处理器指令 63
2.10.1 #define和#undef 63
2.10.2 #if、#elif、#else和#endif 64
2.10.3 #warning和 # error 65
2.10.4 #region和#endregion 65
2.10.5 #line 65
2.10.6 #pragma 65
2.11 C#编程准则 66
2.11.1 关于标识符的规则 66
2.11.2 用法约定 67
2.12 小结 70
第3章 对象和类型 71
3.1 创建及使用类 72
3.2 类和结构 72
3.3 类 73
3.3.1 字段 73
3.3.2 属性 74
3.3.3 方法 76
3.3.4 构造函数 81
3.3.5 只读成员 85
3.3.6 只读字段 85
3.4 匿名类型 88
3.5 结构 89
3.5.1 结构是值类型 90
3.5.2 结构和继承 91
3.5.3 结构的构造函数 91
3.6 按值和按引用传递参数 91
3.6.1 ref参数 92
3.6.2 out参数 93
3.7 可空类型 94
3.8 枚举 95
3.9 部分类 97
3.10 扩展方法 99
3.11 Object类 100
3.12 小结 101
第4章 继承 102
4.1 继承 102
4.2 继承的类型 102
4.2.1 多重继承 103
4.2.2 结构和类 103
4.3 实现继承 103
4.3.1 虚方法 104
4.3.2 多态性 106
4.3.3 隐藏方法 107
4.3.4 调用方法的基类版本 108
4.3.5 抽象类和抽象方法 109
4.3.6 密封类和密封方法 110
4.3.7 派生类的构造函数 110
4.4 修饰符 112
4.4.1 访问修饰符 113
4.4.2 其他修饰符 113
4.5 接口 114
4.5.1 定义和实现接口 115
4.5.2 派生的接口 118
4.6 is和as运算符 120
4.7 小结 121
第5章 托管和非托管的资源 122
5.1 资源 122
5.2 后台内存管理 123
5.2.1 值数据类型 123
5.2.2 引用数据类型 125
5.2.3 垃圾回收 127
5.3 强引用和弱引用 129
5.4 处理非托管的资源 130
5.4.1 析构函数或终结器 130
5.4.2 IDisposable接口 131
5.4.3 using语句 132
5.4.4 实现IDisposable接口和
析构函数 133
5.4.5 IDisposable和终结器的
规则 134
5.5 不安全的代码 135
5.5.1 用指针直接访问内存 135
5.5.2 指针示例:
PointerPlayground 143
5.5.3 使用指针优化性能 147
5.6 平台调用 150
5.7 小结 154
第6章 泛型 155
6.1 泛型概述 155
6.1.1 性能 156
6.1.2 类型安全 157
6.1.3 二进制代码的重用 157
6.1.4 代码的扩展 158
6.1.5 命名约定 158
6.2 创建泛型类 158
6.3 泛型类的功能 162
6.3.1 默认值 163
6.3.2 约束 163
6.3.3 继承 166
6.3.4 静态成员 167
6.4 泛型接口 167
6.4.1 协变和抗变 168
6.4.2 泛型接口的协变 169
6.4.3 泛型接口的抗变 170
6.5 泛型结构 171
6.6 泛型方法 173
6.6.1 泛型方法示例 174
6.6.2 带约束的泛型方法 175
6.6.3 带委托的泛型方法 176
6.6.4 泛型方法规范 176
6.7 小结 178
第7章 数组和元组 179
7.1 同一类型和不同类型的多个
对象 179
7.2 简单数组 180
7.2.1 数组的声明 180
7.2.2 数组的初始化 180
7.2.3 访问数组元素 181
7.2.4 使用引用类型 182
7.3 多维数组 183
7.4 锯齿数组 184
7.5 Array类 185
7.5.1 创建数组 185
7.5.2 复制数组 186
7.5.3 排序 187
7.6 数组作为参数 190
7.6.1 数组协变 190
7.6.2 ArraySegment<T> 191
7.7 枚举 191
7.7.1 IEnumerator接口 192
7.7.2 foreach语句 192
7.7.3 yield语句 193
7.8 元组 197
7.9 结构比较 198
7.10 小结 201
第8章 运算符和类型强制转换 202
8.1 运算符和类型转换 202
8.2 运算符 203
8.2.1 运算符的简化操作 204
8.2.2 运算符的优先级和关联性 212
8.3 类型的安全性 213
8.3.1 类型转换 213
8.3.2 装箱和拆箱 217
8.4 比较对象的相等性 218
8.4.1 比较引用类型的相等性 218
8.4.2 比较值类型的相等性 219
8.5 运算符重载 219
8.5.1 运算符的工作方式 220
8.5.2 运算符重载的示例:Vector
结构 221
8.5.3 比较运算符的重载 225
8.5.4 可以重载的运算符 227
8.6 实现自定义的索引运算符 228
8.7 实现用户定义的类型强制
转换 230
8.7.1 实现用户定义的类型强制
转换 231
8.7.2 多重类型强制转换 237
8.8 小结 240
第9章 委托、lambda表达式和
事件 241
9.1 引用方法 241
9.2 委托 242
9.2.1 声明委托 242
9.2.2 使用委托 243
9.2.3 简单的委托示例 246
9.2.4 Action<T>和Func<T>
委托 248
9.2.5 BubbleSorter示例 248
9.2.6 多播委托 251
9.2.7 匿名方法 254
9.3 lambda表达式 255
9.3.1 参数 256
9.3.2 多行代码 256
9.3.3 闭包 257
9.4 事件 258
9.4.1 事件发布程序 258
9.4.2 事件侦听器 260
9.4.3 弱事件 261
9.5 小结 263
第10章 字符串和正则表达式 264
10.1 System.String类 265
10.1.1 构建字符串 266
10.1.2 StringBuilder成员 269
10.2 字符串格式 270
10.2.1 字符串插值 270
10.2.2 日期时间和数字的格式 272
10.2.3 自定义字符串格式 274
10.3 正则表达式 275
10.3.1 正则表达式概述 275
10.3.2 RegularExpressionsPlayaround
示例 276
10.3.3 显示结果 279
10.3.4 匹配、组和捕获 280
10.4 小结 283
第11章 集合 284
11.1 概述 284
11.2 集合接口和类型 285
11.3 列表 285
11.3.1 创建列表 287
11.3.2 只读集合 294
11.4 队列 294
11.5 栈 298
11.6 链表 300
11.7 有序列表 305
11.8 字典 306
11.8.1 字典初始化器 307
11.8.2 键的类型 307
11.8.3 字典示例 308
11.8.4 Lookup类 312
11.8.5 有序字典 313
11.9 集 313
11.10 性能 315
11.11 小结 316
第12章 特殊的集合 317
12.1 概述 317
12.2 处理位 317
12.2.1 BitArray类 318
12.2.2 BitVector32结构 320
12.3 可观察的集合 323
12.4 不变的集合 324
12.4.1 使用构建器和不变的
集合 327
12.4.2 不变集合类型和接口 327
12.4.3 使用LINQ和不变的
数组 328
12.5 并发集合 328
12.5.1 创建管道 329
12.5.2 使用BlockingCollection 332
12.5.3 使用Concurrent-
Dictionary 333
12.5.4 完成管道 334
12.6 小结 335
第13章 LINQ 337
13.1 LINQ概述 337
13.1.1 列表和实体 338
13.1.2 LINQ查询 341
13.1.3 扩展方法 342
13.1.4 推迟查询的执行 343
13.2 标准的查询操作符 345
13.2.1 筛选 347
13.2.2 用索引筛选 347
13.2.3 类型筛选 348
13.2.4 复合的from子句 348
13.2.5 排序 349
13.2.6 分组 350
13.2.7 LINQ 查询中的变量 351
13.2.8 对嵌套的对象分组 352
13.2.9 内连接 353
13.2.10 左外连接 355
13.2.11 组连接 355
13.2.12 集合操作 358
13.2.13 合并 360
13.2.14 分区 360
13.2.15 聚合操作符 362
13.2.16 转换操作符 363
13.2.17 生成操作符 365
13.3 并行LINQ 365
13.3.1 并行查询 365
13.3.2 分区器 366
13.3.3 取消 367
13.4 表达式树 367
13.5 LINQ提供程序 370
13.6 小结 371
第14章 错误和异常 372
14.1 简介 372
14.2 异常类 373
14.3 捕获异常 374
14.3.1 实现多个catch块 377
14.3.2 在其他代码中捕获异常 380
14.3.3 System.Exception属性 380
14.3.4 异常过滤器 381
14.3.5 重新抛出异常 382
14.3.6 没有处理异常时发生的
情况 386
14.4 用户定义的异常类 386
14.4.1 捕获用户定义的异常 387
14.4.2 抛出用户定义的异常 389
14.4.3 定义用户定义的异常类 392
14.5 调用者信息 394
14.6 小结 396
第15章 异步编程 397
15.1 异步编程的重要性 397
15.2 异步模式 398
15.2.1 同步调用 405
15.2.2 异步模式 406
15.2.3 基于事件的异步模式 407
15.2.4 基于任务的异步模式 408
15.3 异步编程的基础 410
15.3.1 创建任务 410
15.3.2 调用异步方法 411
15.3.3 延续任务 411
15.3.4 同步上下文 412
15.3.5 使用多个异步方法 412
15.3.6 转换异步模式 413
15.4 错误处理 414
15.4.1 异步方法的异常处理 415
15.4.2 多个异步方法的异常
处理 415
15.4.3 使用AggregateException
信息 416
15.5 取消 417
15.5.1 开始取消任务 417
15.5.2 使用框架特性取消任务 417
15.5.3 取消自定义任务 418
15.6 小结 419
第16章 反射、元数据和动态编程 420
16.1 在运行期间检查代码和
动态编程 420
16.2 自定义特性 421
16.2.1 编写自定义特性 422
16.2.2 自定义特性示例:
WhatsNewAttributes 425
16.3 反射 428
16.3.1 System.Type类 428
16.3.2 TypeView示例 430
16.3.3 Assembly类 433
16.3.4 完成WhatsNewAttributes
示例 434
16.4 为反射使用动态语言扩展 438
16.4.1 创建Calculator库 438
16.4.2 动态实例化类型 440
16.4.3 用反射API调用成员 442
16.4.4 使用动态类型调用成员 442
16.5 dynamic类型 443
16.6 DLR 448
16.7 包含DLR ScriptRuntime 449
16.8 DynamicObject和
ExpandoObject 451
16.8.1 DynamicObject 451
16.8.2 ExpandoObject 453
16.9 小结 455
第Ⅱ部分 .NET Core与Windows
Runtime
第17章 Visual Studio 2015 458
17.1 使用Visual Studio 2015 458
17.1.1 Visual Studio的版本 461
17.1.2 Visual Studio设置 461
17.2 创建项目 462
17.2.1 面向多个版本的.NET
Framework 463
17.2.2 选择项目类型 464
17.3 浏览并编写项目 469
17.3.1 构建环境:CLI和
MSBuild 469
17.3.2 Solution Explorer 470
17.3.3 使用代码编辑器 477
17.3.4 学习和理解其他窗口 481
17.3.5 排列窗口 485
17.4 构建项目 485
17.4.1 构建、编译和生成代码 486
17.4.2 调试版本和发布版本 486
17.4.3 选择配置 488
17.4.4 编辑配置 488
17.5 调试代码 490
17.5.1 设置断点 490
17.5.2 使用数据提示和调试器可
视化工具 491
17.5.3 Live Visual Tree 492
17.5.4 监视和修改变量 493
17.5.5 异常 494
17.5.6 多线程 495
17.6 重构工具 495
17.7 体系结构工具 497
17.7.1 代码地图 498
17.7.2 层关系图 499
17.8 分析应用程序 500
17.8.1 诊断工具 500
17.8.2 Concurrency Visualizer 504
17.8.3 代码分析器 505
17.8.4 Code Metrics 506
17.9 小结 506
第18章 .NET编译器平台 507
18.1 简介 507
18.2 编译器管道 509
18.3 语法分析 509
18.3.1 使用查询节点 515
18.3.2 遍历节点 517
18.4 语义分析 519
18.4.1 编译 520
18.4.2 语义模型 521
18.5 代码转换 522
18.5.1 创建新树 522
18.5.2 使用语法重写器 524
18.6 Visual Studio Code重构 529
18.6.1 VSIX包 529
18.6.2 代码重构提供程序 532
18.7 小结 537
第19章 测试 538
19.1 概述 538
19.2 使用MSTest进行单元测试 539
19.2.1 使用MSTest创建单元
测试 539
19.2.2 运行单元测试 541
19.2.3 使用MSTest预期异常 543
19.2.4 测试全部代码路径 544
19.2.5 外部依赖 544
19.2.6 Fakes Framework 547
19.2.7 IntelliTest 549
19.3 使用xUnit进行单元测试 549
19.3.1 使用xUnit和.NET Core 550
19.3.2 创建Fact属性 550
19.3.3 创建Theory属性 551
19.3.4 用dotnet工具运行单元
测试 552
19.3.5 使用Mocking库 552
19.4 UI 测试 556
19.5 Web测试 559
19.5.1 创建Web测试 560
19.5.2 运行Web测试 562
19.5.3 Web 负载测试 563
19.6 小结 565
第20章 诊断和Application Insights 566
20.1 诊断概述 566
20.2 使用EventSource跟踪 567
20.2.1 EventSource的简单用法 568
20.2.2 跟踪工具 570
20.2.3 派生自EventSource 572
20.2.4 使用注释和EventSource 574
20.2.5 创建事件清单模式 576
20.2.6 使用活动ID 578
20.3 创建自定义侦听器 581
20.4 使用Application Insights 582
20.4.1 创建通用Windows应用
程序 583
20.4.2 创建Application Insights
资源 583
20.4.3 配置Windows应用程序 584
20.4.4 使用收集器 586
20.4.5 编写自定义事件 587
20.5 小结 588
第21章 任务和并行编程 590
21.1 概述 590
21.2 Parallel类 591
21.2.1 使用Parallel.For()方法
循环 591
21.2.2 提前停止Parallel.For 594
21.2.3 Parallel.For()的初始化 595
21.2.4 使用Parallel.ForEach()
方法循环 596
21.2.5 通过Parallel.Invoke()方法
调用多个方法 597
21.3 任务 597
21.3.1 启动任务 597
21.3.2 Future——任务的结果 600
21.3.3 连续的任务 601
21.3.4 任务层次结构 602
21.3.5 从方法中返回任务 603
21.3.6 等待任务 603
21.4 取消架构 604
21.4.1 Parallel.For()方法的取消 604
21.4.2 任务的取消 605
21.5 数据流 607
21.5.1 使用动作块 607
21.5.2 源和目标数据块 608
21.5.3 连接块 609
21.6 小结 611
第22章 任务同步 612
22.1 概述 613
22.2 线程问题 613
22.2.1 争用条件 614
22.2.2 死锁 616
22.3 lock语句和线程安全 618
22.4 Interlocked类 623
22.5 Monitor类 624
22.6 SpinLock结构 625
22.7 WaitHandle基类 626
22.8 Mutex类 627
22.9 Semaphore类 628
22.10 Events类 630
22.11 Barrier类 633
22.12 ReaderWriterLockSlim类 636
22.13 Timer类 639
22.14 小结 641
第23章 文件和流 643
23.1 概述 644
23.2 管理文件系统 644
23.2.1 检查驱动器信息 645
23.2.2 使用Path类 646
23.2.3 创建文件和文件夹 647
23.2.4 访问和修改文件的属性 648
23.2.5 创建简单的编辑器 649
23.2.6 使用File执行读写操作 651
23.3 枚举文件 653
23.4 使用流处理文件 654
23.4.1 使用文件流 655
23.4.2 读取流 659
23.4.3 写入流 659
23.4.4 复制流 660
23.4.5 随机访问流 661
23.4.6 使用缓存的流 663
23.5 使用读取器和写入器 663
23.5.1 StreamReader类 663
23.5.2 StreamWriter类 664
23.5.3 读写二进制文件 665
23.6 压缩文件 666
23.6.1 使用压缩流 667
23.6.2 压缩文件 668
23.7 观察文件的更改 668
23.8 使用内存映射的文件 670
23.8.1 使用访问器创建内存映射
文件 671
23.8.2 使用流创建内存映射
文件 673
23.9 使用管道通信 675
23.9.1 创建命名管道服务器 675
23.9.2 创建命名管道客户端 677
23.9.3 创建匿名管道 677
23.10 通过Windows运行库
使用文件和流 679
23.10.1 Windows应用程序
编辑器 679
23.10.2 把Windows Runtime类
型映射为.NET类型 682
23.11 小结 684
第24章 安全性 685
24.1 概述 685
24.2 验证用户信息 686
24.2.1 使用Windows标识 686
24.2.2 Windows Principal 687
24.2.3 使用声称 688
24.3 加密数据 690
24.3.1 创建和验证签名 692
24.3.2 实现安全的数据交换 694
24.3.3 使用RSA签名和散列 697
24.3.4 实现数据的保护 700
24.4 资源的访问控制 703
24.5 使用证书发布代码 706
24.6 小结 707
第25章 网络 708
25.1 网络 708
25.2 HttpClient类 709
25.2.1 发出异步的Get请求 709
25.2.2 抛出异常 710
25.2.3 传递标题 711
25.2.4 访问内容 713
25.2.5 用HttpMessageHandler
自定义请求 713
25.2.6 使用SendAsync创建
HttpRequestMessage 714
25.2.7 使用HttpClient和Windows
Runtime 715
25.3 使用WebListener类 717
25.4 使用实用工具类 720
25.4.1 URI 721
25.4.2 IPAddress 722
25.4.3 IPHostEntry 723
25.4.4 Dns 724
25.5 使用TCP 725
25.5.1 使用TCP创建HTTP客户
程序 726
25.5.2 创建TCP侦听器 728
25.5.3 创建TCP客户端 736
25.5.4 TCP和UDP 740
25.6 使用UDP 740
25.6.1 建立UDP接收器 741
25.6.2 创建UDP发送器 742
25.6.3 使用多播 745
25.7 使用套接字 745
25.7.1 使用套接字创建侦听器 746
25.7.2 使用NetworkStream和
套接字 749
25.7.3 通过套接字使用读取器和
写入器 749
25.7.4 使用套接字实现接收器 751
25.8 小结 753
第26章 Composition 754
26.1 概述 754
26.2 Composition库的体系结构 756
26.2.1 使用特性的Composition 757
26.2.2 基于约定的部件注册 763
26.3 定义协定 766
26.4 导出部件 770
26.4.1 创建部件 770
26.4.2 使用部件的部件 776
26.4.3 导出元数据 776
26.4.4 使用元数据进行惰性
加载 778
26.5 导入部件 779
26.5.1 导入连接 782
26.5.2 部件的惰性加载 784
26.5.3 读取元数据 784
26.6 小结 786
第27章 XML和JSON 787
27.1 数据格式 787
27.1.1 XML 788
27.1.2 .NET支持的XML标准 789
27.1.3 在框架中使用XML 790
27.1.4 JSON 790
27.2 读写流格式的XML 792
27.2.1 使用XmlReader类
读取XML 793
27.2.2 使用XmlWriter类 797
27.3 在.NET中使用DOM 798
27.3.1 使用XmlDocument类
读取 799
27.3.2 遍历层次结构 799
27.3.3 使用XmlDocument插入
节点 800
27.4 使用XPathNavigator类 802
27.4.1 XPathDocument类 802
27.4.2 XPathNavigator类 803
27.4.3 XPathNodeIterator类 803
27.4.4 使用XPath导航XML 803
27.4.5 使用XPath评估 804
27.4.6 用XPath修改XML 805
27.5 在XML中序列化对象 806
27.5.1 序列化简单对象 807
27.5.2 序列化一个对象树 809
27.5.3 没有特性的序列化 811
27.6 LINQ to XML 814
27.6.1 XDocument对象 815
27.6.2 XElement对象 816
27.6.3 XNamespace对象 817
27.6.4 XComment对象 818
27.6.5 XAttribute对象 819
27.6.6 使用LINQ查询XML
文档 820
27.6.7 查询动态的XML文档 821
27.6.8 转换为对象 822
27.6.9 转换为XML 823
27.7 JSON 824
27.7.1 创建JSON 825
27.7.2 转换对象 825
27.7.3 序列化对象 827
27.8 小结 828
第28章 本地化 829
28.1 全球市场 830
28.2 System.Globalization名称
空间 830
28.2.1 Unicode问题 830
28.2.2 区域性和区域 831
28.2.3 使用区域性 835
28.2.4 排序 841
28.3 资源 843
28.3.1 资源读取器和写入器 843
28.3.2 使用资源文件生成器 844
28.3.3 通过ResourceManager
使用资源文件 845
28.3.4 System.Resources名称
空间 846
28.4 使用WPF本地化 846
28.5 使用ASP.NET Core本地化 848
28.5.1 注册本地化服务 848
28.5.2 注入本地化服务 849
28.5.3 区域性提供程序 850
28.5.4 在ASP.NET Core中使用
资源 851
28.6 本地化通用Windows平台 852
28.6.1 给UWP使用资源 853
28.6.2 使用多语言应用程序
工具集进行本地化 854
28.7 创建自定义区域性 856
28.8 小结 857
第Ⅲ部分 Windows应用程序
第29章 核心XAML 860
29.1 XAML的作用 860
29.2 XAML概述 861
29.2.1 使用WPF把元素映射到
类上 862
29.2.2 通过通用Windows应用
程序把元素映射到类上 863
29.2.3 使用自定义.NET类 864
29.2.4 把属性用作特性 865
29.2.5 把属性用作元素 866
29.2.6 使用集合和XAML 867
29.3 依赖属性 867
29.3.1 创建依赖属性 868
29.3.2 值变更回调和事件 869
29.3.3 强制值回调和WPF 870
29.4 路由事件 871
29.4.1 用于Windows 应用程序
的路由事件 871
29.4.2 WPF的冒泡和隧道 873
29.4.3 用WPF实现自定义路由
事件 875
29.5 附加属性 876
29.6 标记扩展 879
29.6.1 创建自定义标记扩展 880
29.6.2 XAML定义的标记
扩展 882
29.7 小结 882