Dan*_*ite 8 c# clr syntactic-sugar
我注意到当我反映到一个程序集时,对属性访问器的调用有时看起来像方法
// "Reflected" example
class Class1 {
public bool Boolean { get; set;}
}
class Class2 {
public Class2() {
var class1 = new Class1();
var boolean = class1.get_Boolean();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我很好奇,我把一个带有类似签名的方法Class1看作是访问者的标准约定.
// "Hacked" example
class Class1 {
public bool get_Boolean() { return true; }
}
Run Code Online (Sandbox Code Playgroud)
不知何故,C#编译器仍将其视为get_Boolean一种方法.
获得一种方法成为财产的神奇之处是什么?
.NET程序集不仅包含代码,还包含描述代码的元数据.
在方法的情况下,发出描述方法的名称,签名等的元数据.
在属性的情况下X,它被编译为一堆访问器方法(get_X和/或set_X),并且对于它们中的每一个,发出通常的方法元数据.然后,发出额外的元数据,指定所有这些访问器方法实际上属于一个逻辑实体(属性).
现在,回到您的示例:如果您定义了一个get_Boolean使用C#调用的方法,则C#编译器将仅发出方法元数据,但不会发出其他属性元数据.本质上,编译器可以选择要发出的元数据.由于您没有将C#语法用于属性,而是使用方法声明语法,这就是C#编译器将为其生成元数据的内容.
ECMA 335标准中详细描述了元数据,该标准描述了CLI(.NET平台).有关属性元数据如何工作的说明,请参阅第241页的第II.22.34章.
如果你看看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
{
...
}
Run Code Online (Sandbox Code Playgroud)
所以'魔术'是.property将两种方法粘合在一起的成员.
| 归档时间: |
|
| 查看次数: |
699 次 |
| 最近记录: |