I have dynamically created the type "FruitTypes" with these two properties
private string _apple;
public string Apple
{
get { return _apple; }
set { _apple= value; }
}
private string _pear;
public string Pear
{
get { return _pear; }
set { _pear= value; }
}
Now the second type called "Farm" shall have two properties like this:
private string _ID;
public string ID
{
get { return 开发者_StackOverflow_ID; }
set { _ID= value; }
}
private ObservableCollection<FruitTypes> _fruits;
public ObservableCollection<FruitTypes> Fruits
{
get { return _fruits; }
set { _fruits= value; }
}
I have no idea how to create the Farm. Can someone please help with with code samples? Many Thanks,
UPDATE: I create the fruitTypes like this:
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);
I do the same thing for a Pear Property within the same type.
Now how to wire them up is like this:
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);
I assume your core issue is creating the field/property accessors in Farm as ObservableCollection<>
with the generic type parameter set to the other dynamic type you just created? The key is to bake the type using TypeBuilder.CreateType()
first; like this:
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);
I use List<T>
for the example but it's not much of a stretch to ObservableCollection<T>
.
精彩评论