【问题标题】:What happens to the custom attributes on records properties?记录属性上的自定义属性会发生什么情况?
【发布时间】:2021-03-25 15:27:18
【问题描述】:

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

【问题讨论】:

标签: .net .net-core c#-9.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

正如 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

【讨论】:

  • 至少 MSDN 文档应该描述这一点。
猜你喜欢
  • 2011-09-17
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
  • 2011-04-27
  • 2019-03-11
  • 1970-01-01
相关资源
最近更新 更多