3.空条件赋值(Null Conditional Assignment)
public int Foo { get; set; }如果需要在 get 或 set 中添加自定义逻辑,就得手动添加一个“后备字段”:
private int _foo; publicint Foo { get { // 执行某些逻辑 return _foo; } set { // 额外逻辑 _foo = value; // 更多逻辑 } }虽然功能强大,但这种写法冗长。从 C# 14 开始,field 关键字带来了全新的简洁写法,允许你在不显式声明后备字段的情况下,编写带逻辑的属性访问器:
public int Foo { get { // 自定义逻辑 return field; } set { // 前置逻辑 field = value; // 后置逻辑 } }在编译时,field 会被自动替换为一个由编译器生成的后备字段,等价于:
[CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int <Foo>k__BackingField; public int Foo { get => <Foo>k__BackingField; set => <Foo>k__BackingField = value; }这种方式兼具可读性与灵活性,是自动属性与传统属性之间的理想折中方案。
internal sealedclassSpecialList<T> { public List<T> Items { get; privateset; } = new(); public void Add(T item) => Items.Add(item); } internalstaticclassExtensionMembers { publicstaticvoid InsertOne<T>(this SpecialList<T> source, int index, T item) { if (index < 0 || index > source.Items.Count) thrownew ArgumentOutOfRangeException(nameof(index)); source.Items.Insert(index, item); } }而 C# 14 引入的新写法更为直观:
internal staticclassExtensionMembers { publicstaticvoid Insert<T>(this SpecialList<T> source, int index, T item) { if (index < 0 || index > source.Items.Count) thrownew ArgumentOutOfRangeException(nameof(index)); source.Items.Insert(index, item); } publicstaticint Count<T>(this SpecialList<T> source) => source.Items.Count; }此外,C# 14 引入了新的 extension 块语法,进一步增强了功能:支持定义 静态扩展成员。
internal static class ExtensionMembers { extension<T>(SpecialList<T>) { public static bool IsEmpty(IEnumerable<T> source) => !source.Any(); } }这样你就可以直接通过类型调用扩展成员:
Console.WriteLine(SpecialList<int>.IsEmpty(new[] { 1, 2, 3 }));示例用法:
var specialList = new SpecialList<int>(); specialList.Add(1); specialList.Add(2); specialList.Add(4); // 堆代码 duidaima.com // 调用扩展方法 specialList.Insert(2, 3); specialList.InsertOne(2, 3); foreach (var item in specialList.Items) { Console.WriteLine(item); } Console.WriteLine($"Count: {specialList.Count}"); Console.WriteLine($"IsEmpty: {SpecialList<int>.IsEmpty(new int[] { 1, 2, 3 })}");输出结果:
1 2 3 3 4 Count: 5 IsEmpty: False三、空条件赋值(Null-Conditional Assignment):让空检查更优雅
foo?.Demo();这段代码表示:仅当 foo 不为 null 时才调用 Demo() 方法。然而,如果我们想对一个对象的属性进行赋值操作,就不得不手动加判断:
if (foo is not null) { foo.Bar = 20; }而在 C# 14 中,这种写法可以被简化为:
foo?.Bar = 20;也就是说,只有在 foo 不为 null 时,Bar 才会被赋值为 20。该功能同样适用于复合赋值操作符,如 +=、-= 等:
foo?.Bar += 10;这让代码更加简洁优雅。