图书目录

目    录

第1章  C#与.NET入门  1

1.1 本书内容简介  1

1.1.1 获取本书的代码解决方案  1

1.1.2 本书使用的.NET术语  2

1.1.3 本书的结构和风格  2

1.1.4 本书讨论的主题  3

1.1.5 Apps and Services with .NET 8一书中涵盖的主题  3

1.2  设置开发环境  3

1.2.1 选择适合学习的工具和应用程序类型  4

1.2.2 跨平台部署  7

1.2.3 下载并安装Visual Studio 2022  7

1.2.4 下载并安装Visual Studio Code  8

1.3  理解.NET  10

1.3.1 了解.NET支持  11

1.3.2 理解中间语言  13

1.3.3 比较.NET技术  14

1.3.4 使用代码编辑器管理多个项目  14

1.4  使用Visual Studio 2022构建控制台应用程序  14

1.4.1 使用Visual Studio 2022编写代码  14

1.4.2 使用Visual Studio编译和运行代码  17

1.4.3 理解顶级程序  18

1.4.4 揭示Program类的名称空间  20

1.4.5 使用Visual Studio 2022添加第二个项目  20

1.5  使用Visual Studio Code构建控制台应用程序  23

1.5.1 使用Visual Studio Code编写代码  23

1.5.2 使用dotnet CLI编译和运行代码  25

1.5.3 使用Visual Studio Code添加第二个项目  26

1.5.4 Visual Studio Code的步骤小结  28

1.5.5 本书中使用的其他项目类型小结  28

1.6  充分利用本书的GitHub存储库  28

1.6.1 了解GitHub上的解决方案代码  29

1.6.2 对本书提出问题  29

1.6.3 反馈  30

1.6.4 避免常见错误  30

1.6.5 从GitHub存储库下载解决方案代码  30

1.6.6 在Visual Studio Code和命令行中使用Git  31

1.7  寻求帮助  31

1.7.1 阅读Microsoft Learn中的文档  31

1.7.2 本书中的文档链接  31

1.7.3 获取关于dotnet工具的帮助  32

1.7.4 获取类型及其成员的定义  33

1.7.5 配置内联提示  36

1.7.6 在Stack Overflow上寻找答案  36

1.7.7 使用谷歌搜索答案  37

1.7.8 搜索.NET源代码  37

1.7.9 订阅官方的.NET博客  38

1.7.10 观看Scott Hanselman的视频  38

1.7.11 ChatGPT和GitHub Copilot等AI工具  39

1.7.12 当工具成为障碍时禁用工具  41

1.8  实践和探索  41

1.8.1 练习1.1:测试你掌握的知识  41

1.8.2 练习1.2:使用浏览器在任何地方练习C#  42

1.8.3 练习1.3:探索主题  42

1.8.4 练习1.4:探索Polygot Notebooks  42

1.8.5 练习1.5:探索现代.NET的主题  42

1.8.6 练习1.6:Free Code Camp和C#认证  43

1.8.7 练习1.7:.NET的alpha版本  43

1.9  本章小结  43

第2章  C#编程基础  45

2.1  介绍C#语言  45

2.1.1  理解C#语言版本和特性  45

2.1.2  了解C#标准  46

2.2  了解C#编译器版本  46

2.2.1 如何输出SDK版本  47

2.2.2 启用特定的语言版本编译器  47

2.2.3 使用未来的C#编译器版本  48

2.2.4 .NET 8的C#编译器切换到后续版本  48

2.2.5  显示编译器版本  49

2.3  理解C#语法和词汇  50

2.3.1  了解C#语法  50

2.3.2  语句  51

2.3.3  注释  51

2.3.4  代码块  52

2.3.5  区域  52

2.3.6  语句和语句块的示例  53

2.3.7  使用空白字符格式化代码  54

2.3.8  了解C#词汇表  54

2.3.9  将编程语言与人类语言进行比较  55

2.3.10  修改C#语法的配色方案  55

2.3.11  如何编写正确的代码  55

2.3.12  导入名称空间  56

2.3.13 隐式和全局导入名称空间  56

2.3.14  动词表示方法  60

2.3.15  名词表示类型、变量、字段和属性  60

2.3.16  揭示C#词汇表的范围  61

2.3.17  请求ChatGPT解释代码的示例  62

2.4  使用变量  64

2.4.1  命名和赋值  64

2.4.2  字面值  65

2.4.3  存储文本  65

2.4.4  输出表情符号  66

2.4.5 理解逐字字符串  66

2.4.6 原始字符串字面值  66

2.4.7 原始内插字符串字面值  67

2.4.8 有关存储文本的总结  67

2.4.9  存储数字  68

2.4.10 探索整数  69

2.4.11 存储实数  69

2.4.12  新的数字类型和不安全代码  72

2.4.13  存储布尔值  73

2.4.14  存储任何类型的对象  74

2.4.15 动态存储类型  74

2.4.16  声明局部变量  76

2.4.17  获取和设置类型的默认值  78

2.5  深入研究控制台应用程序  79

2.5.1  向用户显示输出  79

2.5.2  从用户那里获取文本输入  83

2.5.3  简化控制台的使用  84

2.5.4  获取用户的重要输入  85

2.5.5  向控制台应用程序传递参数  86

2.5.6  使用参数设置选项  89

2.5.7  处理不支持API的平台  90

2.6  理解async和await  92

2.7  实践和探索  93

2.7.1  练习2.1:测试你掌握的知识  93

2.7.2  练习2.2:测试你对数字类型的了解  93

2.7.3  练习2.3:练习数字大小和范围  94

2.7.4  练习2.4:探索主题  94

2.7.5  练习2.5:探索Spectre库  94

2.8  本章小结  94

第3章  控制程序流程、转换类型和处理异常  95

3.1  操作变量  95

3.1.1  理解二元运算符  95

3.1.2  理解一元运算符  96

3.1.3  理解三元运算符  96

3.1.4 二元算术运算符  98

3.1.5  赋值运算符  98

3.1.6 空值合并运算符  99

3.1.7 逻辑运算符  99

3.1.8 条件逻辑运算符  100

3.1.9 按位和二元移位运算符  101

3.1.10  其他运算符  102

3.2  理解选择语句  103

3.2.1  使用if语句进行分支  103

3.2.2  模式匹配与if语句  104

3.2.3  使用switch语句进行分支  105

3.2.4  使用Visual Studio 2022向项目添加新项  106

3.2.5 模式匹配与switch语句  107

3.2.6  使用switch表达式简化switch语句  109

3.3  理解迭代语句  110

3.3.1  while循环语句  110

3.3.2  do循环语句  111

3.3.3  for循环语句  111

3.3.4  foreach循环语句  112

3.4  在数组中存储多个值  113

3.5  类型转换  119

3.5.1  隐式和显式地转换数字  120

3.5.2 负数在二进制中的表示  121

3.5.3 使用System.Convert类型进行转换  122

3.5.4  圆整数字和默认的圆整原则  123

3.5.5  控制圆整规则  124

3.5.6  从任何类型转换为字符串  124

3.5.7  从二进制对象转换为字符串  125

3.5.8  将字符串转换为数字或日期和时间  126

3.6  处理异常  128

3.7  检查溢出  132

3.7.1  使用checked语句抛出溢出异常  132

3.7.2  使用unchecked语句禁用编译时溢出检查  133

3.8  实践和探索  134

3.8.1  练习3.1:测试你掌握的知识  134

3.8.2  练习3.2:探索循环和溢出  135

3.8.3  练习3.3:测试你对运算符的掌握程度  135

3.8.4 练习3.4:实践循环和运算符  135

3.8.5 练习3.5:实践异常处理  136

3.8.6  练习3.6:探索C# Polyglot Notebooks  136

3.8.7  练习3.7:探索主题  136

3.9  本章小结  137

第4章  编写、调试和测试函数  138

4.1  编写函数  138

4.1.1  理解顶级程序、函数和名称空间  138

4.1.2 对于局部函数,编译器会自动生成什么  139

4.1.3  使用静态函数定义分部程序  140

4.1.4 对于静态函数,编译器会自动生成什么  141

4.1.5  乘法表示例  142

4.1.6  简述实参与形参  144

4.1.7  编写带返回值的函数  145

4.1.8  将数字从基数转换为序数  147

4.1.9  用递归计算阶乘  149

4.1.10  使用XML注释文档化函数  151

4.1.11  在函数实现中使用lambda  152

4.2  在开发过程中进行调试  154

4.2.1 创建带有故意错误的代码  154

4.2.2  设置断点并开始调试  155

4.2.3  使用调试工具栏进行导航  157

4.2.4  调试窗口  158

4.2.5  单步执行代码  158

4.2.6  在 Visual Studio Code 中使用集成终端进行调试  159

4.2.7 自定义断点  161

4.3  在开发期间进行热重载  163

4.3.1  使用Visual Studio 2022进行热重载  163

4.3.2  使用Visual Studio Code和dotnet watch命令进行热重载  164

4.4  在开发和运行时进行日志记录  165

4.4.1  理解日志记录选项  165

4.4.2  使用Debug和Trace类型  165

4.4.3  配置跟踪侦听器  167

4.4.4  切换跟踪级别  168

4.4.5  记录有关源代码的信息  174

4.5  单元测试  175

4.5.1  理解测试类型  176

4.5.2  创建需要测试的类库  176

4.5.3  编写单元测试  177

4.6  在函数中抛出并捕获异常  180

4.6.1  理解使用错误和执行错误  180

4.6.2  在函数中通常抛出异常  180

4.6.3 使用保护子句抛出异常  181

4.6.4 理解调用堆栈  181

4.6.5  在哪里捕获异常  184

4.6.6  重新抛出异常  184

4.6.7  实现tester-doer模式和try模式  186

4.7  实践和探索  187

4.7.1  练习4.1:测试你掌握的知识  187

4.7.2  练习4.2:编写带有调试和单元测试功能的函数  187

4.7.3  练习4.3:探索主题  188

4.8  本章小结  188

第5章  使用面向对象编程技术构建自己的类型  189

5.1  面向对象编程  189

5.2  构建类库  190

5.2.1  创建类库  190

5.2.2  理解文件作用域名称空间  192

5.2.3 在名称空间中定义类  192

5.2.4 理解类型访问修饰符  193

5.2.5  理解成员  193

5.2.6  导入名称空间以使用类型  194

5.2.7  实例化类  196

5.2.8  继承System.Object  196

5.2.9 使用别名避免名称空间冲突  197

5.3 在字段中存储数据  198

5.3.1  定义字段  198

5.3.2 字段的类型  199

5.3.3 成员访问修饰符  199

5.3.4  设置和输出字段值  200

5.3.5 使用对象初始化器语法设置字段值  200

5.3.6  使用enum类型存储值  201

5.3.7  使用enum类型存储多个值  202

5.3.8  使用集合存储多个值  203

5.3.9  理解泛型集合  203

5.3.10  使字段成为静态字段  204

5.3.11  使字段成为常量  205

5.3.12  使字段只读  206

5.3.13 在实例化时要求设置字段值  207

5.3.14 使用构造函数初始化字段  208

5.4  使用方法和元组  211

5.4.1  从方法返回值  211

5.4.2  定义参数并将参数传递给方法  211

5.4.3  重载方法  212

5.4.4  传递可选参数  213

5.4.5 调用方法时的命名参数值  213

5.4.6  混用可选参数与必需参数  214

5.4.7  控制参数的传递方式  215

5.4.8  理解ref返回  216

5.4.9  使用元组组合多个返回值  217

5.4.10  使用局部函数实现功能  220

5.4.11  使用partial关键字拆分类  221

5.5  使用属性和索引器控制访问  222

5.5.1  定义只读属性  222

5.5.2  定义可设置的属性  223

5.5.3  限制枚举标志的值  225

5.5.4  定义索引器  227

5.6  模式匹配和对象  228

5.6.1  模式匹配飞机乘客  228

5.6.2  C# 9及更高版本对模式匹配做了增强  230

5.7  使用record类型  231

5.7.1  init-only属性  231

5.7.2  定义record类型  232

5.7.3  record类型的相等性  233

5.7.4  记录中的位置数据成员  234

5.7.5 在类中定义主构造函数  235

5.8  实践和探索  236

5.8.1  练习5.1:测试你掌握的知识  236

5.8.2  练习5.2:练习使用访问修饰符  237

5.8.3 练习5.3:探索主题  237

5.9  本章小结  237

第6章  实现接口和继承类  238

6.1  建立类库和控制台应用程序  238

6.2  静态方法和重载运算符  240

6.2.1  使用方法实现功能  240

6.2.2  使用运算符实现功能  244

