c# - 如何翻译新对象的创建?

标签 c# class translation reflection.emit

不久前我开始学习使用 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选项卡,可以看到生成的代码:

LINQPad IL Output

STLoc.0ldloc.0这两条指令就是代码中的变量。

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

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

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

LINQPad IL output #2

关于c# - 如何翻译新对象的创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9893469/

相关文章:

c# - c#中用于反射的动态类名

java - Capicom 和 SHA1 - 帮助将 Java 代码转换为 Delphi

swift - 为什么我的本地变量显示为数字?

c# - 在 C# 中查找同义词

C# DateTime ToString ("MM-dd-yyyy") 返回有趣的日期值

c++ - 为什么必须将在 A 类中声明为 friend 的函数在 B 类中定义为公共(public)函数?

laravel - 如何在 Laravel 验证中翻译字段名称?

c# - 从 X509Certificate2 中删除私钥

C# MySql 错误 : An established connection was aborted by the software in your host machine

python - PyQt4 如何通过单击按钮使用多处理