.NET 6 中的新增功能

.NET 6 提供从 .NET 5 开始的 .NET 统一计划的最终部分。 .NET 6 跨移动、桌面、IoT 和云应用统一 SDK、基本库和运行时。 除了此统一之外,.NET 6 生态系统还提供:

  • 简化的开发:入门非常简单。 C# 10 中的新语言功能减少了需要编写的代码量。 在 Web 堆栈和最少的 API 中进行投资可以轻松快速编写更小、更快的微服务。

  • 性能更佳:.NET 6 是最快的全堆栈 Web 框架,如果正在云中运行,则降低了计算成本。

  • 最终工作效率:.NET 6 和 Visual Studio 2022 提供热重载、新的 git 工具、智能代码编辑、可靠的诊断和测试工具,以及更好的团队协作。

作为长期支持(LTS)版本,.NET 6 将 支持三年

默认情况下禁用预览功能。 它们也不支持在生产环境中使用,并可能在将来的版本中删除。 RequiresPreviewFeaturesAttribute 用于标注预览 API,如果使用这些预览 API,相应的分析器会提醒您。

Visual Studio 2022 及更高版本支持 .NET 6。

本文不介绍 .NET 6 的所有新功能。 若要查看所有新功能,以及有关本文中列出的功能的详细信息,请参阅 公告 .NET 6 博客文章。

Performance

.NET 6 包括许多性能改进。 本部分列出了 FileStream配置文件引导优化AOT 编译中的一些改进。 有关详细信息,请参阅 .NET 6 博客文章中的性能改进

FileStream

System.IO.FileStream 类型已针对 .NET 6 进行了重写,以便在 Windows 上提供更好的性能和可靠性。 现在,FileStream 在 Windows 上为异步 I/O 创建时不会阻塞。 有关详细信息,请参阅 .NET 6 博客文章中的文件 IO 改进

按配置优化

配置文件引导优化(PGO)是在其中 JIT 编译器生成经过优化的代码,这些代码根据最常使用的类型和代码路径进行优化。 .NET 6 引入了 动态 PGO。 动态 PGO 与分层编译携手合作,根据第 0 层期间实施的其他检测进一步优化代码。 默认情况下禁用动态 PGO,但可以使用DOTNET_TieredPGO启用它。 有关详细信息,请参阅 JIT 性能改进

Crossgen2

.NET 6 引入了 Crossgen2(已删除的 Crossgen2 的继任者)。 Crossgen 和 Crossgen2 是提供预先(AOT)编译以增强应用启动速度的工具。 Crossgen2 采用 C# 而不是C++编写,可以执行以前版本无法执行的分析和优化。 有关详细信息,请参阅 有关 Crossgen2 的对话

Arm64 支持

.NET 6 版本包括对 macOS Arm64(或“Apple Silicon”)和 Windows Arm64作系统的支持,适用于本机 Arm64 执行和 x64 仿真。 此外,x64 和 Arm64 .NET 安装程序现在并行安装。 有关详细信息,请参阅 适用于 Arm64 和 x64 的 macOS 11 和 Windows 11 的 .NET 支持

热重载

热重载 是一项功能,可用于修改应用的源代码,并立即将这些更改应用到正在运行的应用。 此功能的目的是通过在编辑之间避免应用重启来提高工作效率。 Visual Studio 2022 和 dotnet watch 命令行工具中提供了热重载。 热重载适用于大多数类型的 .NET 应用,适用于 C#、Visual Basic 和C++源代码。 有关详细信息,请参阅 热重载博客文章

.NET MAUI

.NET 多平台应用 UI(.NET MAUI)仍处于 预览状态,其候选版本将在 2022 年第一季度发布,而正式发布(GA)预计在 2022 年第二季度。 通过 .NET MAUI,可以使用单个代码库为桌面和移动操作系统构建本机客户端应用。 有关详细信息,请参阅 .NET 多平台应用 UI 上的更新 博客文章。

C# 10 和模板

C# 10 包括 global using 创新,例如指令、文件范围的命名空间声明和记录结构。 有关详细信息,请参阅 C# 语言版本历史记录

