记录属性的自定义属性会发生什么变化?

What happens to the custom attributes on records properties?

我试图通过反射 API 获取 dotnet 记录属性的 自定义属性 但没有成功!我用自定义属性注释了属性,但正如我在 ILDASM 中看到的那样,没有 属性,字段和方法成员也没有 自定义属性 。那么,编译器对该注释做了什么?

干脆试试dotnet new classlib然后在文件夹里新建一个DummyAttribute如:

public class DummyAttribute : System.Attribute {}

然后将Class1替换为:

public record Class1([Dummy] string Name){}

最后用dotnet build构建,在ILDASM中查看生成的dll。 属性 Name 缺少 DummyAttribute,您接下来可以观察到:

.property instance string Name()
{
  .get instance string app10_records_annotations.Class1::get_Name()
  .set instance void modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) app10_records_annotations.Class1::set_Name(string)
} // end of property Class1::Name

那个注释发生了什么?我们可以注释 dotnet 记录的属性吗?

该属性默认应用于构造函数参数。这是 IL 中的构造函数:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(string Name) cil managed
{
  .param [1]
  .custom instance void DummyAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       15 (0xf)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stfld      string Class1::'<Name>k__BackingField'
  IL_0007:  ldarg.0
  IL_0008:  call       instance void [System.Runtime]System.Object::.ctor()
  IL_000d:  nop
  IL_000e:  ret
} // end of method Class1::.ctor

正如 Damian 指出的那样,如果您希望将属性应用于字段或 属性,you use property: or field:。所以你的例子会变成:

public record Class1([property: Dummy] string Name){}

... 此时会如您所料生成 属性 IL:

.property instance string Name()
{
  .custom instance void DummyAttribute::.ctor() = ( 01 00 00 00 ) 
  .get instance string Class1::get_Name()
  .set instance void modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) Class1::set_Name(string)
} // end of property Class1::Name