随着 C# 语言迎来 14 版本(伴随 .NET 10),许多长期困扰开发者的“样板代码”终于可以通过语法糖优雅地解决了。本文带你全面了解 C# 14 的主要语法改进,并配以简明示例。
C# 14 核心新特性
扩展成员(Extension Members)
C# 14 引入了新的 extension 语法块 —— 不仅可以定义传统的扩展方法,还能为已有类型添加扩展属性、扩展运算符,甚至静态扩展成员。这样你可以在不修改原类型定义的情况下,为其贴上新的能力。
public static class StringExtensions
{
extension(string s)
{
public bool IsNullOrEmpty => string.IsNullOrEmpty(s);
}
}
// 用法
string maybe = null;
if (maybe.IsNullOrEmpty)
{
// …
}
相比以往只能通过 public static bool IsNullOrEmpty(this string s) 的方式,现在写法更贴近日常成员定义,语义更清晰,也更易维护。
field 关键字:简化属性逻辑
之前,如果你希望某个属性在设置时带上校验逻辑(例如 null 检查),通常需要手动声明私有 backing-field,再写完整的 getter 和 setter。
C# 14 允许你在自动属性基础上,用 field 关键字简写逻辑:
public string Name
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
这样既保留了自动属性简洁性,又能在 setter(或 getter)中插入自定义逻辑,减少样板代码。
空条件赋值(Null-Conditional Assignment)
空条件访问 (?.) 与索引访问 (?[]) 之前主要用于读取 — C# 14 拓展了它们在赋值语境下的支持,你可以写:
customer?.Order = newOrder;
customer?.Total += delta;
如果 customer 为 null,上述赋值/复合赋值将被跳过。这让代码在涉及 null 检查时更清晰、更简洁。
nameof 支持未绑定泛型
以往 nameof 用于泛型类型时,必须写成具体类型 (closed generic) — 比如 nameof(List<int>)。C# 14 允许你对未绑定泛型 (open generic) 使用 nameof,例如 nameof(List<>),它会返回 "List"。这简化了日志、调试、反射等场景中对类型名称的获取。
隐式 Span 转换
C# 14 增强了对 Span<T> 和 ReadOnlySpan<T> 的一流支持。新增的隐式转换让 T[]、Span<T>、ReadOnlySpan<T> 能在更多场景下互操作,减少手动转换和不必要的内存分配,非常适合对性能敏感、对内存操作频繁的代码。
简化 Lambda 参数修饰符
在 lambda 表达式中,以前如果需要 ref / out / in / scoped / ref readonly 等修饰符,就必须同时指定参数类型。C# 14 允许你直接在 lambda 的简单参数上加修饰符,而无需写类型。例如:
delegate bool TryParse<T>(string text, out T result);
// …
TryParse<int> parser = (text, out result) => int.TryParse(text, out result);
这样的写法让 lambda 更简洁,也减少冗余类型声明。
部分构造函数 & 部分事件 (partial constructors & partial events)
对于使用源代码生成 (Source-Generator) 的项目,C# 14 支持将构造函数和事件拆分为声明 (definition) 与实现 (implementation) 两部分。这种设计非常适合自动化生成代码 + 人手补充逻辑的场景,提高了代码组织和可维护性。
用户定义复合赋值运算符 (User-Defined Compound Assignment)
如果你有自定义类型 (如结构体):可以为它定义自己的 +=, -= 等复合赋值运算符,从而让自定义类型在语义和语法上更接近内建类型。对于涉及数值、向量、矩阵等高性能计算 / 数学逻辑的类型尤其有价值,也减少了不必要的中间对象创建。
为什么这些新特性值得关注
- 减少样板代码:
extension members、field、lambda 修饰符 等让代码更精炼,业务逻辑更突出。 - 提升可读性与语义清晰度:对已有类型添加扩展属性/运算符,看起来像“原生”成员;空条件赋值消除了大量 null 判断。
- 性能优化:隐式 Span 转换 + 自定义复合赋值对高性能、低分配场景友好。
- 更好适配现代开发流程:部分成员 + 源生成特性让自动化生成 + 手写逻辑协作更顺畅。
- 兼容与渐进迁移:这些语法糖主要是语言层面的增强,对旧代码兼容性好,可逐步切换使用,无需一次性大规模重构。
示例:结合使用的新风格
public static class MyExtensions
{
extension(string s)
{
public bool IsEmpty => string.IsNullOrEmpty(s);
}
}
public struct Vector2
{
public float X;
public float Y;
public void operator +=(Vector2 other)
{
X += other.X;
Y += other.Y;
}
}
class Demo
{
public string Name
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
void Process(string? input)
{
if (!input.IsEmpty) {
Console.WriteLine($"{Name}: {input}");
}
Span<byte> buffer = new byte[256];
// 可以直接使用隐式转换 + span 操作…
}
}
上面的代码示例展示了 C# 14 如何让类型扩展、属性简化、null 安全、Span 操作与自定义类型运算都变得自然、优雅。
小结
C# 14 虽然没有引入颠覆性的范式改变,但它通过语言层面的语法糖优化,显著提升了日常开发的便利性、代码可读性和性能潜力。对于长期使用 C# 的开发者而言,这是一次“润色与提效”的重大升级。
如果你已经习惯传统写法,不妨尝试用 C# 14 的新特性逐步改写部分代码 — 从扩展属性、field 简化属性,到隐式 Span、复合赋值运算符等,不仅能让代码更整洁,也会让你更享受编码。