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

C# 在一个简单的编译器中使用Reflection.Emit创建对象,c#,reflection.emit,C#,Reflection.emit,要使用Reflection.Emit创建类的实例,我需要发出操作码.Newobj,但是它需要已创建类的构造函数。所以,如果我编写自己的编译器,如何为一个方法生成代码,该方法创建另一个类的实例,该类是在源代码中定义的(不是在运行库中定义的) 我在两个过程中生成代码,首先我为我拥有的每个类创建TypeBuilder,并向它们添加方法存根,以便在第二个过程中可以引用它们。但是,我不能为这些存根调用TypeBuilder.CreateType,因为我将得到一个异常,Reflection.Emit要求定义

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

我在两个过程中生成代码,首先我为我拥有的每个类创建
TypeBuilder
,并向它们添加方法存根,以便在第二个过程中可以引用它们。但是,我不能为这些存根调用
TypeBuilder.CreateType
,因为我将得到一个异常,Reflection.Emit要求定义所有方法并具有body。但同时,我无法为需要创建源代码中定义的类的实例的方法完成代码生成

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

class Foo
{
}

class Bar
{
    Foo DoSomething()
    {
        return new Foo();
    }
}
这是:

class Foo
{
    public Foo Create()
    {
         return new Foo();
    }
}
你需要三张通行证:

  • 为每个类创建一个
    TypeBuilder
  • 对于每个类,为每个成员方法(包括构造函数)创建一个
    MethodBuilder
  • 对于每个类,使用
    ILGenerator
    生成方法体。在每个类上迭代完方法后,调用
    CreateType()

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

    啊,没错,我的错误是在测试代码中我使用了
    TypeBuilder.GetConstructor()
    要获得默认构造函数和该方法,需要首先创建类型。但是我应该创建自己的构造函数,并按照您所说的传递
    MethodBuilder
    。谢谢。“你可以传递一个表示构造函数的
    MethodBuilder
    ”你是不是说
    ConstructorBuilder
    ?@svick:是的,我以为是一样的,但构造函数和普通方法之间共享的只是
    MethodBase
    ,层次结构的分支超出了这个范围。这可能可以通过反射实现。Emit,但并非编译器可能需要执行的所有任务都是可能的: