不久前我开始学习使用 System.Reflection.Emit 命名空间。我现在正在尝试将此代码转换为使用 ILGenerator:
MyClass c = new MyClass("MyClass");
c.Do(":D");
对于这段代码我有三个问题:如何创建对象?如何调用构造函数以及如何调用类的方法?请帮忙。
最佳答案
这是一个显示必要的 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 类似于这段代码:
new MyClass("MyClass").Do(":D");
即。没有变量,只是堆栈上的临时存储,事实上:
关于c# - 如何翻译新对象的创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9893469/