开发与编程 Sep 3, 2026加入收藏

微软通过 *The Register* 确认,C# 将在 2026 年 11 月引入联合类型(union types)。这一功能在 TypeScript、Rust、Swift 和 F# 中早已存在,它将改变 C# 中业务状态建模的方式。
我们在 C# 中写过多少次这样的代码来表示一个可以采用三种不同形式的状态呢?
public class RésultatPaiement
{
public bool EstSuccès { get; set; }
public string? IdTransaction { get; set; }
public bool EstEnAttente { get; set; }
public string? RaisonAttente { get; set; }
public bool EstErreur { get; set; }
public string? CodeErreur { get; set; }
public string? MessageErreur { get; set; }
} 一个对象中三个互斥的布尔值,五个仅在与特定布尔值组合时才有意义的可空字段,以及编译器无法保证在 if/else 中不会遗漏某个情况。欢迎来到基于约定的建模,它依赖于开发者的自律——也就是说,几乎没有保障。
The Register 于 2026 年 9 月 2 日宣布,微软已确认 联合类型(也称为“区分联合”或“和类型”)将于 2026 年 11 月在 C# 中推出。
其理念很简单:与其用一个包含五个字段的对象来表示“可以是成功、等待或错误”,不如明确地告诉编译器该类型是 三种互斥情况中的一种,每种情况都有其相关的字段。
以伪 C# 为例(最终语法将由官方公布):
public union RésultatPaiement
{
Succès(string IdTransaction);
Attente(string Raison);
Erreur(string Code, string Message);
}
// 使用方式
switch (résultat)
{
case RésultatPaiement.Succès s:
Console.WriteLine($"交易 {s.IdTransaction}");
break;
case RésultatPaiement.Attente a:
Console.WriteLine($"等待中:{a.Raison}");
break;
case RésultatPaiement.Erreur e:
Console.WriteLine($"错误 {e.Code}:{e.Message}");
break;
// 编译器会检查是否遗漏了某个情况
} 编译器会 检查 switch 的完整性:遗漏某个情况将成为错误,而不是六个月后才在生产环境中发现的 bug。
F#,C# 在 .NET 生态系统中的函数式“表亲”,从一开始就拥有区分联合——这是该语言的历史卖点之一。Rust 将其作为设计核心(著名的 enum 和 match)。Swift 也是如此。TypeScript 以其方式从 2015 年起就支持联合类型。Kotlin 的 sealed class 也接近这种模式。C# 则一直落后——开发者不得不拼凑抽象类层次结构、sealed record,或使用第三方库如 OneOf<T1,T2,T3>。
这种新特性到来的三个具体影响:
OneOf 和 LanguageExt 等库将重新调整。 它们提供的一部分功能将成为原生支持;其余部分(单子、局部应用)仍然有用。|>、默认不可变性),但差距在缩小——在 .NET 项目中选择语言的问题变得更加复杂。C# 中的联合类型是 F# 对 C# 的渗透——这是 Mads Torgersen(C# 首席设计师)在过去几个版本中的编辑方针。对于我们的项目,最直接的好处在于建模 API 结果(成功/错误/部分)、工作流状态(草稿/审核中/已发布)和 多态负载(事件溯源、Kafka 消息)。
这并非革命性变化——其他主要语言早在十年前就已支持。但对于以 C# 为主导业务逻辑语言的 .NET 企业生态系统而言,这是 类型可靠性的一次质的飞跃。建议从 11 月的预览版开始测试。
本文由人工智能撰写,并经人工编辑审核。