前言
今天咱们一起来看看在 C# 14 中新增的几个功能特性,是否给我们日常编码带了来便利。
前提准备
要体验 C# 14 中的新增功能,你需要安装最新的 Visual Studio 2022 版本或下载 .NET 10 SDK。
下载 .NET 10 SDK:https://dotnet.microsoft.com/zh-cn/download/dotnet/10.0

扩展成员(Extension Members)
从 C# 14 开始,可以使用两种语法来定义扩展方法。C# 14 添加了 extension 容器,可以声明扩展块,扩展块是包含类型或该类型的实例的扩展成员的非嵌套、非泛型静态类中的块。在 C# 14 之前,将修饰符添加到 this 静态方法的第一个参数,以指示该方法显示为参数类型的实例的成员。
下面的代码示例定义了 string 类型的扩展块。扩展块包含一个成员:计算字符串中单词的方法:
C# 14 之前:
namespace CustomExtensionMethods;
public static class MyExtensions
{
public static int WordCount(this string str) =>
str.Split([' ', '.', '?'], StringSplitOptions.RemoveEmptyEntries).Length;
}
C# 14 开始:
namespace CustomExtensionMembers;
public static class MyExtensions
{
extension(string str)
{
public int WordCount() =>
str.Split([' ', '.', '?'], StringSplitOptions.RemoveEmptyEntries).Length;
}
}
field 关键字
使用令牌 field 可以编写属性访问器体,而无需声明后备字段。令牌 field 将替换为编译器合成支持字段。
例如,C# 14 之前,如果要确保 string 属性无法设置为 null,则必须声明一个后备字段并实现这两个访问器:
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}
C# 14 开始,现在可以简化代码:
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
可以为字段支持的属性的一个或两个访问器声明一个主体。
隐式跨度转换
C# 14 在语言中引入了对 System.Span<T>
和 System.ReadOnlySpan<T>
的一流支持。这种支持包括新的隐式转换,使得使用这些类型进行编程更加自然。
在 C# 和运行时中,Span<T>
和 ReadOnlySpan<T>
被用于多种关键方式。他们的引入可提高性能,而不会造成安全风险。C# 14 识别其相互关系,并支持在 ReadOnlySpan<T>
、Span<T>
和 T[]
之间进行一些转换。跨度类型可以作为扩展方法的接收器、与其他转换组合,或者在泛型类型推理场景中提供帮助。
未绑定的泛型类型与nameof
从 C# 14 开始,nameof 的参数可以是未绑定的泛型类型。例如,nameof(List<>)
计算为 List
。在早期版本的 C# 中,只能使用关闭的泛型类型(例如 List<int>
)返回 List
名称。
带修饰符的简单 lambda 参数
从 C# 14 开始,可以在不指定参数类型的情况下,向 lambda
表达式参数添加参数修饰符,例如:scoped、ref、in、out或 ref readonly
。
支持更多部分成员(partial members)
从 C# 14 开始可以将实例构造函数
和事件
声明为部分成员(partial members)
。
注意:部分构造函数和分部事件必须包含一个定义声明和一个实现声明。
Null 条件赋值
Null 条件成员访问运算符“?.”
和“?[]”
现在可在赋值或复合赋值的左侧使用。
在 C# 14 之前,在分配给属性之前,需要对变量进行 null 检查:
public static void GetUserInfo()
{
UserInfo userInfo = null;
if (userInfo is not null)
{
userInfo.Age = CalculateAge(userInfo);
}
}
private static int CalculateAge(UserInfo userInfo)
{
return DateTime.Now.Year - userInfo.Birthday.Year;
}
在 C# 14 中可以使用运算符简化上述代码 ?.
:
注意:运算符 = 的右侧仅在左侧不为 null 时才会被计算。如果 userInfo 为 null,则代码不调用 CalculateAge。
public static void GetUserInfo()
{
UserInfo userInfo = null;
userInfo?.Name = CalculateAge(userInfo);
}
private static int CalculateAge(UserInfo userInfo)
{
return DateTime.Now.Year - userInfo.Birthday.Year;
}
参考文章
https://learn.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-14
https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
DotNetGuide编程学院
DotNetGuide编程学院是一个专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享的知识星球!当然这里不仅仅只有C#/.NET/.NET Core还有前端、云原生(Docker,K8s)、分布式,微服务、实用工具、学习书籍、AIGC、AI赋能、求职和招聘资讯、热点资讯等多个领域,我们致力于构建一个积极向上、和谐友善的.NET技术交流、学习平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。
大姚发放了100张DotNetGuide编程学院知识星球68元新人立减优惠券,有兴趣的小伙伴可以领券加入(当前应该是星球最优惠的阶段),加入后如果感觉不值得,3天内知识星球APP右上角退出,直接全额退款,无任何套路!

免费开源的程序员简历模板
了解作者&获取更多学习资料
程序员常用的开发工具软件推荐
加入DotNetGuide技术社区交流群
.NET/.NET Core ORM框架资源汇总
C#/.NET/.NET Core开发者学习路线集
学习是一个永无止境的过程,你知道的越多,你不知道的也会越多,在有限的时间内坚持每天多学一点,你一定能成为你想要成为的那个人。不积跬步无以至千里,不积小流无以成江海!