1. 引言:把不确定性收进类型里
2026 年 11 月 10 日,.NET Conf 2026 开幕当天,微软正式发布 .NET 11。这是一个标准期限支持(STS)版本,提供两年支持;.NET 10 仍是当前的 LTS 选项。
如果只用一个词概括这一版,那就是——把不确定性收进类型里:
- C# 15 的联合类型,让「一个操作只有这几种结果」从口头约定变成编译器能检查的契约;
- Runtime Async 把异步状态机从编译器生成的代码里搬进运行时;
- SDK 默认启用 Native AOT CLI,
dotnet命令的等待感明显变短。
下面按开发者最关心的几条线拆开看。
2. C# 15:联合类型转正,编译器帮你「查漏」
C# 15 是 .NET 11 的默认语言版本,主要特性无需 preview 开关即可使用。最值得关注的是联合类型(union types)。
过去的常见写法是:一个方法要么返回结果,要么返回 null,要么抛异常——调用方只能靠文档和记忆去猜。联合类型把「可能的结果集合」直接写进返回类型:
public sealed record Product(int Id, string Name);
public sealed record ProductNotFound(int Id);
public union ProductLookup(Product, ProductNotFound);
调用侧用 switch 处理时,编译器会检查你是否覆盖了所有分支。如果将来给 union 新增一种 case,所有漏掉该分支的 switch 会直接给出警告,而不是等到运行时才暴露。
微软 C# 团队 Bill Wagner 的总结很直接:「编译器在构建时抓住缺失的分支,而不是运行时。」
和联合类型配套的还有封闭层次结构(closed hierarchies):用 closed 修饰的类,只允许在其声明程序集内派生,编译器因此知道全部直接子类型,switch 不需要 default 分支也能通过穷尽性检查。
两者定位不同:
- 联合类型:适合组合你已有的类型;
- 封闭层次:适合你自己掌控继承关系的模型。
此外,几个「日常顺手」的特性也稳定了:
- ✅ 集合表达式可以传构造参数
- ✅ 扩展索引器
- ✅ 带标签的
break/continue
⚠️ 需要留意:联合类型的简写声明,在性能敏感代码中会对值类型产生装箱。库作者可以通过非装箱的自定义 union 模式规避,普通业务代码一般不需要为此改变写法。
3. 运行时与性能:几百项优化,很多不需要改代码
Stephen Toub 的年度性能长文覆盖了 .NET 11 中数百项 JIT 和基础库优化,其中相当一部分效果,不需要修改源码或重新设计逻辑就能吃到。
JIT 这一版的重点是:把冗余证明掉。
- 边界检查消除
- 冗余
checked移除 - 去虚拟化
SequenceEqual常量折叠- 冗余分支消除
一些微基准里,byte 求最大值比 .NET 10 快了接近 4 倍,已经纯向量化。
更长远的变化是 Runtime Async:把异步的挂起/恢复从编译器生成的状态机下移到运行时。直接好处之一是:调试器和性能分析器看到的实时调用栈更干净,异步方法本身更直接地出现在栈上,而不是一堆状态机基础设施帧。
Runtime Async 在 .NET 11 中仍是预览特性,需要手动开启:
<PropertyGroup>
<Features>runtime-async=on</Features>
</PropertyGroup>
⚠️ 一旦开启,不需要再额外打开
EnablePreviewFeatures。建议先在非关键路径上测试,再考虑扩大范围。
4. SDK 与工具链:dotnet 命令的「启动税」降了
.NET 11 的 SDK 做了两件对日常手感影响很直接的事。
第一,Native AOT CLI 宿主默认启用。dotnet --help、dotnet --version 这类命令不再需要启动完整的托管 CLI,几乎瞬间返回;需要托管执行的命令仍然走原路径,不影响功能。
第二,MSBuild 服务器在多次 CLI 调用之间保持预热,减少每次构建反复启动的开销。
其他值得知道的:
- 📦 Linux 和 macOS 安装包通过程序集去重变得更小
- 📄 基于文件的应用可以通过
#:include跨多个源文件 - 🛡️ NuGet 新增最低包发布年龄设置,团队可以选择延迟消费刚发布的包版本,作为供应链策略的补充控制
5. Web 与 AI:异步验证、Blazor AI 组件、Agent 开发栈
ASP.NET Core 11 最实用的一项改进是:异步验证。过去「用户名是否已存在」「邮箱是否已被注册」这类需要查数据库或调外部服务的校验,往往要绕开标准验证管道。现在 Minimal APIs 和 Blazor 表单可以直接使用异步验证器,表单提交管道会 await 异步校验,并支持取消和 pending 状态上报。
OpenAPI 生成默认版本升到 3.2,下游工具需要旧版时可以显式选择。
Blazor 方面,实验性的 Blazor AI 组件(Microsoft.AspNetCore.Components.AI,预发布包)把流式响应、工具调用、人工审批和共享状态,做成了 Razor 组件可以渲染和控制的「内容块」。Agent 交互不再是一堆手写的 div 和事件回调,而是框架一等公民的 UI 构件。
AI 开发栈的主线是三层:
- Microsoft.Extensions.AI(MEAI):提供
IChatClient等模型访问抽象 - MCP:作为工具集成的通用协议,SDK 已内置
dotnet new mcpserver模板 - Microsoft Agent Framework(MAF):在两者之上提供带工具调用和对话状态的 Agent,以及编排多个 Agent 的工作流
MAF 和 MCP 本身不要求你先把应用整体迁到 .NET 11,它们以 NuGet 包形式提供,可以逐步引入。
6. 基础库:Zstd、Process API、JSON 的实用增量
📦 压缩
Zstandard 压缩进入 System.IO.Compression,提供 ZstandardStream 和基于 span 的压缩 API;读取 ZIP 时新增 CRC32 校验。
⚙️ Process API
一次性「运行并捕获输出和退出码」的方法、fire-and-forget 启动、挂起启动、SafeProcessHandle 生命周期管理。
🧩 JSON
System.Text.Json 原生支持 C# 联合类型和 F# 可区分联合的序列化。注意:F# union 支持基于反射,不兼容 trimming 和 Native AOT,裁剪场景需要留意。
🔗 LINQ
新增 FullJoin,保留两侧未匹配的元素,适合对账类场景。
7. 升级前需要知道的两件事
第一,.NET 11 是 STS,不是 LTS。
如果你所在的项目对支持周期有硬性要求,.NET 10 仍然是当前的 LTS 选择。.NET 11 适合愿意跟随年度节奏、希望尽早吃到语言和工具链改进的团队。
第二,一部分醒目的能力仍是实验性或预览状态。
Runtime Async 需要显式开启 · Blazor AI 组件是预发布包 · AG-UI 托管集成仍为 prerelease。正式版发布,不等于其中每一项都已达到生产就绪标准。选型时,需要区分「稳定特性」和「可以开始试的特性」。
8. 一句话收尾
.NET 11 最实在的升级,不在于某一个跑分数字,而在于它开始系统性地把「运行时才暴露的问题」往编译期和工具链前端挪。联合类型管契约,Native AOT CLI 管等待,异步验证管网络边界上的校验。
如果你已经在 .NET 10 上,挑一个非关键项目先升上去,用你自己的负载量一遍,比任何基准都准。
你的团队打算升级 .NET 11 吗?评论区聊聊 👇