描述
开 本: 128开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302618775丛书名: 开源.NET生态软件开发
这本专家级指南是有经验的程序员学习C#的超快方式。C#旨在帮助开发人员更快地完成更多工作,没有人比Microsoft MVP Christian Nagel更适合撰写这样一本对于现实开发有巨大帮助作用的权威指南。他从实用的角度出发,以清晰且易于理解的方式,向开发人员展示了如何为Windows和Linux平台构建.NET解决方案,如何使用Microsoft Azure服务来扩展开发,并以其他多种有意义的方式进行交互。
? 为需要新的库和工具的高级开发人员介绍了C#和.NET的众多新特性
? 揭示了使用.NET库的技巧和实用提示,包括通道、异步流和新的JSON序列化器等
? 论述了使用ASP.NET Core、gRPC、SignalR、Azure Functions和Docker开发微服务的创新方式
? 为开发Web应用程序提供了逐步指导,包括ASP.NET Core Razor、ASP.NET Core Blazor Server和Blazor WebAssembly
? 讨论了如何使用新的WinUI 3库开发Windows桌面应用程序
? 为需要新的库和工具的高级开发人员介绍了C#和.NET的众多新特性
? 揭示了使用.NET库的技巧和实用提示,包括通道、异步流和新的JSON序列化器等
? 论述了使用ASP.NET Core、gRPC、SignalR、Azure Functions和Docker开发微服务的创新方式
? 为开发Web应用程序提供了逐步指导,包括ASP.NET Core Razor、ASP.NET Core Blazor Server和Blazor WebAssembly
? 讨论了如何使用新的WinUI 3库开发Windows桌面应用程序
第 I 部分 C#语言
第1章 .NET应用程序和工具 3
1.1 从.NET Framework到.NET Core,
再到.NET 3
1.2 .NET术语 4
1.2.1 .NET SDK 4
1.2.2 .NET运行库 5
1.2.3 公共语言运行库 5
1.2.4 .NET编译平台 6
1.2.5 .NET Framework 6
1.2.6 .NET Core 6
1.2.7 .NET 7
1.2.8 .NET Standard 7
1.2.9 NuGet包 7
1.2.10 名称空间 8
1.3 .NET支持周期 9
1.4 应用程序类型和技术 9
1.4.1 数据访问 9
1.4.2 Windows应用程序 10
1.4.3 Web应用程序 10
1.4.4 服务 11
1.4.5 SignalR 11
1.4.6 Microsoft Azure 11
1.5 开发工具 13
1.5.1 .NET CLI 13
1.5.2 Visual Studio Code 13
1.5.3 Visual Studio Community 13
1.5.4 Visual Studio Professional 13
1.5.5 Visual Studio Enterprise 13
1.5.6 Visual Studio for Mac 14
1.5.7 Windows终端 14
1.5.8 WSL 2 14
1.5.9 Docker Desktop 14
1.6 使用.NET CLI 15
1.6.1 创建应用程序 15
1.6.2 语句 16
1.6.3 选择框架和语言版本 16
1.6.4 构建应用程序 17
1.6.5 运行应用程序 18
1.6.6 创建Web应用程序 18
1.6.7 发布应用程序 19
1.6.8 自包含部署 19
1.6.9 创建单个可执行文件 20
1.6.10 readytorun 20
1.6.11 剪裁 21
1.7 小结 21
第2章 核心C# 23
2.1 C#基础 24
2.1.1 语句 24
2.1.2 变量 25
2.1.3 命令行实参 25
2.1.4 变量的作用域 26
2.1.5 常量 27
2.1.6 在语句中使用方法和类型 28
2.2 可空类型 28
2.2.1 可空值类型 29
2.2.2 可空引用类型 29
2.3 使用预定义数据类型 31
2.3.1 整型 31
2.3.2 BigInteger 32
2.3.3 本机整数类型 32
2.3.4 数字分隔符 32
2.3.5 二进制值 32
2.3.6 浮点类型 33
2.3.7 bool类型 33
2.3.8 字符类型 34
2.3.9 数字的字面值 34
2.3.10 object类型 34
2.4 程序流控制 35
2.4.1 if语句 35
2.4.2 is运算符的模式匹配 36
2.4.3 switch语句 36
2.4.4 switch语句的模式匹配 37
2.4.5 switch表达式 38
2.4.6 for循环 39
2.4.7 while循环 41
2.4.8 do…while循环 41
2.4.9 foreach循环 41
2.4.10 退出循环 42
2.5 名称空间 42
2.5.1 using语句 43
2.5.2 名称空间的别名 43
2.6 使用字符串 43
2.6.1 使用StringBuilder 43
2.6.2 字符串插值 44
2.6.3 FormattableString 44
2.6.4 字符串格式 45
2.6.5 verbatim字符串 45
2.6.6 字符串的范围 46
2.7 注释 46
2.7.1 源文件中的内部注释 46
2.7.2 XML文档 47
2.8 C#预处理器指令 48
2.8.1 #define和#undef 48
2.8.2 #if、#elif、#else和#endif 49
2.8.3 #warning和#error 50
2.8.4 #region和#endregion 50
2.8.5 #line 50
2.8.6 #pragma 51
2.8.7 #nullable 51
2.9 C#编程准则 51
2.9.1 关于标识符的规则 51
2.9.2 用法约定 52
2.9.3 命名约定 52
2.9.4 属性和方法的使用 54
2.9.5 字段的使用 54
2.10 小结 55
第3章 类、记录、结构和元组 56
3.1 创建及使用类型 57
3.2 按值传递和按引用传递 57
3.3 类 59
3.3.1 字段 60
3.3.2 只读字段 60
3.3.3 属性 61
3.3.4 方法 64
3.3.5 构造函数 68
3.3.6 局部函数 70
3.3.7 泛型方法 71
3.3.8 扩展方法 71
3.3.9 匿名类型 72
3.4 记录 73
3.4.1 不可变类型 73
3.4.2 名义记录 73
3.4.3 位置记录 73
3.4.4 记录的相等性比较 74
3.4.5 with表达式 74
3.5 结构 75
3.6 枚举类型 76
3.7 ref、in和out 78
3.7.1 ref参数 78
3.7.2 in参数 79
3.7.3 ref return 80
3.7.4 out参数 81
3.8 元组 81
3.8.1 声明和初始化元组 82
3.8.2 元组解构 83
3.8.3 元组的返回 83
3.9 ValueTuple 83
3.10 解构 84
3.11 模式匹配 85
3.11.1 使用元组进行模式匹配 85
3.11.2 属性模式 86
3.12 分部类型 87
3.13 小结 89
第4章 C#面向对象编程 90
4.1 面向对象 90
4.2 类的继承 91
4.2.1 虚方法 91
4.2.2 隐藏方法 94
4.2.3 调用方法的基类版本 95
4.2.4 抽象类和抽象方法 96
4.2.5 密封类和密封方法 96
4.2.6 派生类的构造函数 97
4.3 修饰符 99
4.3.1 访问修饰符 99
4.3.2 其他修饰符 100
4.4 记录的继承 100
4.5 使用接口 101
4.5.1 预定义接口 102
4.5.2 使用接口进行依赖注入 104
4.5.3 显式和隐式实现的接口 105
4.5.4 对比接口和类 106
4.5.5 默认接口方法 106
4.6 泛型 109
4.7 小结 112
第5章 运算符和类型强制转换 113
5.1 运算符 113
5.1.1 复合赋值运算符 114
5.1.2 条件运算符 115
5.1.3 checked和unchecked运算符 115
5.1.4 is和as运算符 116
5.1.5 sizeof运算符 117
5.1.6 typeof运算符 118
5.1.7 nameof 运算符 118
5.1.8 索引器 118
5.1.9 空合并运算符和空合并赋值
运算符 119
5.1.10 空值条件运算符 119
5.2 使用二进制运算符 121
5.2.1 位的移动 122
5.2.2 有符号数和无符号数 123
5.3 类型的安全性 125
5.3.1 类型转换 125
5.3.2 装箱和拆箱 128
5.4 运算符重载 128
5.4.1 运算符的工作方式 129
5.4.2 Vector类型的运算符重载 130
5.5 比较对象的相等性 132
5.6 实现自定义的索引器 134
5.7 用户定义的转换 136
5.7.1 实现用户定义的类型强制转换 136
5.7.2 多重类型强制转换 142
5.8 小结 145
第6章 数组 147
6.1 相同类型的多个对象 147
6.2 简单数组 148
6.2.1 数组的声明和初始化 148
6.2.2 访问数组元素 149
6.2.3 使用引用类型 149
6.3 多维数组 150
6.4 锯齿数组 151
6.5 Array类 152
6.5.1 创建数组 152
6.5.2 复制数组 153
6.5.3 排序 154
6.6 数组作为参数 156
6.7 枚举器 157
6.7.1 IEnumerator接口 157
6.7.2 foreach语句 158
6.7.3 yield语句 158
6.8 对数组使用Span 160
6.8.1 创建切片 160
6.8.2 使用Span改变值 161
6.8.3 只读的Span 162
6.9 索引和范围 163
6.9.1 索引和hat运算符 163
6.9.2 范围 163
6.9.3 高效地修改数组内容 164
6.9.4 自定义集合的索引和范围 165
6.10 数组池 165
6.10.1 创建数组池 165
6.10.2 从池中租用内存 166
6.10.3 将内存返回给池 166
6.11 BitArray 167
6.12 小结 169
第7章 委托、lambda表达式和事件 171
7.1 引用方法 171
7.2 委托 172
7.2.1 声明委托 172
7.2.2 使用委托 173
7.2.3 将委托传递给方法 175
7.2.4 Action和Func委托 176
7.2.5 多播委托 177
7.2.6 匿名方法 179
7.3 lambda表达式 180
7.3.1 参数 181
7.3.2 多行代码 181
7.3.3 闭包 181
7.4 事件 182
7.4.1 事件发布程序 183
7.4.2 事件侦听器 184
7.5 小结 185
第8章 集合 187
8.1 概述 187
8.2 集合接口和类型 188
8.3 列表 188
8.3.1 创建列表 189
8.3.2 集合初始化器 190
8.3.3 添加元素 190
8.3.4 插入元素 191
8.3.5 访问元素 191
8.3.6 删除元素 192
8.3.7 搜索 192
8.3.8 排序 194
8.3.9 只读集合 195
8.3.10 队列 195
8.4 栈 199
8.5 链表 200
8.6 有序列表 202
8.7 字典 203
8.7.1 字典初始化器 204
8.7.2 键的类型 204
8.7.3 字典示例 206
8.7.4 Lookup类 209
8.7.5 有序字典 209
8.8 集 210
8.9 性能 212
8.10 不变的集合 213
8.10.1 使用构建器和不变的集合 215
8.10.2 不变集合类型和接口 215
8.10.3 使用LINQ和不变的数组 216
8.11 小结 216
第9章 LINQ 217
9.1 LINQ概述 217
9.1.1 列表和实体 218
9.1.2 LINQ查询 220
9.1.3 扩展方法 220
9.1.4 推迟查询的执行 221
9.2 标准的查询操作符 223
9.2.1 筛选 224
9.2.2 用索引筛选 225
9.2.3 类型筛选 226
9.2.4 复合的from子句 226
9.2.5 排序 227
9.2.6 分组 229
9.2.7 LINQ 查询中的变量 230
9.2.8 对嵌套的对象分组 231
9.2.9 内连接 232
9.2.10 左外连接 235
9.2.11 组连接 236
9.2.12 集操作 239
9.2.13 合并 240
9.2.14 分区 241
9.2.15 聚合操作符 242
9.2.16 转换操作符 243
9.2.17 生成操作符 245
9.3 并行LINQ 246
9.3.1 并行查询 246
9.3.2 取消 247
9.4 表达式树 248
9.5 LINQ提供程序 250
9.6 小结 251
第10章 错误和异常 253
10.1 处理错误 253
10.2 预定义的异常类 254
10.3 捕获异常 255
10.3.1 异常和性能 257
10.3.2 实现多个catch块 258
10.3.3 捕获其他代码中的异常 260
10.3.4 System.Exception属性 261
10.3.5 异常过滤器 261
10.3.6 重新抛出异常 262
10.3.7 没有处理异常时发生的情况 266
10.4 用户定义的异常类 266
10.4.1 捕获用户定义的异常 267
10.4.2 抛出用户定义的异常 269
10.4.3 定义用户定义的异常类 272
10.5 调用者信息 273
10.6 小结 275
第11章 任务和异步编程 277
11.1 异步编程的重要性 277
11.2 基于任务的异步模式 278
11.3 任务 280
11.3.1 创建任务 280
11.3.2 调用异步方法 281
11.3.3 使用Awaiter 282
11.3.4 延续任务 282
11.3.5 同步上下文 283
11.3.6 使用多个异步方法 283
11.3.7 使用ValueTasks 284
11.4 错误处理 285
11.4.1 异步方法的异常处理 286
15.4.2 多个异步方法的异常处理 286
11.4.3 使用AggregateException
信息 287
11.5 取消异步方法 288
11.6 异步流 289
11.7 异步与Windows应用程序 290
11.7.1 配置await 291
11.7.2 切换到UI线程 292
11.7.3 使用IAsyncOperation 293
11.7.4 避免阻塞情况 293
11.8 小结 294
第12章 反射、元数据和源代码生成器 295
12.1 在运行期间检查代码和动态
编程 295
12.2 自定义特性 296
12.2.1 编写自定义特性 296
12.2.2 自定义特性示例:
WhatsNewAttributes 299
12.3 使用反射 301
12.3.1 System.Type类 301
12.3.2 TypeView示例 303
12.3.3 Assembly类 305
12.3.4 完成WhatsNewAttributes
示例 306
12.4 为反射使用动态语言扩展 309
12.4.1 创建Calculator库 309
12.4.2 动态实例化类型 310
12.4.3 用Reflection API调用成员 310
12.4.4 使用动态类型调用成员 311
12.5 ExpandoObject 312
12.6 源代码生成器 314
12.6.1 Hello, World源代码生成器 314
12.6.2 使用分部方法的源代码
生成器 316
12.7 小结 320
第13章 托管和非托管内存 321
13.1 内存 321
13.2 后台内存管理 322
13.2.1 值数据类型 322
13.2.2 引用数据类型 324
13.2.3 垃圾收集 326
13.3 强引用和弱引用 328
13.4 处理非托管的资源 329
13.4.1 析构函数或终结器 329
13.4.2 IDisposable和IAsyncDisposable
接口 330
13.4.3 using语句和using声明 331
13.4.4 实现IDisposable接口和析构
函数 332
13.4.5 IDisposable和终结器的规则 333
13.5 不安全的代码 333
13.5.1 用指针直接访问内存 334
13.5.2 用unsafe关键字编写不安全
的代码 334
13.5.3 指针的语法 335
13.5.4 将指针强制转换为整数类型 337
13.5.5 指针类型之间的强制转换 337
13.5.6 void指针 337
13.5.7 指针算术的运算 338
13.5.8 sizeof运算符 339
13.5.9 结构指针:指针成员访问
运算符 339
13.5.10 类成员的指针 340
13.5.11 指针示例:PointerPlayground 341
13.5.12 函数指针 344
13.5.13 使用指针优化性能 345
13.6 Span 348
13.6.1 Span引用托管堆 349
13.6.2 Span引用栈 349
13.6.3 Span引用本机堆 350
13.6.4 Span扩展方法 351
13.7 平台调用 351
13.7.1 调用本机Windows API 352
13.7.2 调用Linux本机API 354
13.7.3 使用库调用本机API 356
13.8 小结 356
第 II 部分 库
第14章 库、程序集、包和NuGet 359
14.1 库的地狱 359
14.2 程序集 361
14.3 创建和使用库 362
14.3.1 .NET 标准 363
14.3.2 创建.NET标准库 363
14.3.3 解决方案文件 364
14.3.4 引用项目 364
14.3.5 引用NuGet包 365
14.3.6 NuGet的来源 366
14.4 创建NuGet包 367
14.4.1 NuGet包和命令行 367
14.4.2 支持多个平台 368
14.4.3 NuGet包与Visual Studio 370
14.5 模块初始化器 371
14.6 小结 372
第15章 依赖注入和配置 373
15.1 依赖注入的概念 373
15.2 使用.NET DI容器 374
15.3 使用Host类 376
15.4 服务的生存期 376
15.4.1 使用单例和临时服务 378
15.4.2 使用Scoped服务 380
15.4.3 使用自定义工厂 383
15.5 使用选项初始化服务 384
15.6 使用配置文件 385
15.7 .NET应用程序的配置 387
15.7.1 使用IConfiguration 387
15.7.2 读取强类型的值 388
15.7.3 配置源 388
15.7.4 生产和开发设置 389
15.7.5 用户秘密 390
15.8 Azure App Configuration 391
15.8.1 创建Azure App Configuration 391
15.8.2 在开发环境中使用
Azure App Configuration 392
15.8.3 动态配置 394
15.8.4 使用Azure App Configuration
的生产和准备设置 395
15.8.5 特性标志 395
15.8.6 使用Azure Key Vault 397
15.9 小结 398
第16章 诊断和指标 399
16.1 诊断概述 399
16.2 日志 401
16.2.1 配置提供程序 403
16.2.2 过滤 405
16.2.3 配置日志记录 406
16.2.4 使用OpenTelemetry进行
日志记录和跟踪 406
16.2.5 更多日志提供程序 408
16.3 指标 408
16.3.1 EventSource类 409
16.3.2 指标计数器 409
16.3.3 使用MetricsSampleSource 411
16.3.4 使用.NET CLI监控指标 412
16.4 使用Visual Studio App Center
进行分析 413
16.5 Application Insights 416
16.6 小结 417
第17章 并行编程 419
17.1 概述 420
17.2 Parallel类 421
17.2.1 使用Parallel.For()方法循环 421
17.2.2 提前中断Parallel.For() 423
17.2.3 Parallel.For()方法的初始化 424
17.2.4 使用Parallel.ForEach()方法
循环 425
17.2.5 通过Parallel.Invoke()方法调用
多个方法 425
17.3 任务 426
17.3.1 启动任务 426
17.3.2 任务的结果 429
17.3.3 连续的任务 429
17.3.4 任务层次结构 430
17.3.5 从方法中返回任务 431
17.3.6 等待任务 431
17.3.7 ValueTask 431
17.4 取消架构 433
17.4.1 Parallel.For()方法的取消 433
17.4.2 任务的取消 434
17.5 通道 436
17.5.1 创建有界和无界通道 436
17.5.2 写入通道 437
17.5.3 从通道读取数据 438
17.5.4 通道的异步流 438
17.6 Timer类 439
17.6.1 使用Timer类 439
17.6.2 WinUI DispatcherTimer 439
17.7 线程问题 441
17.7.1 争用条件 441
17.7.2 死锁 444
17.8 Interlocked类 445
17.9 Monitor类 446
17.10 SpinLock结构 447
17.11 WaitHandle类 447
17.12 Mutex类 447
17.13 Semaphore类 448
17.14 Events类 450
17.15 Barrier类 453
17.16 ReaderWriterLockSlim类 456
17.17 lock和await 458
17.18 小结 461
第18章 文件和流 463
18.1 概述 464
18.2 管理文件系统 464
18.2.1 检查驱动器信息 464
18.2.2 使用Path类 465
18.2.3 创建文件和文件夹 466
18.2.4 访问和修改文件属性 467
18.2.5 使用File执行读写操作 469
18.3 枚举文件 470
18.4 使用流 471
18.4.1 使用文件流 472
18.4.2 读取流 475
18.4.3 写入流 476
18.4.4 复制流 476
18.4.5 随机访问流 477
18.4.6 使用缓存的流 479
18.5 使用读取器和写入器 479
18.5.1 StreamReader类 480
18.5.2 StreamWriter类 481
18.5.3 读写二进制文件 481
18.6 压缩文件 482
18.6.1 使用压缩流 482
18.6.2 使用Brotli 483
18.6.3 压缩文件 484
18.7 观察文件的更改 484
18.8 JSON序列化 485
18.8.1 JSON序列化 486
18.8.2 JSON反序列化 488
18.8.3 使用JsonDocument 489
18.8.4 JSON读取器 490
18.8.5 JSON写入器 490
18.9 通过Windows运行库使用
文件和流 491
18.9.1 Windows App编辑器 492
18.9.2 把Windows Runtime类型
映射为.NET类型 494
18.10 小结 496
第19章 网络 497
19.1 概述 497
19.2 使用实用工具类 498
19.2.1 URI 498
19.2.2 IPAddress 499
19.2.3 IPHostEntry 501
19.2.4 DNS 501
19.2.5 配置套接字 502
19.3 使用套接字 503
19.3.1 使用套接字的TCP Echo示例 503
19.3.2 创建侦听器 505
19.3.3 使用管道进行通信 506
19.3.4 实现接收器 508
19.4 使用TCP类 509
19.4.1 创建TCP侦听器 510
19.4.2 创建TCP客户端 512
19.5 使用UDP 513
19.5.1 建立UDP接收器 513
19.5.2 创建UDP发送器 515
19.5.3 使用多播 517
19.6 使用Web服务器 518
19.6.1 配置Kestrel 519
19.6.2 Startup 520
19.6.3 HTTP头 521
19.7 HttpClient类 523
19.7.1 发出异步的Get请求 524
19.7.2 抛出异常 525
19.7.3 创建HttpRequestMessage 526
19.7.4 传递头 526
19.7.5 访问内容 528
19.7.6 用HttpMessageHandler
自定义请求 528
19.8 HttpClient工厂 530
19.8.1 类型化的客户端 530
19.8.2 命名的客户端 530
19.8.3 弹性HTTP请求 531
19.9 小结 532
第20章 安全性 535
20.1 安全性的重要方面 535
20.2 验证用户信息 536
20.2.1 使用Microsoft标识平台 536
20.2.2 使用Microsoft.Identity.Client 536
20.2.3 在Web应用程序中使用身份
验证和授权 540
20.3 加密数据 542
20.3.1 获得X.509证书 545
20.3.2 创建和验证签名 547
20.3.3 实现安全的数据交换 549
20.4 确保Web安全 552
20.4.1 编码 552
20.4.2 防范SQL注入 554
20.4.3 防范跨站点请求伪造 555
20.5 小结 557
第21章 Entity Framework Core 559
21.1 Entity Framework简介 560
21.1.1 数据库提供程序 560
21.1.2 创建Azure SQL数据库 560
21.1.3 创建模型 561
21.1.4 创建上下文 562
21.1.5 约定、注释和流式API 563
21.1.6 使用DI提供程序配置上下文 563
21.1.7 创建数据库 564
21.1.8 删除数据库 565
21.1.9 写入数据库 565
21.1.10 读取数据库 566
21.1.11 更新类 567
21.1.12 更新记录 567
21.1.13 删除记录 568
21.1.14 日志和指标 568
21.2 创建模型 569
21.2.1 创建关系 569
21.2.2 使用流式API来映射定义 570
21.2.3 使用自包含类型的配置 571
21.2.4 映射到字段 573
21.2.5 使用影子属性 574
21.3 在数据库中搭建模型 576
21.4 迁移 577
21.4.1 实现
IDesignTimeDbContextFactory 577
21.4.2 创建迁移 578
21.4.3 以编程方式应用迁移 580
21.4.4 应用迁移的其他方法 581
21.5 使用查询 581
21.5.1 基本查询 582
21.5.2 异步流 584
21.5.3 原始SQL查询 584
21.5.4 已编译查询 584
21.5.5 全局查询过滤器 586
21.5.6 EF.Functions 586
21.6 加载相关数据 587
21.6.1 预先加载相关数据 587
21.6.2 使用带过滤条件的Include()的
预先加载 588
21.6.3 显式加载相关数据 588
21.6.4 延迟加载 590
21.7 使用关系 591
21.7.1 多对多关系 591
21.7.2 表的拆分 594
21.7.3 拥有的实体 595
21.7.4 每个层次结构一张表 597
21.8 保存数据 599
21.8.1 用关系添加对象 600
21.8.2 对象的跟踪 601
21.8.3 更新对象 602
21.8.4 更新未跟踪的对象 603
21.9 冲突的处理 604
21.9.1 后一个更改获胜 604
21.9.2 个更改获胜 606
21.10 使用事务 608
21.10.1 使用隐式的事务 608
21.10.2 创建显式的事务 609
21.10.3 使用环境事务 610
21.11 使用Azure Cosmos DB 611
21.12 小结 616
第22章 本地化 617
22.1 全球市场 617
22.2 System.Globalization名称空间 618
22.2.1 Unicode问题 618
22.2.2 区域性和区域 619
22.2.3 使用区域性 622
22.2.4 排序 627
22.3 资源 629
22.3.1 资源读取器和写入器 629
22.3.2 通过ResourceManager使用
资源文件 630
22.4 使用ASP.NET Core本地化 631
22.4.1 注册本地化服务 631
22.4.2 配置中间件 631
22.4.3 ASP.NET Core区域性提供
程序 632
22.4.4 在ASP.NET Core中使用
区域性 633
22.4.5 在ASP.NET Core中使用
资源 634
22.4.6 使用数据注释进行本地化 635
22.5 本地化WinUI 636
22.5.1 使用MRT ResourceLoader 637
22.5.2 使用MRT ResourceManager 637
22.5.3 使用ResourceContext修改
资源 638
22.6 小结 639
第23章 测试 641
23.1 概述 641
23.2 单元测试 642
23.2.1 创建单元测试 642
23.2.2 运行单元测试 643
23.2.3 实现复杂的方法 644
23.2.4 预期异常 645
23.2.5 测试全部代码路径 645
23.2.6 代码覆盖率 646
23.2.7 外部依赖 647
23.3 使用模拟库 650
23.4 ASP.NET Core集成测试 654
23.5 小结 655
第 III 部分 Web应用程序和服务
第24章 ASP.NET Core 659
24.1 Web技术 659
24.1.1 HTML 660
24.1.2 CSS 660
24.1.3 JavaScript和TypeScript 660
24.1.4 脚本库 661
24.1.5 WebAssembly 661
24.2 创建ASP.NET Core Web项目 661
24.2.1 宿主服务器 663
24.2.2 启动 663
24.2.3 示例应用程序 665
24.3 添加客户端内容 666
24.4 创建自定义中间件 668
24.5 端点路由 670
24.5.1 定义路由 670
24.5.2 路由约束 671
24.6 请求和响应 672
24.6.1 请求头 673
24.6.2 查询参数 675
24.6.3 表单数据 675
24.6.4 cookie 676
24.6.5 发送JSON 677
24.7 会话状态 677
24.8 健康检查 679
24.9 部署 682
24.10 小结 683
第25章 服务 685
25.1 理解今天的服务 685
25.2 使用ASP.NET Core创建REST
服务 686
25.2.1 定义模型 687
25.2.2 创建服务 687
25.2.3 创建控制器 690
25.2.4 测试REST API 693
25.2.5 REST结果和状态码 694
25.3 创建.NET客户端 694
25.3.1 发送GET请求 696
25.3.2 发送POST请求 698
25.3.3 发送PUT请求 698
25.3.4 发送DELETE请求 699
25.4 使用EF Core和服务 700
25.5 使用Azure AD B2C进行身份
验证和授权 703
25.5.1 创建和配置服务 706
25.5.2 在客户端应用程序中添加
身份验证 707
25.6 通过gRPC实现和使用服务 709
25.6.1 创建一个gRPC项目 709
25.6.2 使用Protobuf定义契约 710
25.6.3 实现一个gRPC服务 712
25.6.4 实现一个gRPC客户端 713
25.6.5 gRPC的流传输 715
25.7 使用Azure Functions 717
25.7.1 创建一个Azure Functions
项目 717
25.7.2 添加HTTP Trigger函数 719
25.8 更多Azure服务 720
25.9 小结 720
第26章 Razor页面和MVC 723
26.1 为Razor页面和MVC建立
服务 723
26.1.1 创建Razor页面项目 724
26.1.2 理解Razor语法 725
26.2 Razor页面 726
26.2.1 布局 727
26.2.2 在视图间传递数据 728
26.2.3 渲染节 728
26.2.4 带参数的路由 729
26.2.5 Razor库和区域 731
26.2.6 注入服务 732
26.2.7 返回结果 732
26.2.8 模型绑定 733
26.2.9 使用HTML Helper 733
26.2.10 使用Tag Helper 735
26.2.11 验证用户输入 736
26.2.12 创建自定义Tag Helper 736
26.2.13 用Tag Helper创建元素 738
26.2.14 视图组件 741
26.3 ASP.NET Core MVC 744
26.3.1 启动MVC 744
26.3.2 MVC路由 745
26.3.3 控制器 745
26.3.4 Razor视图 746
26.3.5 标识UI 748
26.4 小结 749
第27章 Blazor 751
27.1 Blazor Server和
Blazor Assembly 751
27.1.1 Blazor Server 752
27.1.2 WebAssembly 752
27.1.3 BlazorWebAssembly 753
27.2 创建Blazor Server Web
应用程序 753
27.2.1 启动Blazor Server 754
27.2.2 Blazor布局 755
27.2.3 导航 756
27.2.4 Counter组件 757
27.2.5 FetchData组件 758
27.3 BlazorWebAssembly 759
27.3.1 启动BlazorWebAssembly 760
27.3.2 在BlazorWebAssembly中
注入HttpClient 761
27.3.3 使用渐进式Web应用程序 762
27.4 Razor组件 763
27.4.1 理解组件的参数 763
27.4.2 注入服务 764
27.4.3 使用事件回调 765
27.4.4 通过代码更新UI 767
27.4.5 双向绑定 767
27.4.6 级联参数 768
27.4.7 使用模板化组件 769
27.4.8 使用内置组件 770
27.5 小结 771
第28章 SignalR 773
28.1 概述 773
28.2 使用SignalR创建一个简单的
聊天 774
28.2.1 创建中心 774
28.2.2 使用HTML和JavaScript创建
客户端 776
28.2.3 创建SignalR .NET客户端 778
28.3 连接分组 781
28.3.1 使用组扩展中心 781
28.3.2 使用组扩展Windows客户端
应用程序 783
28.4 使用SignalR进行流传输 785
28.5 小结 787
第 IV 部分 应用程序
第29章 Windows应用程序 791
29.1 Windows应用程序简介 791
29.1.1 Windows运行库 793
29.1.2 Hello, Windows 793
29.1.3 应用程序清单文件 794
29.1.4 应用程序启动 795
29.1.5 主窗口 796
29.2 XAML 797
29.2.1 将元素映射到类 798
29.2.2 通过XAML使用自定义的
.NET类 799
29.2.3 将属性用作特性 800
29.2.4 将属性用作元素 800
29.2.5 依赖属性 801
29.2.6 创建依赖属性 802
29.2.7 值变更回调和事件 802
29.2.8 路由事件 803
29.2.9 附加属性 804
29.2.10 标记扩展 807
29.2.11 自定义标记扩展 807
29.3 使用控件 808
29.3.1 派生自FrameworkElement的
UI元素 809
29.3.2 Control派生的控件 811
29.3.3 范围控件 817
29.3.4 内容控件 818
29.3.5 按钮 819
29.3.6 项控件 821
29.3.7 Flyout控件 821
29.4 使用数据绑定 821
29.4.1 用INotifyPropertyChanged
更改通知 822
29.4.2 创建图书列表 824
29.4.3 列表绑定 824
29.4.4 把事件绑定到方法 825
29.4.5 使用数据模板和数据模板
选择器 826
29.4.6 显示列表和详细信息 827
29.4.7 绑定简单对象 828
29.4.8 值的转换 829
29.5 实现导航 830
29.5.1 Hub 831
29.5.2 TabView 832
29.5.3 NavigationView 833
29.6 实现布局面板 835
29.6.1 StackPanel 836
29.6.2 Grid 836
29.6.3 VariableSizedWrapGrid 837
29.6.4 RelativePanel 839
29.6.5 自适应触发器 840
29.6.6 延迟加载 842
29.7 小结 843
第30章 模式和XAML应用程序 845
30.1 使用 MVVM的原因 845
30.2 定义MVVM模式 846
30.3 示例解决方案 847
30.4 模型 848
30.5 服务 850
30.6 视图模型 852
30.6.1 IEditableObject 854
30.6.2 视图模型的具体实现 855
30.6.3 命令 857
30.6.4 服务、ViewModel和依赖
注入 858
30.7 视图 859
30.7.1 从视图模型中打开对话框 861
30.7.2 页面之间的导航 862
30.8 使用事件传递消息 865
30.9 小结 866
第31章 样式化Windows应用程序 867
31.1 样式设置 867
31.2 形状 868
31.3 几何图形 870
31.3.1 使用段的几何图形 870
31.3.2 使用路径标记的几何图形 871
31.4 变换 872
31.4.1 缩放 872
31.4.2 平移 872
31.4.3 旋转 873
31.4.4 倾斜 873
31.4.5 组合变换和复合变换 873
31.4.6 使用矩阵的变换 873
31.5 笔刷 874
31.5.1 SolidColorBrush 874
31.5.2 渐变笔刷 875
31.5.3 ImageBrush 875
31.5.4 AcrylicBrush 876
31.6 样式和资源 876
31.6.1 样式 877
31.6.2 资源层次结构 878
31.6.3 主题资源 879
31.7 模板 881
31.7.1 控件模板 881
31.7.2 样式化ListView 883
31.7.3 项容器的样式 885
31.7.4 项面板 886
31.8 动画 887
31.8.1 时间轴 887
31.8.2 缓动函数 888
31.8.3 关键帧动画 893
31.8.4 过渡 894
31.9 可视化状态管理器 896
31.9.1 用控件模板预定义状态 897
31.9.2 定义自定义状态 898
31.9.3 设置自定义的状态 899
31.10 小结 899
.NET早在2000年就被正式宣布,但直到现在,它依然活跃在开发人员的视野中。自从.NET变得开源,不只能够在Windows上使用,还能够在Linux平台上使用之后,就开始受到越来越多开发人员的青睐。通过使用WebAssembly标准,.NET还可以在客户端的浏览器中运行,且不需要安装插件。
随着C#和.NET新的增强功能的出现,现在关注点不只是提高性能,也在于提高易用程度。.NET成为越来越多新开发人员的选择。
对于有长时间开发经验的开发人员,C#也很有吸引力。每一年,Stack Overflow都会调查开发人员喜欢、不喜欢和想要的编程语言和框架。多年来,C#一直在开发人员喜欢的前10名编程语言榜单内。ASP.NET Core现在是开发人员喜欢的框架。.NET Core在喜欢的其他框架/库/工具分类中排名。详细信息可以参见网址0-5。
使用C#和ASP.NET Core时,可以创建在Windows、Linux和macOS上运行的Web应用程序和服务(包括微服务)。可以使用Windows Runtime,通过C#、XAML和.NET创建原生Windows应用程序。可以创建在ASP.NET Core、Windows应用程序和.NET MAUI之间共享的库,还可以创建传统的Windows Forms和WPF应用程序。
本书的大部分示例可以在Windows或Linux系统上运行。Windows应用程序示例是例外,它们只能运行在Windows平台上。可以使用Visual Studio、Visual Studio Code或Visual Studio for Mac作为开发环境,只有Windows应用程序示例需要使用Visual Studio。
0.1 .NET Core的世界
.NET有很长的历史,个版本发布于2002年。新一代.NET完全重写了原来的.NET,它还很年轻(.NET Core 1.0发布于2016年)。近来,旧的.NET版本的许多特性被添加到.NET Core中,使得迁移过程更加轻松。
创建新的应用程序时,没有理由不使用新的.NET版本。是应该继续使用老版本的.NET,还是迁移到新的.NET,这要取决于应用程序使用的特性,迁移的难度,以及迁移应用程序能够带来什么好处。对于不同的应用程序,好的选择可能不一样。
新的.NET为创建Windows和Web应用程序及服务提供了简单的方式。可以创建在Kubernetes集群的Docker容器中运行的微服务;创建Web应用程序;使用新的OpenTelemetry标准,以独立于供应商的方式分析分布式跟踪;创建返回HTML、JavaScript和CSS的Web应用程序;以及创建返回HTML、JavaScript和.NET二进制文件的Web应用程序,这些.NET二进制文件通过使用WebAssembly,以安全的、标准的方式在客户端的浏览器中运行。可以使用WPF和Windows Forms,以传统的方式创建Windows应用程序,也可以使用现代XAML特性和控件,它们支持WinUI以及使用.NET MAUI的移动应用程序的流畅设计。
.NET使用现代模式。其核心服务(如ASP.NET Core和EF Core)中内置了依赖注入,这不只让单元测试变得更加简单,也使得开发人员更容易增强和修改这些技术的特性。
.NET能够在多个平台上运行。除了Windows和macOS,还支持许多Linux环境,如Alpine、CentOS、Debian、Fedora、openSUSE、Red Hat、SLES和Ubuntu。
.NET 开源(网址0-6)且免费可用。你可以找到C#编译器的会议记录(网址0-7)、C#编译器的源代码(网址0-8)、.NET运行库和库(网址0-9)以及支持Razor页面、Blazor和SignalR的ASP.NET Core(网址0-10)。
下面总结了新的.NET的一些特性:
● .NET是开源的。
● .NET使用现代模式。
● .NET支持在多个平台上开发。
● ASP.NET Core可以在Windows和Linux上运行。
0.2 C#的世界
C#在2002年发布时,是一种用于.NET Framework的开发语言。C#的设计思想来自C 、Java和Pascal。Anders Hejlsberg从Borland来到微软公司,带来了开发Delphi语言的经验。Hejlsberg在微软公司开发了Java的Microsoft版本J ,之后创建了C#。
注意:
Anders Hejlsberg现在已经转移到TypeScript(而他仍在影响C#), Mads Torgersen是C#的项目负责人。C#的改进可以在网址0-7上公开讨论。在这里,可以阅读C#语言建议和会议记录,也可以提交自己的C#建议。
C#一开始不仅作为一种面向对象的通用编程语言,也是一种基于组件的编程语言,支持属性、事件、特性(注解)和构建程序集(包括元数据的二进制文件)。
随着时间的推移,C#增强了泛型、语言集成查询(Language Integrated Query,LINQ)、lambda表达式、动态特性和更简单的异步编程。C#编程语言并不简单,它提供了很多功能,而且实际使用的功能在不断进化。因此,C#不仅是面向对象或基于组件的语言,它还包括函数式编程的理念,开发各种应用程序的通用语言会实际应用这些理念。
如今,每年都会发布一个新的C#版本。C# 8添加了可空引用类型,C# 9添加了记录等。C# 10在2021年随着.NET 6发布,C# 11将在2022年随着.NET 7发布。由于如今变化飞快,请查看本书的GitHub存储库来获得持续更新。
0.3 C#的新特性
每一年,新的 C#版本都会发布,提供许多新的特性。版本包含许多特性,例如使用可空引用类型来减少NullableReferenceException类型的异常,让编译器提供更多帮助;例如提高生产效率的特性,如索引和范围;例如使得switch语句看起来经典的switch表达式;例如使用声明的特性;例如对模式匹配的增强。语句可以减少小型应用程序和记录的源代码行数。记录是类,只不过编译器会为它的相等性比较、解构和with表达式创建样板代码。代码生成器允许在编译器运行时自动创建代码。本书将讨论所有这些新特性。
0.4 ASP.NET Core中的新特性
ASP.NET Core现在包含一种新的创建Web应用程序的技术:Blazor Server和Blazor WebAssembly。Blazor提供了一种全栈选项,可以使用C#为客户端和服务器编写代码。在Blazor Server中,你创建的包含HTML和C#代码的Razor组件在服务器端运行。在Blazor WebAssembly中,使用C#和HTML编写的Razor组件通过HTML 5标准WebAssembly在客户端运行。WebAssembly允许在所有现代Web浏览器中运行二进制代码。
对于创建服务,现在可以在ASP.NET Core中使用gRPC来实现服务之间的二进制通信。对于服务与服务之间的通信,结合使用ASP.NET Core与gRPC可以降低需要的带宽,并且在需要进行大量数据传输时,还可以降低CPU和内存使用率。
0.5 Windows的新特性
对于为Windows开发应用程序,有一种新技术将通用Windows平台(Universal Windows Platform,UWP)和桌面应用程序的特性结合了起来,即WinUI 3。WinUI是Windows 10应用程序的原生UI平台。借助WinUI,可以使用包含已编译绑定的现代XAML代码来创建桌面应用程序。Microsoft的流畅设计系统中也提供了新的控件。不同于之前UWP平台随着Windows Runtime而交付,现在这些控件是独立于Windows 10版本来开发的,这就允许在Windows 10的1809版本及更高版本中使用控件。WinUI的路线图显示,将来也可以在WPF应用程序中使用这些新控件。
0.6 编写和运行C#代码的环境
.NET Core运行在Windows、Linux和macOS操作系统上。使用Visual Studio Code(网址0-11),可以在任何操作系统上创建和构建程序。在Windows或Linux平台上,可以使用.NET开发工具构建和运行本书的大部分示例。只有WinUI应用程序需要使用Windows平台,此时Visual Studio是选项。构建和运行WinUI应用程序需要的版本是16.10。
使用.NET CLI和Azure CLI时,命令行起着重要的作用。你可以使用新的Windows终端。在的Windows 10版本中,该终端作为Windows的一部分提供。对于较旧的版本,可以在Microsoft Store中下载它。
大部分.NET开发人员使用Windows平台进行开发。使用Windows Subsystem for Linux (WSL 2)时,可以在Linux环境中构建和运行.NET应用程序,并且可以在Windows环境中安装不同的Linux发行版,访问相同的文件。Visual Studio甚至允许调试在WSL 2上的Linux环境中运行的.NET应用程序。
本书中的一些示例展示了如何使用Microsoft Azure作为可选的托管环境来运行Web应用程序、使用Azure Functions,以及使用Entity Framework Core来访问SQL Server和Azuer Cosmos DB。对于这些示例,可以使用Microsoft Azure的免费试用服务,请访问网址0-12进行注册。
0.7 本书内容
本书分为4个主要部分:
● C#语言
● 使用.NET的基类库
● 开发Web应用程序和服务
● 开发Windows应用程序
下面详细介绍不同部分的各章讲述的内容。
第I部分—— C#语言
本书第I部分介绍C#编程语言的方方面面。你将学到C#的语法选项,并了解C#语法如何与.NET中的类和接口整合在一起。本部分为学习C#语言打下坚实的基础。这里不假定你熟悉特定的编程语言,但认为你是一名有经验的程序员。该部分首先介绍C#的基本语法和数据类型,然后介绍C#的高级特性。
● 第1章介绍创建.NET应用程序的基础知识。你将了解.NET CLI,并使用C# 9的语句创建一个Hello World应用程序。
● 第2章介绍C#的核心特性,并详细解释语句以及关于变量声明和类型的信息。该章介绍目标类型的new表达式,解释可空引用类型,并定义包含新的switch表达式的程序流。
● 第3章介绍如何创建引用类型或值类型,创建和使用元组,以及使用C# 9的增强来创建和使用记录。
● 第4章详细介绍C#的面向对象技术,并演示C#中用于面向对象的所有关键字。还介绍了C# 9记录的继承。
● 第5章解释C#运算符,以及如何为自定义类型重载标准运算符。
● 第6章不只介绍简单的数组,还介绍多维数组和锯齿数组,使用Span类型来访问数组,以及使用新的索引和范围运算符来访问数组。
● 第7章介绍方法的.NET指针,lambda表达式和闭包,以及.NET事件。
● 第8章介绍不同类型的集合,例如列表、队列、栈、字典和不可变集合。该章还介绍了如何在不同的场景中选择合适的集合。
● 第9章介绍C#语言集成查询,用于查询集合中的数据。该章还介绍如何在查询中使用多个CPU核心,以及当在Entity Framework Core中使用LINQ来访问数据库时,表达式树中发生了什么。
● 第10章介绍如何处理错误,抛出和捕获异常,以及在捕获异常时过滤异常。
● 第11章介绍C#关键字async和await的应用,介绍基于任务的异步模式,还介绍异步流,这是C# 8中新增的特性。
● 第12章介绍如何在C#中使用和读取特性。介绍使用反射读取特性,还介绍源代码生成器,它允许在编译时创建源代码。
● 第13章是第I部分的后一章,展示如何通过using语句和新的using声明来使用IDisposable接口,并将展示如何对托管和非托管内存使用Span类型。该章介绍如何在Windows和Linux环境中使用平台调用。
第II部分——库
第II部分首先创建自定义库和NuGet包,但这部分的主要主题是使用对于所有应用程序类型都很重要的.NET库。
● 第14章解释程序集和NuGet包之间的区别。你将学习如何创建NuGet包,还会学到一种新的C#特性“模块初始化器”,它允许在库中运行初始代码。
● 第15章详细介绍如何使用Host类来配置依赖注入容器,以及通过不同的配置提供程序(包括Azure App Configuration和用户秘密)在.NET应用程序中获取配置信息的内置选项。
● 第16章继续使用Host类来配置日志选项。你还将学到如何使用.NET提供程序读取提供的指标信息,如何使用Visual Studio App Center,以及如何使用OpenTelemetry为分布式跟踪扩展日志。
● 第17章介绍.NET为并行化和同步提供的多种特性。第11章介绍Task类的核心功能。该章则介绍Task类的更多功能,例如构成任务层次结构和使用ValueTask。该章介绍并行编程中会遇到的一些问题,如争用条件和死锁。对于同步,则介绍lock关键字可用的不同特性,以及Monitor、SpinLock、Mutex、Semaphore类等。
● 第18章介绍使用新的流API(它们允许使用Span类型)来读写文件系统,还介绍通过System.Text.Json名称空间中的类新提供的.NET JSON序列化器。
● 第19章介绍网络编程的基础类(如Socket类),以及如何使用TCP和UDP创建应用程序。还可以使用HttpClient工厂模式来创建在发生暂时性错误时自动重试的HttpClient对象。
● 第20章介绍用于加密数据的加密类,解释如何使用新的Microsoft.Identity平台进行用户身份验证,提供关于Web安全性的信息,以及关于编码和跨站请求伪造攻击的信息。
● 第21章介绍如何读写数据库的数据,包括EF Core提供的众多特性,如影子属性、全局查询过滤器、多对多关系以及EF Core现在提供的指标信息。还介绍如何使用EF Core读写Azure Cosmos DB。
● 第22章介绍如何使用对于Windows和Web应用程序都很重要的技术来本地化应用程序。
● 第23章介绍如何创建单元测试,使用.NET CLI分析代码覆盖率,以及在创建单元测试时使用模拟库。还介绍ASP.NET Core为创建集成测试提供的特性。
第III部分——Web应用程序和服务
本书第III部分介绍用于创建Web应用程序和服务的ASP.NET Core技术。可以在本地环境中运行这些应用程序和服务,也可以使用Azure App Services、Azure Static Web Apps或Azure Functions在云中运行它们。
● 第24章介绍 ASP.NET Core 的基础知识。该章基于第II部分介绍的依赖注入容器,展示ASP.NET Core如何使用中间件来向每个HTTP请求添加功能,以及为ASP.NET Core端点路由定义路由。
● 第25章介绍如何使用不同的技术(如ASP.NET Core和Azure Functions)来创建微服务,以及如何使用gRPC进行二进制通信。
● 第26章介绍如何使用ASP.NET Core技术与用户交互。该章介绍Razor页面、Razor视图以及Tag Helper和视图组件等功能。
● 第27章介绍Razor组件对ASP.NET Core的增强,这次增强允许实现在服务器和在客户端(使用WebAssembly)运行的C#代码。该章介绍Blazor Server和Blazor WebAssembly的区别,各自的局限,以及可用的内置组件。
● 第28章介绍如何使用ASP.NET Core的实时功能来向一组客户端发送信息,以及如何在SignalR中使用C#异步流。
第IV部分——应用程序
本书的第IV部分介绍XAML代码,以及使用Windows 10的原生UI平台WinUI来创建Windows应用程序。该部分介绍的许多信息也适用于WPF应用程序和.NET MAUI,适用于为移动平台开发基于XAML的应用程序。
● 第29章介绍XAML的基础知识,包括依赖属性和附加属性。你将学习如何创建自定义标记扩展,以及WinUI提供的控件类别,包括自适应触发器和延迟加载等高级技术。
● 第30章介绍使用MVVM模式所需的信息,以及如何在不同的基于XAML的技术(如WinUI、WPF和.NET MAUI)之间共享尽可能多的代码。
● 第31章介绍XAML形状和几何图形元素,展示样式和控件模板,说明如何创建动画,并解释如何在基于XAML的应用程序中使用可视化状态管理器。
0.8 如何下载本书的示例代码
读者在学习本书中的示例时,可手工输入所有的代码,也可使用本书附带的源代码文件。本书使用的所有源代码都可以从本书合作站点网址0-13上下载。登录到网址0-13,使用搜索框或书名列表就可找到本书。接着单击本书细目页面上的Download Code链接,就可以获得所有源代码,也可扫描封底的二维码获取本书的源代码和书中提到的网址。
注意:
许多图书的书名都很相似,所以通过ISBN查找本书是简单的,本书英文版的ISBN是978-1-119-79720-3。
在下载代码后,只需要用自己喜欢的解压缩软件对它进行解压缩即可。
本书源代码也在 GitHub 上提供,网址是网址0-14。在GitHub中,还可以使用Web浏览器打开每个源代码文件。使用这个网站时,可以把完整的源代码下载到一个zip文件。还可以将源代码复制到系统上的本地目录,只需要安装git工具即可。为此可以使用Visual Studio或者从网址0-15下载Windows、Linux和macOS的git工具。要将源代码复制到本地目录,请使用git clone:
> git clone https://www.github.com/ProfessionalCSharp/ProfessionalCSharp2021
使用此命令,把完整的源代码复制到子目录ProfessionalCSharp2021。之后就可以开始处理源文件了。
在.NET更新后(本书的下个版本出版前),源代码将在GitHub上更新。请查看GitHub存储库中的readme.md文件以了解更新。如果在复制源代码之后源代码发生了变化,可以将当前目录更改为源代码目录,并提取的更改:
> git pull
如果对源代码做了更改,git pull可能会导致错误。如果发生这种情况,可以把更改隐藏起来,然后再次获取:
> git stash
> git pull
git命令的完整列表可以在网址0-16上找到。
如果有关于源代码的疑问,可以使用GitHub存储库的讨论功能。如果发现源代码有错误,可以在存储库中报告问题。在浏览器中打开网址0-14,单击Issues选项卡,单击New Issue按钮。这将打开一个编辑器。你应该尽可能详细地描述问题。
为了报告问题,需要一个GitHub账户。如果有GitHub账户,也可以将源代码存储库分叉到账户上。有关使用GitHub的更多信息,请查看网址0-17。
注意:
可以读取源代码和相关问题,并在不加入GitHub的情况下在本地复制存储库。要在GitHub上发布问题并创建自己的存储库,需要自己的GitHub账户。GitHub的基本功能是免费的(参见0-18)。
0.9 勘误表
尽管我们已经尽力保证不出现错误,但错误总是难免的,如果你在本书中找到了错误,如拼写错误或代码错误,请告诉我们,我们将非常感激。通过勘误表,可以让其他读者避免受挫,当然,这还有助于提供更高质量的信息。
要在网站上找到本书的勘误表,可以登录网址0-13,通过搜索框或书名列表查找本书,然后在本书的细目页面上,单击Book Errata链接。在这个页面上可以查看图书编辑已提交的所有勘误项。
如果没有在Book Errata页面上发现自己找到的错误,请访问网址0-19,了解如何把自己发现的错误发送给我们。我们将检查信息,如果合适的话,将会把消息提交到该书的勘误页面,并在该书的后续版本中修复问题。
评论
还没有评论。