如何翻译新对象?

时间:2012-03-27 16:12:26

标签: c# class translation reflection.emit

不久前,我开始学习使用System.Reflection.Emit命名空间。我现在正在尝试将此代码翻译为使用ILGenerator:

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

对于这段代码,我有三个问题:如何创建对象?如何调用构造函数以及如何调用类的方法?请帮忙。

1 个答案:

答案 0 :(得分: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.0ldloc.0是代码中的变量。

首先发出的IL I类似于这段代码:

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

即。没有变量,只是堆栈上的临时存储,确实:

LINQPad IL output #2