Отражение испускает стек и вызывает метод

Может кто-нибудь объяснить мне, что нужно загрузить в стек перед вызовом функции через Reflection.emit?

у меня очень простой способ

public static void Execute(string 1, string 2)

Я хочу динамически сгенерировать метод в следующем классе (забудьте об остальном, я разобрался с ними)

public class Test{
    public string s1;

    public void Run(string s2)
    {
        MyOtherClass.Execute(s2,s1)
    }
}

У меня есть копия вышеуказанного теста для справки, и я заметил, что перед «вызовом» были сгенерированы следующие коды операций.

  1. ldarg_1
  2. ldarg_0
  3. лдфлд

Вопрос, что там делает ldarg_0? Мне нужно только 2 аргумента для вызова, почему CLR требует, чтобы ldarg_0 помещался в стек?


person Alwyn    schedule 11.01.2013    source источник
comment
Можете ли вы предоставить окружающие IL?   -  person Simon Whitehead    schedule 11.01.2013


Ответы (2)


arg.0 содержит this и требуется ldfld string Test:s1 для помещения this.s1 в стек.

.method public hidebysig instance void Run(string s2) cil managed
{
    .maxstack 8                                      // maximum stack size 8
    ldarg.1                                          // push argument s2
    ldarg.0                                          // push this
    ldfld string Test::s1                            // pop this, push this.s1
    call void MyOtherClass::Execute(string, string)  // call
    ret                                              // return
}
person Daniel Brückner    schedule 11.01.2013
comment
Спасибо! Я знаю, что я пропустил сейчас. - person Alwyn; 11.01.2013

Вам нужно передать аргументы метода в порядке объявления и ссылки на объект, если метод не является статическим. В вашем тестовом примере вы обращаетесь к полю-члену (s1), поэтому вам нужна ссылка this для него. Это то, что ldarg_0 обеспечивает. Последующий ldfld извлекает ссылку this и помещает значение поля в стек вычислений.

person Anton Tykhyy    schedule 11.01.2013