不久前,我开始学习使用System.Reflection.Emit命名空间。我现在正在尝试将此代码翻译为使用ILGenerator:
MyClass c = new MyClass("MyClass");
c.Do(":D");
对于这段代码,我有三个问题:如何创建对象?如何调用构造函数以及如何调用类的方法?请帮忙。
答案 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选项卡,您可以看到生成的代码:
两条说明stloc.0
和ldloc.0
是代码中的变量。
首先发出的IL I类似于这段代码:
new MyClass("MyClass").Do(":D");
即。没有变量,只是堆栈上的临时存储,确实: