使用 Reflection.Emit 生成相互引用的类型

7

我希望在运行时通过反射生成相互引用的类型。

使用静态代码,我会这样做

public class Order
{
    public int Id { get; set; }
    public Customer Customer { get; set; }
}

public class Customer
{
    public int Id { get; set; }
    public Order Order { get; set; }
}

我可以成功地生成我的Order和OrderDetails类型,使用值类型属性。

代码看起来像这样:

var aName = new System.Reflection.AssemblyName("DynamicAssembly");
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
    aName, System.Reflection.Emit.AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule(aName.Name);

var tb = mb.DefineType("Order",
    System.Reflection.TypeAttributes.Public, typeof(Object));

var pbId = tb.DefineProperty("Id", PropertyAttributes.None, typeof(int), null);

现在我卡在这一行代码上了:
var pbCustomer = tb.DefineProperty("Customer", PropertyAttributes.None, ???, null);

我需要在DefineProperty方法中传递属性类型,但是此时该类型不存在。现在我可以创建一个Customer的类型生成器,并使用tb.CreateType()来获取类型,但这并没有帮助,因为Customer还需要引用Order。


1
我知道这个例子可能过于简单,实际情况可能会更加复杂,但是...你有一个循环引用。你能通过修改你的设计来打破它吗?(只是好奇) - Lorenzo Dematté
首先,您必须使用TypeBuilder.DefineType方法为订单和客户定义类型,然后将该TypeBuilder对象传递给DefineProperty。 - terrybozzio
1个回答

9
你的最后一段大致正确,但是TypeBuilder继承自Type,因此你不需要调用CreateType。也就是说,为每个递归类型创建类型构建器,然后定义属性时将相应的构建器本身作为返回类型传递。

谢谢,那个可行。首先,我为每个需要的类型创建一个TypeBuilder,然后使用PropertyType = TypeBuilder添加属性,在最后调用typeBuilder.CreateType()来创建每个TypeBuilder实例,以便在运行时使用它们。 - Jürgen Steinblock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接