根据这项工作,C# 的 .NET SDK 项目模板已现代化,以使用一些新的语言功能:

  • async Main 方法
  • 顶级语句
  • 目标类型的新表达式
  • 隐式 global using 指令
  • 文件范围的命名空间
  • 可为 Null 的引用类型

通过将这些新的语言功能添加到项目模板,新代码从启用的功能开始。 但是,升级到 .NET 6 时,现有代码不会受到影响。 有关这些模板更改的详细信息,请参阅 .NET SDK:C# 项目模板现代化 博客文章。

F# 和 Visual Basic

F# 6 为 F# 语言和 F# 交互添加了多项改进。 有关详细信息,请参阅 F# 6 中的新增功能。

Visual Basic 改进了 Visual Studio 体验和 Windows 窗体项目启动。

SDK 工作负载

为了减小 .NET SDK 的大小,某些组件已放置在新的可选 SDK 工作负载中。 这些组件包括 .NET MAUI 和 Blazor WebAssembly AOT。 如果使用 Visual Studio,它将负责安装所需的任何 SDK 工作负载。 如果使用 .NET CLI,可以使用新 dotnet workload 命令管理工作负荷:

Command Description
dotnet 工作负荷搜索 搜索可用的工作负载。
用于安装工作负载的命令 dotnet workload install 安装指定的工作负载。
dotnet workload uninstall 执行此命令以卸载 .NET 工作负载。 删除指定的工作负荷。
dotnet 工作负载更新 更新已安装的工作负载。
dotnet 工作负荷修复 重新安装所有已安装的工作负载以修复损坏的安装。
dotnet 工作负荷列表 列出已安装的工作负荷。

有关详细信息,请参阅 可选 SDK 工作负载

System.Text.Json API

在 .NET 6 中,System.Text.Json 进行了许多改进,现在已成为一种“工业级”序列化解决方案。

源生成器

.NET 6 为 添加了新的System.Text.Json。 源生成与 JsonSerializer 一起工作,并且可以采用多种方式进行配置。 它可以提高性能、减少内存使用量并简化程序集修整。 有关详细信息,请参阅 如何在 System.Text.Json 中选择反射或源生成以及如何在 System.Text.Json 中使用源生成

可写 DOM

添加了一个新的可写文档对象模型(DOM),该模型补充了预先存在的只读 DOM。 新 API 为使用普通旧 CLR 对象 (POCO) 类型是不可能的情况提供轻型序列化替代方法。 它还允许你有效地导航到大型 JSON 树的子节,并从该子节读取数组或反序列化 POCO。 添加了以下新类型以支持可写 DOM:

有关详细信息,请参阅 JSON DOM 选项

IAsyncEnumerable 序列化

System.Text.Json 现在支持使用 IAsyncEnumerable<T> 实例进行序列化和反序列化。 异步序列化方法枚举对象图中的任何 IAsyncEnumerable<T> 实例,然后将其序列化为 JSON 数组。 对于反序列化,添加了新方法 JsonSerializer.DeserializeAsyncEnumerable<TValue>(Stream, JsonSerializerOptions, CancellationToken) 。 有关详细信息,请参阅 IAsyncEnumerable 序列化

其他新 API

用于验证和默认值的新序列化接口:

有关详细信息,请参阅 回调

新的属性排序特性:

编写“raw”JSON 的新方法:

同步序列化和反序列化到流:

在序列化期间检测到引用周期时忽略对象的新选项:

有关使用序列化和反序列化 System.Text.Json的详细信息,请参阅 .NET 中的 JSON 序列化和反序列化

HTTP/3

.NET 6 包括对 HTTP/3 的预览支持,这是 HTTP 的新版本。 HTTP/3 通过使用名为 QUIC 的新基础连接协议来解决一些现有的功能和性能难题。 QUIC 更快地建立连接,连接独立于 IP 地址,允许移动客户端在 Wi-fi 和手机网络之间漫游。 有关详细信息,请参阅 将 HTTP/3 与 HttpClient 配合使用

ASP.NET Core

ASP.NET Core 包括对最小化 API 的改进,对 Blazor WebAssembly 应用程序的提前(即时)编译(AOT),以及单页应用程序的改进。 此外,Blazor 组件现在可以从 JavaScript 呈现,并与基于 JavaScript 的现有应用集成。 有关详细信息,请参阅 ASP.NET Core 6 中的新增功能

OpenTelemetry

.NET 6 为 OpenTelemetry 提供了改进的支持,OpenTelemetry 是一系列工具、API 和 SDK,可帮助你分析软件的性能和行为。 命名空间中的 System.Diagnostics.Metrics API 实现 OpenTelemetry 指标 API 规范。 例如,有四个检测类支持不同的指标方案。 仪器类别包括:

安全性

.NET 6 增加了对两项关键安全缓解措施的预览支持:控制流强制技术(CET)和“写入独占执行”(W^X)。

CET 是一种 Intel 技术,在某些较新的 Intel 和 AMD 处理器中可用。 它为防止某些控制流劫持攻击的硬件添加了功能。 .NET 6 为 Windows x64 应用提供 CET 支持,必须显式启用它。 有关详细信息,请参阅 .NET 6 与 Intel CET 阴影堆栈的兼容性

W^X 可用于使用 .NET 6 的所有操作系统,但默认仅在 Apple Silicon 上启用。 W^X 禁止同时写入和可执行内存页来阻止最简单的攻击路径。

IL 剪裁

独立部署的剪裁得到了改进。 在 .NET 5 中,只剪裁了未使用的程序集。 .NET 6 也会添加未使用的类型和成员的移除。 此外,默认情况下,裁剪警告会提醒你哪些地方的裁剪可能会删除在运行时使用的代码。 有关详细信息,请参阅 剪裁独立部署和可执行文件

代码分析

.NET 6 SDK 包括一些新的代码分析器,这些分析器涉及 API 兼容性、平台兼容性、修整安全性、在字符串串联和拆分中使用范围、更快的字符串 API 和更快的收集 API。 有关新的(和已删除)分析器的完整列表,请参阅 分析器版本 - .NET 6

自定义平台防护

平台兼容性分析器将类Is<Platform>中的OperatingSystem方法,例如OperatingSystem.IsWindows(),识别为平台保护器。 为了允许自定义平台防护,.NET 6 引入了两个新属性,可用于对字段、属性或方法添加支持或不支持的平台名称:

Windows 窗体

Application.SetDefaultFont(Font) 是 .NET 6 中的一个新方法,用于跨应用程序设置默认字体。

C# Windows 窗体应用的模板已更新,以支持 global using 指令、文件范围的命名空间和可为 null 的引用类型。 此外,它们还包括应用程序启动代码,这可减少样板代码,并允许 Windows 窗体设计器以首选字体呈现设计图面。 启动代码是对ApplicationConfiguration.Initialize()的调用,它是一种源生成的方法,可用于调用其他配置方法,例如Application.EnableVisualStyles()。 此外,如果通过 ApplicationDefaultFont MSBuild 属性设置非默认字体, ApplicationConfiguration.Initialize() 则发出调用 SetDefaultFont(Font)

有关详细信息,请参阅 Windows 窗体的最新动态 博客文章。

源代码构建

源代码包 (tarball) 包含 .NET SDK 的所有源代码,现在由 .NET SDK 构建生成。 其他组织(如 Red Hat)可以使用此源 tarball 生成自己的 SDK 版本。

目标框架标识

为 .NET 6 添加了其他特定于 OS 的目标框架名字对象(例如,net6.0-androidnet6.0-iosnet6.0-macos)。 有关详细信息,请参阅 特定于 OS 的TFM

泛型数学

预览版 中,能够对 .NET 6 中的泛型类型使用运算符。 .NET 6 引入了许多接口,这些接口使用 C# 10 的新预览功能( static abstract 接口成员)。 这些接口对应于不同的运算符,例如, IAdditionOperators 表示 + 运算符。 这些接口在 System.Runtime.Experimental NuGet 包中可用。 有关详细信息,请参阅 泛型数学 博客文章。

NuGet 包验证

如果你是 NuGet 库开发人员,可以使用新的 包验证工具 来验证包是否一致且格式正确。 你可以确定是否:

  • 是否存在包版本的破坏性变更。
  • 对于所有特定于运行时的实现,该包具有相同的公共 API 集。
  • 目标框架或运行时适用性是否存在差距。

有关详细信息,请参阅 包验证 博客文章。

反射 API

