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

时间:2021-03-25 15:27:18

标签: .net .net-core c#-9.0

我尝试通过反射 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 记录的属性吗?

1 个答案:

答案 0 :(得分:1)

该属性默认应用于构造函数参数。这是 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

正如达米安所指出的,如果您希望将该属性应用于字段或属性,请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