【问题标题】:What is the magic that makes properties work with the CLR?使属性与 CLR 一起工作的魔力是什么?
【发布时间】:2012-10-16 18:10:20
【问题描述】:

我注意到当我反映到程序集中时,对属性访问器的调用有时看起来像方法

// "Reflected" example
class Class1 {
   public bool Boolean { get; set;}
}

class Class2 {
   public Class2() {
       var class1 = new Class1();
       var boolean = class1.get_Boolean();
   }
}

现在我很好奇,我在Class1 中放了一个类似签名的方法,看起来像是访问器的标准约定。

// "Hacked" example
class Class1 {
   public bool get_Boolean() { return true; }
}

不知何故,C# 编译器仍然将get_Boolean 视为一种方法。

让方法成为属性的秘诀是什么?

【问题讨论】:

  • 最有可能的是,没有 spoon 酱可以使它起作用:当您通过反射 API 查看它们时,两者的表示方式不同,因此其中可能有一些元数据区分两者的程序集。
  • 最神奇的是编译器生成的 .property IL 指令。并且为 getter 方法生成的 specialname 属性,您的 get_Boolean 方法两者都没有。你可以用 ildasm.exe 看到它
  • 当您说“反射”等时,您是指 RedGate Reflector 吗?它是对 每个 属性的访问执行此操作,还是仅对某些属性执行此操作?
  • @AakashM 其 resharper 的自动反编译。
  • 有趣的是,我会将您所看到的内容归类为反编译器中的错误(通常 dotPeek 似乎可以毫无问题地确定是否正在调用属性或方法)

标签: c# clr syntactic-sugar


【解决方案1】:

.NET 程序集不仅包含代码,它还包含描述代码的元数据

在方法的情况下,会发出描述方法名称、签名等的元数据。

在属性X 的情况下,它被编译为一堆访问器方法(get_X 和/或set_X),并且对于其中的每一个,都会发出通常的方法元数据。然后,发出额外的元数据,指定所有这些访问器方法实际上属于一个逻辑实体(属性)。

现在,回到您的示例:如果您使用 C# 定义一个名为 get_Boolean 的方法,C# 编译器将仅发出方法元数据,而不会发出其他属性元数据。本质上,编译器可以选择要发出的元数据。由于您没有使用 C# 语法来处理属性,而是使用方法声明语法,因此 C# 编译器将为其生成元数据。

元数据在描述 CLI(.NET 平台)的ECMA 335 standard 中有详细描述。请参阅 第 241 页的第 II.22.34 章,了解属性元数据的工作原理。

【讨论】:

    【解决方案2】:

    如果您查看 IL,您会发现如下内容:

    .property instance string Source()
    {
        .get instance string System.Exception::get_Source()
        .set instance void System.Exception::set_Source(string)
    }
    
    .method public hidebysig specialname newslot virtual 
        instance string get_Source () cil managed 
    {
        ...
    }
    
    .method public hidebysig specialname newslot virtual 
        instance void set_Source (
            string 'value'
        ) cil managed 
    {
        ...
    }
    

    所以“魔法”是.property 成员,它将两种方法粘合在一起。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-29
      • 2016-09-23
      • 2015-09-09
      • 2011-01-20
      • 2012-05-15
      • 2012-11-30
      • 2011-04-02
      • 2017-09-26
      相关资源
      最近更新 更多