Код MSIL для доступа к полю только для чтения приводит к ldarg.0

У меня есть простой метод в C#, который обращается к полю только для чтения:

IL_0024:  ldarg.0
IL_0025:  ldfld      string MyAssembly.MyClass.TestClass::A

Моим естественным предположением было то, что это используется для загрузки ссылки "this" при доступе к полям-членам, и этот вопрос также подтверждает, что: Почему я должен выполнить ldarg.0 перед вызовом поля в MSIL?

Однако в документации к ldarg упоминается, что он используется для загрузки параметров, передаваемых методу.

Каково правильное объяснение этого поведения? и как можно отличить загрузку ссылки "this" от загрузки первого формального параметра в метод в IL?

2 ответа

Решение

Оба верны:)

this значение передается в качестве первого "невидимого" параметра в методы экземпляра, поэтому в методе экземпляра ldarg.0 это "загрузить this значение".

Вы можете увидеть разницу, если напишите метод, который использует другой параметр. Например:

static void StaticMethod(int x)
{
    // This uses ldarg.0
    Console.WriteLine(x);
}

void InstanceMethod(int x)
{
    // This uses ldarg.1
    Console.WriteLine(x);
}

и как можно отличить загрузку ссылки "this" от загрузки первого формального параметра в метод в IL?

Проверяя вышеизложенное, в основном - если это метод экземпляра, то ldarg.0 загружает неявное this значение. В противном случае он загружает первое формальное значение параметра.

Все методы экземпляра принимают первый параметр в качестве самого экземпляра класса. Это делается неявно, поэтому вам не нужно передавать его при вызове метода.

При условии this это параметр метода, вам нужно использовать ldarg.0 подтолкнуть this экземпляр для стека оценки.

Другие вопросы по тегам