2010-08-18 51 views
0

我是动态创建的类型“FruitTypes”与这两个属性反思:创建两种类型,而一种类型的引用其他类型的

private string _apple; 
public string Apple 
{ 
    get { return _apple; } 
    set { _apple= value; } 
} 

private string _pear; 
public string Pear 
{ 
    get { return _pear; } 
    set { _pear= value; } 
} 

现在所谓的“农场”第二类须有两个属性是这样:

private string _ID; 
public string ID 
{ 
    get { return _ID; } 
    set { _ID= value; } 
} 

private ObservableCollection<FruitTypes> _fruits; 
public ObservableCollection<FruitTypes> Fruits 
{ 
    get { return _fruits; } 
    set { _fruits= value; } 
} 

我不知道如何创建农场。 有人可以请代码示例帮忙吗? 非常感谢,

更新:我创建fruitTypes这样的:

TypeBuilder typeBldr = modBldr.DefineType("FruitTypes", TypeAttributes.Public | TypeAttributes.Class); 

FieldBuilder field = typeBldr.DefineField("_apple", typeof(string), FieldAttributes.Private); 

PropertyBuilder propertyBuilder = typeBldr.DefineProperty("Apple", PropertyAttributes.None, typeof(string), new[] { typeof(string) }); 

MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig; 

MethodBuilder currGetPropMthdBldr = typeBldr.DefineMethod("get_Apple", GetSetAttr, typeof(string), Type.EmptyTypes); 

ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator(); 
currGetIL.Emit(OpCodes.Ldarg_0); 
currGetIL.Emit(OpCodes.Ldfld, field); 
currGetIL.Emit(OpCodes.Ret); 

MethodBuilder currSetPropMthdBldr = typeBldr.DefineMethod("set_Apple", GetSetAttr, null, new[] { typeof(string) }); 
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); 
currSetIL.Emit(OpCodes.Ldarg_0); 
currSetIL.Emit(OpCodes.Ldarg_1); 
currSetIL.Emit(OpCodes.Stfld, field); 
currSetIL.Emit(OpCodes.Ret); 

propertyBuilder.SetGetMethod(currGetPropMthdBldr); 
propertyBuilder.SetSetMethod(currSetPropMthdBldr); 

我做同样的事情了梨物业同类型中。

现在如何将它们连接起来是这样的:

var tempName = new AssemblyName {Name = "MyTempAssembly"}; 
AssemblyBuilder assemBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(tempName, AssemblyBuilderAccess.Run); 
ModuleBuilder modBldr = assemBldr.DefineDynamicModule("MainMod"); 
Type generetedType = typeBldr.CreateType(); 

object generetedObject = Activator.CreateInstance(generetedType); 
PropertyInfo[] properties = generetedType.GetProperties(); 

properties[0].SetValue(generetedObject , "Apple", null); 
properties[1].SetValue(generetedObject , "Pear", null); 
+0

你是如何创建FruitTypes类型的? – SWeko 2010-08-18 13:03:30

+0

我已经插入了它,但为什么这很重要? – Houman 2010-08-18 13:18:54

回答

1

我假设你的核心问题与设置为其它动态类型的泛型类型参数创造了农场的字段/属性访问器ObservableCollection<>你只产生的?关键是先用TypeBuilder.CreateType()烘焙;像这样:

AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("testassembly"), AssemblyBuilderAccess.Run); 

    ModuleBuilder mb = ab.DefineDynamicModule("testmodule"); 

    TypeBuilder tbFoo = mb.DefineType("FooType"); 
    TypeBuilder tbBar = mb.DefineType("BarType"); 

    /* Make our List<FooType> type by baking tbFoo, then setting the result 
    * as the generic type parameter for our List<> 
    */ 
    Type tFoo = tbFoo.CreateType(); 
    Type genListType = typeof(List<>); 
    Type listFooType = genListType.MakeGenericType(tFoo); 

    /* Now we can define fields/properties of that type */ 
    FieldBuilder fb = tbBar.DefineField("_foolist", listFooType, FieldAttributes.Public); 

    ConstructorInfo ciFooList = listFooType.GetConstructor(System.Type.EmptyTypes); 

    ConstructorInfo ciObj = typeof(object).GetConstructor(System.Type.EmptyTypes); 

    ConstructorBuilder cb = tbBar.DefineConstructor(MethodAttributes.Public|MethodAttributes.SpecialName|MethodAttributes.RTSpecialName, CallingConventions.Standard, System.Type.EmptyTypes); 
    ILGenerator il = cb.GetILGenerator(); 

    /* Call the base object constructor */ 
    il.Emit(OpCodes.Ldarg_0); 
    il.Emit(OpCodes.Call, ciObj); 

    /* Set our _foolist_ field to a new List<FooType> */ 
    il.Emit(OpCodes.Ldarg_0); 
    il.Emit(OpCodes.Newobj, ciFooList); 
    il.Emit(OpCodes.Stfld, fb); 

    /* Done! */ 
    il.Emit(OpCodes.Ret); 

    /* Now we can bake and create a BarType with its public List<FooType> field 
    * set to an empty list of FooTypes 
    */ 
    Type tBar = tbBar.CreateType(); 
    object oBar = Activator.CreateInstance(tBar); 

我用List<T>的例子,但它不是太大的舒展到ObservableCollection<T>

+0

非常感谢。我现在更了解它。我现在编译它, 但我如何将值插入我的List <>的实例? 类型listFooType = genListType.MakeGenericType(tFoo); object hObject = Activator.CreateInstance(listFooType); 如何设置现在显示为一个整体实例(hObject)的列表<>内的属性? THANKs – Houman 2010-08-18 18:33:21

+0

更多反思巫毒,不幸的是,它很简单: object oFoo = Activator.CreateInstance(tFoo); object oList = Activator.CreateInstance(listFooType); MethodInfo miListAdd = oList.GetType()。GetMethod(“Add”); miListAdd.Invoke(oList,new object [] {oFoo}); (OT:你可以在评论中加入代码片段吗?) – twon33 2010-08-18 19:18:16

+0

非常感谢。现在对我来说更有意义。不要以为您可以在评论区域中添加适当的代码片段,但您随时可以编辑您的回复并在其中添加更多代码。 ;) – Houman 2010-08-19 07:41:44