6.3 使用泛型安全地重用类型  246

6.3.1  使用非泛型类型  246

6.3.2  使用泛型类型  248

6.4  触发和处理事件  249

6.4.1  使用委托调用方法  249

6.4.2  定义和处理委托  250

6.4.3  定义和处理事件  252

6.5  实现接口  254

6.5.1  公共接口  254

6.5.2  排序时比较对象  254

6.5.3  使用单独的类比较对象  258

6.5.4  隐式和显式的接口实现  259

6.5.5  使用默认实现定义接口  260

6.6  使用引用类型和值类型管理内存  262

6.6.1  理解栈内存和堆内存  262

6.6.2  定义引用类型和值类型  262

6.6.3  如何在内存中存储引用类型和值类型  263

6.6.4  理解装箱  264

6.6.5  类型的相等性  265

6.6.6  定义struct类型  267

6.6.7  定义record struct类型  268

6.6.8  释放非托管资源  269

6.6.9  确保调用Dispose方法  270

6.7  使用空值  271

6.7.1  使值类型可为空  271

6.7.2  了解与null相关的缩略词  273

6.7.3  理解可空引用类型  273

6.7.4  控制可空性警告检查特性  274

6.7.5  禁用null值和其他编译器警告  274

6.7.6 声明非可空变量和参数  275

6.7.7  检查null  277

6.8  从类继承  279

6.8.1  扩展类以添加功能  280

6.8.2  隐藏成员  280

6.8.3  了解this和base关键字  281

6.8.4 覆盖成员  281

6.8.5  从抽象类继承  282

6.8.6  选择接口还是抽象类  283

6.8.7 防止继承和覆盖  283

6.8.8  理解多态  284

6.9  在继承层次结构中进行类型转换  285

6.9.1  隐式类型转换  286

6.9.2  显式类型转换  286

6.9.3  避免类型转换异常  286

6.10  继承和扩展.NET类型  288

6.10.1  继承异常  288

6.10.2  无法继承时扩展类型  289

6.11 总结自定义类型的选择  291

6.11.1 自定义类型的分类及其功能  291

6.11.2 可变性与record类型  292

6.11.3 比较继承与实现  293

6.11.4 回顾示例代码  293

6.12  实践和探索  295

6.12.1  练习6.1:测试你掌握的知识  295

6.12.2  练习6.2:练习创建继承层次结构  296

6.12.3  练习6.3:编写更好的代码  296

6.12.4  练习6.4:探索主题  296

6.13  本章小结  296

第7章  打包和分发.NET类型  298

7.1  .NET 8简介  298

7.2  了解.NET组件  300

7.2.1  程序集、NuGet包和名称空间  300

7.2.2  Microsoft .NET project SDK  301

7.2.3  理解程序集中的名称空间和类型  301

7.2.4  NuGet包  302

7.2.5  理解框架  302

7.2.6  导入名称空间以使用类型  302

7.2.7  将C#关键字与.NET类型相关联  303

7.2.8  使用.NET Standard在旧平台之间共享代码  306

7.2.9  理解不同SDK中类库的默认设置  306

7.2.10  创建.NET Standard 类库  307

7.2.11  控制.NET SDK  308

7.2.12 混合使用SDK和目标框架  309

7.3  发布用于部署的代码  310

7.3.1  创建要发布的控制台应用程序  310

7.3.2  理解dotnet命令  312

7.3.3  获取关于.NET及其环境的信息  313

7.3.4  使用dotnet CLI管理项目  313

7.3.5  发布自包含的应用程序  314

7.3.6  发布单文件应用  316

7.3.7  使用app trimming系统减小应用程序的大小  316

7.3.8  控制构建产物的生成位置  317

7.4 原生ATO编译  318

7.4.1 本地AOT 的限制  318

7.4.2 反射与原生AOT  319

7.4.3 原生AOT的要求  319

7.4.4 为项目启用原生AOT  320

7.4.5 构建原生AOT项目  320

7.4.6 发布原生AOT项目  321

7.5 反编译.NET程序集  322

7.5.1  使用Visual Studio 2022的ILSpy扩展进行反编译  322

7.5.2  使用Visual Studio 2022查看源链接  325

7.5.3  不能在技术上阻止反编译  326

7.6  为NuGet分发打包自己的库  327

7.6.1  引用NuGet包  327

