发布于 

C# Next: Field关键字-半自动实现属性

现在还用不了^_^

原计划 C#11 可用,现在跳票到 C#12,不确定何时可用。

C# 3.0 新增了自动实现属性,编译器会自动生成一个匿名、私有的字段来保存值,仅访问器可使用。

1
public string Prop { get; set; }

然而,我们有时需要给 Get、Set 或 Init 访问器添加自定义逻辑,例如:

  • 验证输入值是否合法
  • 通知值已更新(…INotifyPropertyChanged.PropertyChanged

这时自动实现属性便无法胜任,只能使用传统写法,自己创建一个字段:

1
2
3
4
5
6
7
8
9
10
private string _prop;
public string Prop
{
get => _prop;
set
{
ArgumentException.ThrowIfNullOrEmpty(value, nameof(Prop));
_prop = value;
}
}

这样做后有这样几个问题:

  1. _prop 可以被类中其他部分访问,有潜在隐患。
  2. 增加了代码量,可读性下降。

在即将到来的 C# 12 中,我们可以使用 field 关键字,来实现半自动属性。半自动属性与全自动属性类似,编译器都会生成辅助字段,但该字段可以在访问器块中使用 field 来访问。因此,我们的代码可以简化成:

1
2
3
4
5
6
7
8
9
10
public string Prop
{
// No more _prop, compiler generates it automatically as the `field` keyword.
get => field;
set
{
ArgumentException.ThrowIfNullOrEmpty(value, nameof(Prop));
field = value;
}
}
SharpLab.io C# and decompiled c# code of field keyword
SharpLab.io C# and decompiled c# code of field keyword

SharpLab.io C# and decompiled C# Code

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
namespace SemiAutoProperty;

using System;
public class User
{
// Use of field: semi-auto property.
// In this case, a constraint is applied to setter.
public required string Name
{
get => field;
set
{
ArgumentException.ThrowIfNullOrEmpty(value, nameof(Prop));
field = value;
}
}

// No accessor body: auto property.
public string Nickname {get; set;} = String.Empty;

public User() {}

[System.Diagnostics.CodeAnalysis.SetsRequiredMembers]
public User(string name):this() => Name = name;
}

internal static class Program{
private static void Main()
{
var f = new User()
{
Name="John",
};
Console.WriteLine(f.Name);

try
{
f.Name = "";
}
catch (ArgumentException)
{
Console.WriteLine("ArgumentException Thrown");
}
}
}

本站由 @C2iCs 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本"页面"访问 次 | 👀总访问 次 | 🥷总访客