.NET 11 在 11 月 10 日正式发布。这是 STS(标准支持期)版本,两年支持,不是 LTS——.NET 10 仍然是那个长期支持的选项。版本号本身没什么好说的,值得看的是这次几个实打实的变化。

C# 15:union types 终于来了
把这条放最前面,因为它解决的是一个困扰 C# 很久的问题。
以前写一个「要么返回结果、要么返回错误」的方法,只有两条路:定义一个共同的父类,或者用 object 兜着。前者要求你为了返回值去改类的继承结构,后者直接丢掉类型安全。
C# 15 加了 union types。官方给的例子是这样:
ProductLookup result = new Product(42, "Mechanical keyboard");
string message = result switch
{
Product product => $"Found {product.Name}",
ProductNotFound missing => $"No product with ID {missing.Id}",
};
public sealed record Product(int Id, string Name);
public sealed record ProductNotFound(int Id);
public union ProductLookup(Product, ProductNotFound);
关键在于编译器能做穷尽性检查。返回值类型本身就告诉调用方「你只有这几种情况要处理」,少写一个分支会编译报错。
同时加的还有 closed hierarchies(封闭继承体系):把一个类标记为封闭后,只允许在声明它的程序集内部派生,编译器因此能对继承层次做模式匹配检查。
两者分工很清楚:union 用来组合已有的类型,closed hierarchy 适合你自己控制继承关系的模型。
另外还有几个小改动值得一提。collection expression 现在可以带构造参数:
HashSet<string> names = [with(StringComparer.OrdinalIgnoreCase), "Alice", "ALICE", "Bob"];
这段会打印 2——大小写不敏感的比较器生效了。还有 extension indexers,以及带标签的 break 和 continue。这几个都不需要开 preview。
日常开发变快的地方
SDK 有两处改动直接冲着「每天都要等」的地方去。
Native AOT CLI host 默认开启。 像 help、version 这类命令现在不用启动托管 CLI 就能跑完。
MSBuild server 默认常驻。 两次命令之间不再反复冷启动。Linux 和 macOS 的安装包也通过程序集去重变小了。
对跑 CI 的团队,还有几个具体的改善:dotnet test 加了运行级超时、失败数量上限、更清楚的进度显示;容器发布支持通过 SOURCE_DATE_EPOCH 生成可复现的镜像 digest,目标清单已存在时跳过重复的层上传。
NuGet 还加了个挺实用的策略——最小包发布年龄。可以设置让新发布的包过一段时间才有资格被选中。官方特别声明这是额外的策略控制,不能替代漏洞检查。
Runtime Async:还没正式启用,但值得关注
这是 .NET 11 预览期一直在讲的东西,正式版里仍然是 preview。
它的做法是把异步的挂起和恢复交给运行时处理,不再依赖编译器生成的状态机。一个直接可见的好处是实时调用栈变干净了——性能分析器和调试器能直接显示异步方法本身,而不是执行它的那套基础设施。
要在 net11.0 项目里试,加一行 <Features>runtime-async=on</Features> 就行,不需要开 EnablePreviewFeatures。类库本身已经用 Runtime Async 构建了,但把自己的代码切过去是独立的选择。官方建议先测依赖和诊断工具。
AI 工具链:MCP 模板进了 SDK
这是这次最值得单独说的部分。
SDK 里内置了 MCP server 模板。 一条命令就能起一个可用的 MCP 服务:
dotnet new mcpserver -o MyMcpServer
模板用的是官方 MCP C# SDK,自带一个能跑的示例工具,不用先装额外的模板包。
配套还有三层:Microsoft.Extensions.AI(MEAI)提供 IChatClient、IEmbeddingGenerator 这类抽象,把模型访问和依赖注入、缓存、OpenTelemetry 串起来;Microsoft Agent Framework(MAF)在抽象之上提供带工具调用和会话状态的 agent,以及协调多个 agent 的工作流;最后通过 ASP.NET Core 的 AG-UI 端点把 agent 暴露成 Blazor 交互界面——不过 AG-UI 托管集成目前还是预览状态。
另外 dotnetup 这个工具链管理器进了公开预览,可以在用户账户级别安装和更新 SDK,方便管并存的多个版本。
库和 EF Core 的变化
几个能省事的东西:
System.IO.Compression 原生支持 Zstandard。 以前要引第三方库。
Process API 加了单次调用方法,跑一个进程、拿输出和退出码一行搞定;需要细控的还有继承句柄、挂起启动、进程信号这些。
四个新的内存流适配器:ReadOnlyMemoryStream、WritableMemoryStream、ReadOnlySequenceStream、StringStream。比如管道里的分段 ReadOnlySequence<byte> 可以直接当流读,不用先拍平成一个连续缓冲区——省一次内存拷贝。
LINQ 加了 FullJoin,两侧未匹配的元素都保留。对账场景用得上,比现在自己拼 GroupJoin 清爽。
System.Text.Json 支持 C# union 和 F# 判别联合,以及从异步序列输出 JSON Lines。但要注意 F# union 支持走的是反射,不支持源生成、裁剪和 Native AOT——用到裁剪的项目得先看清限制。
EF Core 11 方面:更多场景下能去掉多余的 join,GroupBy 翻译改进,新的 FullJoin 在支持的关系型提供程序上也能翻译。SQL Server 用户多了个新东西——向量索引和近似向量搜索支持,不过官方标注为实验性。
要不要升
.NET 11 是 STS,两年支持期。如果你在用 .NET 10 的 LTS、对稳定性要求高,没有必须立刻升的理由。

但有两类人值得早点看:一是被 SDK 启动速度折磨的,AOT CLI host 和常驻 MSBuild server 是白捡的改善;二是打算给现有系统接 AI 能力的,MCP 模板进 SDK 这件事降低了起步门槛。
C# 15 的 union types 是那种「一旦用上就回不去」的东西,但它也会改变你写返回值的方式,团队需要时间适应。
参考来源