Почему я должен делать ldarg.0 перед вызовом поля в MSIL?

Я хочу вызвать функцию с параметрами string и Int32. string — это просто литерал, Int32 должен быть field. Поэтому я подумал, что это должно быть что-то вроде:

.method public hidebysig instance string TestVoid() cil managed
{
    .maxstack 1
    .locals init (
        [0] string CS$1$0000)
    L_0000: nop 
    L_0001: ldstr "myString"
    L_0006: ldfld int32 FirstNamespace.FirstClass::ByteField
    L_000b: call string [Class1]Class1.TestClass::Functie<int32>(string, int32)
    L_0010: ret 
}

Но это выдает ошибку, что это недействительный код. При добавлении

ldarg.0 

до ldfld работает нормально. Почему это так, и будут ли у меня проблемы, если у меня будет больше полей?


person Jan Jongboom    schedule 23.11.2009    source источник


Ответы (1)


Методы экземпляра имеют неявный параметр с именем this. Он загружается в качестве первого аргумента в стек, поэтому у вас есть ldarg.0 для «этого».

person Joel Marcey    schedule 23.11.2009
comment
разве ldarg.0 не соответствует первому параметру, переданному методу? - person lysergic-acid; 26.11.2014
comment
Как объясняет Джоэл Марси, существует неявный первый параметр this. Немного похоже на то, когда вы объявляете метод расширения и включаете параметр (этот targetType targetObject, ... на который вам потом не нужно ссылаться. - person Phil; 04.11.2015
comment
... напр. У вас может быть метод: public static char MyStringMethod(this String inputString, int index) { return inputString[index]; } - при вызове первый параметр является неявным - var myCharacter = myString.MyStringMethod(5); - но все еще загружается при выполнении метода. - person Phil; 04.11.2015