7.6.2  为NuGet打包库  328

7.6.3  使用工具探索NuGet包  332

7.6.4  测试类库包  333

7.7  使用预览功能  334

7.7.1  需要预览功能  335

7.7.2  使用预览功能  335

7.7.3 方法拦截器  335

7.8  实践和探索  336

7.8.1  练习7.1:测试你掌握的知识  336

7.8.2  练习7.2:探索主题  336

7.8.3  练习7.3:从.NET Framework移植到现代.NET  336

7.8.4 练习 7.4:创建源代码生成器  336

7.8.5 练习7.5:探索PowerShell  336

7.8.6 练习7.6:提升.NET性能  337

7.9  本章小结  337

第8章  使用常见的.NET类型  338

8.1  处理数字  338

8.1.1  处理大的整数  338

8.1.2  处理复数  339

8.1.3 为游戏和类似应用程序生成随机数  340

8.1.4  生成GUID  342

8.2  处理文本  343

8.2.1  获取字符串的长度  343

8.2.2  获取字符串中的字符  344

8.2.3  拆分字符串  344

8.2.4  获取字符串的一部分  344

8.2.5  检查字符串的内容  345

8.2.6  比较字符串值  345

8.2.7 连接、格式化和其他的字符串成员  347

8.2.8  高效地连接字符串  348

8.3  模式匹配与正则表达式  349

8.3.1  检查作为文本输入的数字  349

8.3.2  改进正则表达式的性能  350

8.3.3  正则表达式的语法  350

8.3.4  正则表达式示例  351

8.3.5  拆分使用逗号分隔的复杂字符串  351

8.3.6  激活正则表达式语法着色功能  353

8.3.7  使用源生成器提高正则表达式的性能  355

8.4  在集合中存储多个对象  357

8.4.1  所有集合的公共特性  357

8.4.2  使用列表  358

8.4.3 字典  361

8.4.4 集、堆栈和队列  364

8.4.5  集合的Add和Remove方法  367

8.4.6 集合的排序  367

8.4.7  使用专门的集合  368

8.4.8  只读集合、不可变集合和冻结集合  368

8.4.9 使用集合表达式初始化集合  372

8.4.10 集合的最佳实践  372

8.5  使用Span、索引和范围  373

8.5.1  通过Span高效地使用内存  373

8.5.2  用索引类型标识位置  374

8.5.3  使用Range类型标识范围  374

8.5.4  使用索引、范围和Span  374

8.6 实践和探索  375

8.6.1  练习8.1:测试你掌握的知识  375

8.6.2  练习8.2:练习正则表达式  375

8.6.3  练习8.3:练习编写扩展方法  376

8.6.4  练习8.4:使用网络资源  376

8.6.5  练习8.5:探索主题  376

8.7  本章小结  376

第9章  处理文件、流和序列化  377

9.1  管理文件系统  377

9.1.1  处理跨平台环境和文件系统  377

9.1.2  管理驱动器  380

9.1.3  管理目录  382

9.1.4  管理文件  383

9.1.5  管理路径  384

9.1.6  获取文件信息  385

9.1.7  控制处理文件的方式  385

9.2  用流来读写  386

9.2.1  理解抽象和具体的流  386

9.2.2 构建流管道  388

9.2.3  写入文本流  388

9.2.4  写入XML流  390

9.2.5  压缩流  394

9.2.6 使用随机访问句柄进行读写  396

9.3  编码和解码文本  397

9.3.1  将字符串编码为字节数组  398

9.3.2  对文件中的文本进行编码和解码  400

9.4  序列化对象图  400

9.4.1  序列化为XML  401

9.4.2  生成紧凑的XML  404

9.4.3  反序列化XML文件  405

9.4.4  用JSON序列化  406

9.4.5  高性能的JSON处理  407

9.4.6 反序列化JSON文件  407

9.4.7  控制处理JSON的方式  408

9.5 使用环境变量  411

9.5.1 读取所有环境变量  411

9.5.2 展开、设置和获取环境变量  413

9.6  实践和探索  415

9.6.1  练习9.1:测试你掌握的知识  415

9.6.2  练习9.2:练习序列化为XML  416

9.6.3 练习9.3:使用tar存档  416

9.6.4 练习9.4:从Newtonsoft迁移到新的JSON  416