.NET 6 引入了以下新 API,可用于检查代码并提供可空性信息:

这些 API 对于基于反射的工具和序列化程序非常有用。

Microsoft.Extensions API接口

如下表所示,多个扩展命名空间在 .NET 6 中进行了改进。

Namespace 改进
Microsoft.Extensions.DependencyInjection CreateAsyncScope允许你安全地为注册using服务的服务提供商使用IAsyncDisposable语句。
Microsoft.Extensions.Hosting ConfigureHostOptions 方法简化了应用程序设置。
Microsoft.Extensions.Logging Microsoft.Extensions.Logging 具有用于高性能日志记录 API 的新源生成器。 如果将新的 LoggerMessageAttribute 源生成器添加到 partial 日志记录方法,则会触发源生成器。 在编译时,生成器生成方法的 partial 实现,该方法在运行时通常比现有日志记录解决方案更快。 有关详细信息,请参阅 编译时日志记录源生成

新的 LINQ API

.NET 6 中添加了许多 LINQ 方法。 在下表中列出的新方法中,大多数在System.Linq.Queryable类型中都有等效的方法。

方法 Description
Enumerable.TryGetNonEnumeratedCount<TSource>(IEnumerable<TSource>, Int32) 尝试在不强制枚举的情况下确定序列中的元素数。
Enumerable.Chunk<TSource>(IEnumerable<TSource>, Int32) 将序列的元素拆分为指定大小的区块。
Enumerable.MaxByEnumerable.MinBy 使用键选择器查找最大或最小元素。
Enumerable.DistinctByEnumerable.ExceptByEnumerable.IntersectByEnumerable.UnionBy 这些执行基于集的操作的方法的新变体使您能够使用键选择器函数指定相等性。
Enumerable.ElementAt<TSource>(IEnumerable<TSource>, Index)Enumerable.ElementAtOrDefault<TSource>(IEnumerable<TSource>, Index) 接受从序列的开头或结尾计数的索引,例如 Enumerable.Range(1, 10).ElementAt(^2) 返回 9
Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, TSource)Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)
Enumerable.LastOrDefault<TSource>(IEnumerable<TSource>, TSource)Enumerable.LastOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)
Enumerable.SingleOrDefault<TSource>(IEnumerable<TSource>, TSource)Enumerable.SingleOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)
通过新的重载,可以指定在序列为空时要使用的默认值。
Enumerable.Max<TSource>(IEnumerable<TSource>, IComparer<TSource>)Enumerable.Min<TSource>(IEnumerable<TSource>, IComparer<TSource>) 使用新的重载可以指定比较器。
Enumerable.Take<TSource>(IEnumerable<TSource>, Range) 接受参数 Range 以简化获取序列的切片,例如,可以使用 source.Take(2..7) 而不是 source.Take(7).Skip(2)
Enumerable.Zip<TFirst,TSecond,TThird>(IEnumerable<TFirst>, IEnumerable<TSecond>, IEnumerable<TThird>) 生成一个元组序列,其中的元素来自于指定的 三个 序列。

日期、时间和时区改进

在 .NET 6 中添加了以下两个结构: System.DateOnlySystem.TimeOnly。 它们分别表示DateTime的日期部分和时间部分。 DateOnly 对于生日和周年纪念日非常有用, TimeOnly 适用于每日警报和每周营业时间。

现在可以在任何安装了时区数据的作系统上使用 Internet 分配号码颁发机构(IANA)或 Windows 时区 ID。 如果系统上找不到所请求的时区,则 TimeZoneInfo.FindSystemTimeZoneById(String) 该方法已更新为自动将其输入从 Windows 时区转换为 IANA 时区(反之亦然)。 此外,在仍需要手动从一种时区格式转换为另一种时区格式时,已针对方案添加了新方法TryConvertIanaIdToWindowsId(String, String)TryConvertWindowsIdToIanaId

还有一些其他时区改进。 有关详细信息,请参阅 .NET 6 中的日期、时间和时区增强功能

PriorityQueue 类

PriorityQueue<TElement,TPriority> 类表示同时具有值和优先级的项的集合。 项按递增优先级顺序出队列,即首先出队列优先级值最低的项。 此类实现 最小堆 数据结构。

另请参阅