// in the background... [CompilerGenerated] privatestring <Prop>k__BackingField;
但我们有时候要给Getter和Setter添加自定义逻辑,例如
验证输入值是否合法
通知值已更新(…INotifyPropertyChanged.PropertyChanged)
这时自动实现属性便无法胜任,只能使用传统写法,自己创建一个字段:
1 2 3 4 5 6 7 8 9 10
privatestring _prop; publicstring Prop { get => _prop; set { ArgumentException.ThrowIfNullOrEmpty(value, nameof(Prop)); _prop = value; } }
这样做后有这样几个问题:
_prop 可以被类中其他部分访问,有潜在隐患。
增加了代码量,可读性下降。
在即将到来的 C# 12 中,我们可以使用 field 关键字,来实现半自动属性。半自动属性与全自动属性类似,编译器都会生成辅助字段,但该字段可以在访问器块中使用 field 来访问。因此,我们的代码可以简化成:
1 2 3 4 5 6 7 8 9 10
publicstring Prop { // No more _prop, compiler generates it automatically accessed by the `field` keyword. get => field; set { ArgumentException.ThrowIfNullOrEmpty(value, nameof(Prop)); field = value; } }
SharpLab.io C# and decompiled c# code of field keyword
namespaceSemiAutoProperty; using System; publicclassUser { // 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. publicstring Nickname {get; set;} = String.Empty; publicUser() {} [System.Diagnostics.CodeAnalysis.SetsRequiredMembers] publicUser(string name):this() => Name = name; } internalstaticclassProgram{ privatestaticvoidMain() { var f = new User() { Name="John", }; Console.WriteLine(f.Name); try { f.Name = ""; } catch (ArgumentException) { Console.WriteLine("ArgumentException Thrown"); } } }