9.6.5  练习9.5:探索主题  416

9.7  本章小结  417

第10章  使用Entity Framework Core处理数据  418

10.1  理解现代数据库  418

10.1.1 理解旧的实体框架  419

10.1.2 理解Entity Framework Core  419

10.1.3 理解数据库优先和代码优先  420

10.1.4 EF Core的性能改进  420

10.1.5 使用示例关系数据库  420

10.1.6 使用SQLite  421

10.1.7  使用SQL Server还是其他SQL系统  422

10.1.8  为Windows设置SQLite  422

10.1.9  为macOS和Linux设置SQLite  423

10.2 在.NET项目中设置EF Core  423

10.2.1 为使用EF Core创建控制台应用程序  423

10.2.2 为SQLite创建Northwind示例数据库  423

10.2.3 使用SQLiteStudio管理Northwind示例数据库  424

10.2.4 使用轻量级的ADO.NET数据库提供程序  426

10.2.5 选择EF Core数据库提供程序  426

10.2.6 连接到命名的SQLite数据库  427

10.2.7 定义Northwind数据库上下文类  427

10.3  定义EF Core模型  428

10.3.1 使用EF Core约定定义模型  428

10.3.2 使用EF Core注解特性定义模型  429

10.3.3 使用EF Core Fluent API定义模型  431

10.3.4  理解数据播种和Fluent API  431

10.3.5 为Northwind表构建EF Core模型  431

10.3.6  定义Category和Product实体类  432

10.3.7 向Northwind数据库上下文类添加表  434

10.3.8 安装dotnet-ef工具  435

10.3.9 使用现有数据库搭建模型  436

10.3.10 自定义逆向工程模板  440

10.3.11 配置约定前模型  440

10.4  查询EF Core模型  441

10.4.1 过滤结果中返回的实体  443

10.4.2 过滤和排序产品  445

10.4.3 获取生成的SQL  446

10.4.4 记录EF Core  447

10.4.5  根据特定于提供程序的值过滤日志  449

10.4.6  使用查询标记进行日志记录  449

10.4.7 获取单个实体  450

10.4.8 使用Like进行模式匹配  451

10.4.9 在查询中生成随机数  453

10.4.10 定义全局过滤器  454

10.5  使用EF Core加载和跟踪模式  454

10.5.1 使用Include扩展方法立即加载实体  454

10.5.2 启用延迟加载  455

10.5.3 使用Load方法显式加载实体  456

10.5.4 控制实体跟踪  458

10.5.5 3种跟踪场景  459

10.5.6 延迟加载未启用跟踪的查询  460

10.6  使用EF Core修改数据  461

10.6.1 插入实体  462

10.6.2 更新实体  464

10.6.3 删除实体  465

10.6.4 更高效地更新和删除  466

10.6.5 池化数据库环境  469

10.7  实践和探索  469

10.7.1 练习10.1:测试你掌握的知识  470

10.7.2 练习10.2:练习使用不同的序列化格式导出数据  470

10.7.3 练习10.3:使用事务  470

10.7.4 练习10.4:探索代码优先EF Core模型  470

10.7.5 练习10.5:探索应用程序机密  470

10.7.6 练习10.6:探索主题  471

10.7.7 练习10.7:探索NoSQL数据库  471

10.8  本章小结  471

第11章  使用LINQ查询和操作数据  472

11.1  编写LINQ表达式  472

11.1.1 对比命令式语言和声明式语言的特性  472

11.1.2 LINQ的组成  473

11.1.3 使用Enumerable类构建LINQ表达式  473

11.2 LINQ的现实应用  475

11.2.1 理解延迟执行  475

11.2.2 使用Where扩展方法过滤实体  477

11.2.3 以命名方法为目标  479

11.2.4 通过删除委托的显式实例化来简化代码  480

11.2.5 以lambda表达式为目标  480

11.2.6 具有默认参数值的lambda表达式  480

11.3  排序及其他操作  481

11.3.1  使用OrderBy扩展方法按单个属性排序  481

11.3.2  使用ThenBy扩展方法按后续属性排序  481

11.3.3 按项自身排序  482

11.3.4 使用var或指定类型声明查询  482

11.3.5 根据类型进行过滤  483

11.3.6 处理集合和bag  484

11.4  使用LINQ与EF Core  486

