2012-03-27 6 views
3

Не так давно я начал учиться использовать пространство имен System.Reflection.Emit. Я сейчас пытаюсь перевести этот код на использование ILGenerator:Как перевести создание нового объекта?

MyClass c = new MyClass("MyClass"); 
c.Do(":D"); 

Для этого куска кода у меня есть три вопроса: как создать объект? как вызвать contructor и как вызвать метод класса? Пожалуйста помоги.

+4

Лучший способ узнать, что C# делает за кулисами не смотреть на IL, который он генерирует для вашего кода. Я предполагаю, что вы знаете, как смотреть на разборку в отладчике, не так ли? – dasblinkenlight

+0

ОК. Спасибо вам всем. – user35443

ответ

3

Вот полный пример, который показывает необходимый код IL.

Вы можете проверить это в LINQPad:

void Main() 
{ 
    // Manual test first 
    MyClass c = new MyClass("MyClass"); 
    c.Do(":D"); 

    var method = new DynamicMethod("dummy", null, Type.EmptyTypes); 
    var il = method.GetILGenerator(); 

    // <stack> = new MyClass("MyClass"); 
    il.Emit(OpCodes.Ldstr, "MyClass"); 
    il.Emit(OpCodes.Newobj, typeof(MyClass).GetConstructor(new[] { typeof(string) })); 

    // <stack>.Do(":D"); 
    il.Emit(OpCodes.Ldstr, ":D"); 
    il.Emit(OpCodes.Call, typeof(MyClass).GetMethod("Do", new[] { typeof(string) })); 

    // return; 
    il.Emit(OpCodes.Ret); 

    var action = (Action)method.CreateDelegate(typeof(Action)); 
    action(); 
} 

public class MyClass 
{ 
    public MyClass(string text) 
    { 
     Console.WriteLine("MyClass(" + text + ")"); 
    } 

    public void Do(string text) 
    { 
     Console.WriteLine("Do(" + text + ")"); 
    } 
} 

Выход:

MyClass(MyClass) 
Do(:D) 
MyClass(MyClass) 
Do(:D) 

Кстати, вы можете использовать LINQPad разжиться кода IL для конкретного примера. Позвольте мне вырезать IL-часть приведенного выше примера, как это (я удалил класс а, это тот же самый класс):

void Main() 
{ 
    MyClass c = new MyClass("MyClass"); 
    c.Do(":D"); 
} 

При выполнении этого кода, а затем с помощью вкладки IL выхода , вы можете увидеть сгенерированный код:

LINQPad IL Output

две инструкции stloc.0 и ldloc.0 является переменной в коде.

Ил I излучается первым сродни этот кусок кода:

new MyClass("MyClass").Do(":D"); 

т.е.. ни одна переменная, только временное хранение в стеке, и в самом деле:

LINQPad IL output #2

Смежные вопросы