在简单的编译器中使用 Reflection.Emit 创建对象

Creating object using Reflection.Emit in a simple compiler

要使用 Reflection.Emit 创建 class 的实例,我需要发出 OpCodes.Newobj,但是它需要创建 class 的构造函数。因此,如果我编写自己的编译器,我如何为创建另一个 class 实例的方法生成代码,该实例在源代码(而不是运行时库)中定义?

我分两次生成代码,首先我为每个 class 创建 TypeBuilder,然后向它们添加方法存根,以便在第二次通过时可以引用它们。但是我不能为那些存根调用 TypeBuilder.CreateType 因为我会得到一个异常,Reflection.Emit 需要定义所有方法并具有主体。但与此同时,我无法为需要创建源代码中定义的 class 实例的方法完成代码生成。

那么,我该如何为此创建代码:

class Foo
{
}

class Bar
{
    Foo DoSomething()
    {
        return new Foo();
    }
}

还有这个:

class Foo
{
    public Foo Create()
    {
         return new Foo();
    }
}

你需要三遍:

  1. 为每个 class
  2. 创建一个 TypeBuilder
  3. 为每个class,为每个包含构造函数的成员方法创建一个MethodBuilder
  4. 对于每个 class,使用 ILGenerator 生成方法体。在每个 class 上完成迭代方法后,调用 CreateType()

当你发出 newobj 时,你可以传递一个 ConstructorBuilder 表示构造函数,这意味着 class 和构造函数还不必被冻结。