.NET IL属性设置程序

.NET IL属性设置程序,.net,intermediate-language,.net,Intermediate Language,以这一类为例: public class Foo { // Fields private string _bar; // Properties private string Bar { get { return this._bar; } set { this._bar = value; } } } 现在

以这一类为例:

public class Foo
{
    // Fields
    private string _bar;

    // Properties
    private string Bar
    {
        get
        {
            return this._bar;
        }
        set
        {
            this._bar = value;
        }
    }
}
现在,当我在编译器发出的IL代码中查找
Bar
属性的setter时:

.method private hidebysig specialname instance void set_Bar(string 'value') cil managed
{
    .maxstack 8
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: ldarg.1 
    L_0003: stfld string ConsoleApplication2.Program/Foo::_bar
    L_0008: ret 
}
为什么它会执行
ldarg.0
?第一个(索引0)参数中有什么?由于方法/属性设置程序只接受1个参数

getter也是如此:

.method private hidebysig specialname instance string get_Bar() cil managed
{
    .maxstack 1
    .locals init (
        [0] string CS$1$0000)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: ldfld string ConsoleApplication2.Program/Foo::_bar
    L_0007: stloc.0 
    L_0008: br.s L_000a
    L_000a: ldloc.0 
    L_000b: ret 
}
为什么使用
.locals init
?为什么使用ldarg.0?为什么它不执行备份字段的
ldfld
,然后返回该字段呢?:)

对于setter:

任何实例成员都有一个隐式的“this”参数——基本上就是加载的参数。尝试将其转换为静态属性,您将看到它消失


对于getter,我不知道为什么会有局部变量。。。调试器支持吗?当然,在优化模式下编译它(从命令行编译)可以去掉局部变量。

但是为什么要将它推到堆栈上呢?对我来说似乎是在浪费空间。@Snake:别忘了你在看IL,而不是最终的本机代码。仅仅因为IL通过将某些内容推到堆栈上表示“从特定实例获取字段”,并不意味着这就是真正发生的情况。@Snake:堆栈与求值堆栈相同,而不是堆栈内存与堆内存之比。ldfld将加载一个字段,但它需要一个类的实例来加载。对于ldarg.0来说,这并不是隐含的,其余的低效只是看起来像调试留下的额外指令。