2010-11-15 2 views
1

Рассмотрим этот класс:.NET IL Свойство

public class Foo 
{ 
    // Fields 
    private string _bar; 

    // Properties 
    private string Bar 
    { 
     get 
     { 
      return this._bar; 
     } 
     set 
     { 
      this._bar = value; 
     } 
    } 
} 

Теперь, когда я иду и смотрю в код IL излучаемого компилятором для сеттер в Bar собственности:

.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 аргумент ...

То же самое относится и к геттер:

.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 заднего поля и просто возвращает это? :)

Спасибо.

-Snake

ответ

4

Для сеттер:

Любой член экземпляра имеет неявный «этот» параметр - это то, что загружается, в основном. Попробуйте превратить его в статическое свойство, и вы увидите, как оно исчезнет.

Для получателя я не уверен, почему существует локальная переменная ... возможно, поддержка отладчика? Конечно, компиляция в оптимизированном режиме (/o+ /debug- из командной строки) избавляется от локальной переменной.

+0

Но зачем толкнуть его в стек? Кажется, это пустая трата времени. – Snake

+0

@Snake: Не забывайте, что вы смотрите на IL, а не на окончательный собственный код. Просто потому, что IL представляет собой «получение поля из определенного экземпляра», нажимая что-то в стек, не означает, что это действительно так. –

+0

@Snake: стек как в стеке оценки, а не стек памяти и память кучи. ldfld загрузит поле, но для этого ему нужен экземпляр класса. Это неявно, ergo ldarg.0 http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldfld.aspx Остальная часть неэффективности выглядит просто как дополнительные инструкции оставил в отладке. – Krypes