Рассмотрим этот класс:.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
Но зачем толкнуть его в стек? Кажется, это пустая трата времени. – Snake
@Snake: Не забывайте, что вы смотрите на IL, а не на окончательный собственный код. Просто потому, что IL представляет собой «получение поля из определенного экземпляра», нажимая что-то в стек, не означает, что это действительно так. –
@Snake: стек как в стеке оценки, а не стек памяти и память кучи. ldfld загрузит поле, но для этого ему нужен экземпляр класса. Это неявно, ergo ldarg.0 http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldfld.aspx Остальная часть неэффективности выглядит просто как дополнительные инструкции оставил в отладке. – Krypes