我注意到当我反映到一个程序集时,对属性访问器的调用有时看起来像方法
// "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
视为一种方法。
获得方法成为财产的神奇之处是什么?
答案 0 :(得分:7)
.NET程序集不仅包含代码,还包含描述代码的元数据。
对于方法,会发出描述方法名称,签名等的元数据
对于属性X
,它被编译为一堆访问器方法(get_X
和/或set_X
),并且对于每个方法,通常的方法元数据发出。然后,发出额外的元数据,指定所有这些访问器方法实际上属于一个逻辑实体(属性)。
现在,回到您的示例:如果使用C#定义名为get_Boolean
的方法,则C#编译器将仅发出方法元数据,但不会发出其他属性元数据。本质上,编译器可以选择要发出的元数据。由于您没有将C#语法用于属性,而是使用方法声明语法,因此C#编译器将为其生成元数据。
元数据在ECMA 335 standard中有详细描述,它描述了CLI(.NET平台)。有关属性元数据如何工作的说明,请参阅第241页的第II.22.34页。
答案 1 :(得分:7)
如果你看看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
成员,它将两种方法粘合在一起。