11.4.1 为探索LINQ to Entities来创建一个控制台应用程序  486

11.4.2 构建EF Core模型  487

11.4.3 序列的过滤和排序  489

11.4.4 将序列投影到新的类型中  492

11.5  连接、分组和查找  493

11.5.1  连接序列  494

11.5.2  分组连接序列  495

11.5.3  分组查找  496

11.6  聚合和分页序列  498

11.6.1 检查空序列  500

11.6.2 小心使用Count  500

11.6.3 使用LINQ分页  502

11.6.4 使用语法糖美化LINQ语法  505

11.7  实践和探索  506

11.7.1 练习11.1:测试你掌握的知识  506

11.7.2 练习11.2:练习使用LINQ进行查询  507

11.7.3 练习11.3:在并行LINQ中使用多线程  507

11.7.4 练习11.4:使用LINQ to XML  507

11.7.5 练习11.5:创建自己的LINQ扩展方法  507

11.7.6 练习11.6:探索主题  508

11.8  本章小结  508

第12章  使用ASP.NET Core进行Web开发  509

12.1  理解ASP.NET Core  509

12.1.1  经典ASP.NET与现代ASP.NET Core的对比  510

12.1.2  使用ASP.NET Core构建网站  511

12.1.3  ASP.NET Core中使用的不同文件类型  511

12.1.4  使用内容管理系统构建网站  512

12.1.5  使用SPA框架构建Web应用程序  512

12.1.6  构建Web服务和其他服务  513

12.2  结构化项目  513

12.3  建立实体模型供本书剩余部分章节使用  515

12.3.1  创建Northwind数据库  515

12.3.2  使用SQLite创建实体模型类库  515

12.3.3  使用SQLite为数据库上下文创建类库  517

12.3.4  自定义模型并定义扩展方法  519

12.3.5  注册依赖服务的作用域  522

12.3.6  使用SQL Server为实体模型创建类库  522

12.3.7  改进类到表的映射  522

12.3.8  测试类库  524

12.4  了解Web开发  527

12.4.1  理解HTTP  527

12.4.2  使用Google Chrome浏览器发出HTTP请求  528

12.4.3  了解客户端Web开发技术  530

12.5  实践和探索  530

12.5.1  练习12.1:测试你掌握的知识  530

12.5.2  练习12.2:了解Web开发中常用的缩写  531

12.5.3  练习12.3:探索主题  531

12.6  本章小结  531

第13章  使用ASP.NET Core Razor Pages构建网站  532

13.1  了解ASP.NET Core  532

13.1.1  创建空的ASP.NET Core项目  532

13.1.2  测试和保护网站  535

13.1.3  启用更强的安全性并重定向到安全连接  538

13.1.4  控制托管环境  539

13.1.5  使网站能够提供静态内容  540

13.2  了解ASP.NET Core Razor Pages  543

13.2.1  启用Razor Pages  543

13.2.2  给Razor Pages添加代码  544

13.2.3  对Razor Pages使用共享布局  545

13.2.4  临时存储数据  547

13.2.5  使用后台代码文件与Razor Pages  549

13.2.6  配置ASP.NET Core项目中包含的文件  551

13.2.7  项目文件构建操作  552

13.3  使用Entity Framework Core与ASP.NET Core  553

13.3.1  将Entity Framework Core配置为服务  553

13.3.2  启用模型以插入实体  555

13.3.3  定义用来插入新供应商的表单  556

13.3.4  将依赖服务注入Razor Pages中  556

13.4  配置服务和HTTP请求管道  557

13.4.1  了解端点路由  557

13.4.2 配置端点路由  557

13.4.3 查看项目中的端点路由配置  557

13.4.4 配置HTTP管道  559

13.4.5 总结关键的中间件扩展方法  560

13.4.6 可视化HTTP管道  560

13.4.7 实现匿名内联委托作为中间件  561

13.5  实践和探索  563

13.5.1 练习13.1:测试你掌握的知识  563

13.5.2 练习13.2:使用Razor类库  563

13.5.3 练习13.3:启用HTTP/3和对请求解压缩的支持  563

13.5.4 练习13.4:练习构建数据驱动的网页  563

13.5.5 练习13.5:练习为函数构建Web页面  564

13.5.6 练习13.6:Bootstrap简介  564

13.5.7 练习13.7:探索主题  564

13.5.8 练习13.8:使用MVC模式构建网站  564

13.6  本章小结  565

第14章  构建和消费Web服务  566

14.1  使用ASP.NET Core Web API构建Web服务  566

14.1.1 理解Web服务缩写词  566

14.1.2 理解Web API的HTTP请求和响应  567

14.1.3 创建ASP.NET Core Web API项目  569

14.1.4 检查Web服务的功能  572

14.2  为Northwind示例数据库创建Web服务  573

14.2.1 注册依赖服务  574

14.2.2 创建带实体缓存的数据存储库  575

14.2.3 路由Web服务  578

14.2.4  路由约束  578

14.2.5  ASP.NET Core 8中的短路路由  579

14.2.6  ASP.NET Core 8中改进的路由工具  579

14.2.7  理解操作方法的返回类型  579

14.2.8 配置客户存储库和Web API控制器  580

14.2.9 指定问题的细节  584

14.2.10 控制XML序列化  585

14.3  记录和测试Web服务  586

14.3.1 使用浏览器测试GET请求  586

14.3.2  使用HTTP/REST工具发出GET请求  587

14.3.3  使用HTTP/REST工具发出其他请求  588

14.3.4 传递环境变量  589

14.3.5 理解Swagger  590

14.3.6 使用Swagger UI测试请求  590

14.3.7 启用HTTP日志记录  593

14.3.8 W3CLogger支持记录额外的请求头  595

14.4  使用HTTP客户端消费Web服务  596

14.4.1 了解HttpClient类  596

14.4.2 使用HttpClientFactory配置HTTP客户端  596

14.4.3 在控制器中以JSON格式获取客户  596

14.4.4 启动多个项目  599

14.4.5 启动Web服务和MVC客户端项目  600

14.5  实践和探索  601

14.5.1 练习14.1:测试你掌握的知识  601

14.5.2 练习14.2:练习使用HttpClient创建和删除客户  601

14.5.3 练习14.3:为Web服务实现高级特性  601

14.5.4 练习14.4:使用最小API构建Web服务  602

14.5.5 练习14.5:探索主题  602

14.6  本章小结  602

第15章  使用Blazor构建用户界面  603

15.1  Blazor的历史  603

15.1.1 JavaScript和它的朋友们  603

15.1.2 Silverlight——使用插件的C#和.NET  604

15.1.3 WebAssembly——Blazor的目标  604

15.1.4 .NET 7和更早版本中的Blazor托管模型  604

15.1.5 .NET 8统一了Blazor托管模型  604

15.1.6 理解Blazor组件  605

15.1.7 比较Blazor和Razor  606

15.2 Blazor Web App项目模板简介  606

15.2.1 创建一个Blazor Web App项目  606

15.2.2 Blazor的路由、布局和导航  608

15.2.3 运行Blazor Web App项目模板  614

15.3  使用Blazor构建组件  615

15.3.1 定义和测试简单的Blazor组件  615

15.3.2 使用Bootstrap图标  616

15.3.3 将组件转换成可路由的页面组件  617

15.3.4 将实体放入组件  617

15.3.5 为Blazor组件抽象服务  618

15.3.6  启用流式渲染  622

15.3.7 使用EditForm组件定义表单  623

15.3.8 构建客户详细信息组件  623

15.3.9 构建创建、编辑和删除客户的组件  625

15.3.10 启用服务器端交互  627

15.3.11 测试客户组件  627

15.4 使用WebAssembly启用客户端执行  628

15.5  实践和探索  628

15.5.1 练习15.1:测试你掌握的知识  628

15.5.2 练习15.2:通过创建乘法表组件进行练习  629

15.5.3 练习15.3:通过创建国家导航项进行练习  629

15.5.4 练习15.4:增强Blazor应用程序  630

15.5.5 练习15.5:使用开源的Blazor组件库  630

15.5.6 练习15.6:探索主题  630

15.6  本章小结  630

第16章  结语  631

16.1 C#和.NET学习之旅的下一步  631

16.1.1 使用设计指南来完善技能  631

16.1.2 本书的配套图书  632

16.1.3 可以让学习更深入的其他图书  633

16.2 祝你好运  633

16.3 分享意见  633

—— 以下内容可扫描封底二维码下载 ——

附录A  练习题答案  634

使用MVC模式构建网站  653