我建议从 C# 8.0 开始阅读以下内容,了解每个 C# 版本的新功能。
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
在早期,我们习惯于实现如下属性:
private string userName;
public string UserName
{
get { return userName; }
set { userName = value; }
}
因此,当您反编译具有该属性的类的程序集时,您会看到与此完全一样的反编译器输出。
从 C# 2.0 开始,并且一直在改进,现在有多种方法可以在 C# 中实现属性。
public string StringProperty1 => "String Property Value";
public string StringProperty2 { get; private set; }
public ICollection<double> Grades { get; } = new List<double>();
这里有什么共同点?
它们没有可读取或写入的字段。此类声明的字段由编译器创建并存储在名为PrivateImplementationDetails 的结构中。这不必是一个单独的字段。这只是运行时访问属性的自动生成的私有支持字段的方式。
例如,对于名为 AProperty 的 int[] 属性,将生成以下 IL:
.field private int32[] '<AProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
当您查看设置此属性的此类的构造函数 IL 时,您会看到它正在访问(支持)字段,如下所示:
IL_0009: ldc.i4.3
IL_000a: newarr [mscorlib]System.Int32
IL_000f: dup
IL_0010: ldtoken field valuetype '<PrivateImplementationDetails>{3CA49917-EFBC-4E01-A884-1CFF6283A97C}'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>{3CA49917-EFBC-4E01-A884-1CFF6283A97C}'::'$$method0x6000029-1'
IL_0015: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
最后,您在反编译器输出中看到的意思是,它正在设置私有自动生成的字段。