2013-08-17 109 views
0

我写的一些方法与Reflection.Emit 我的代码创建运行时类和属性是:如何创建类的实例在运行时创建

 public class DynamicLibraryProperties 
     { 
      public string PropName { get; set; } 
      public Type PropType { get; set; } 
      public string DefaultValue { get; set; } 
     } 

public class GenerateDynamicClass 
    { 
     public static void GenerateLegacyStructureObject(string libraryName, string className, List<DynamicLibraryProperties> properties) 
     { 
      ILGenerator ilgen = default(ILGenerator); 
      string library = string.Concat(libraryName, ".dll"); 
      AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(libraryName), AssemblyBuilderAccess.RunAndSave); 
      ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(libraryName, library); 
      TypeBuilder legacyBuilder = modBuilder.DefineType(string.Concat(libraryName, ".", className), TypeAttributes.Class | TypeAttributes.Public); 
      //Field Builder - Based on number of months add so many fields 
      foreach (DynamicLibraryProperties p in properties) 
      { 
       FieldBuilder field = legacyBuilder.DefineField(string.Concat("_", p.PropName), p.PropType, FieldAttributes.Private); 
       PropertyBuilder nameProp = legacyBuilder.DefineProperty(p.PropName, PropertyAttributes.HasDefault, p.PropType, null); 
       Type[] types = new Type[] { p.PropType }; 
       dynamic typeConvertor = TypeDescriptor.GetConverter(p.PropType); 
       dynamic defaultValue = typeConvertor.ConvertFromString(p.DefaultValue); 
       ConstructorInfo ctor = typeof(DefaultValueAttribute).GetConstructor(types); 
       CustomAttributeBuilder customAttrib = new CustomAttributeBuilder(ctor, new object[] { defaultValue }); 
       nameProp.SetCustomAttribute(customAttrib); 
       MethodAttributes getAttr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName; 
       MethodBuilder getNameBuilder = legacyBuilder.DefineMethod(string.Concat("get_", p.PropName), getAttr, p.PropType, Type.EmptyTypes); 
       ilgen = getNameBuilder.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0); 
       ilgen.Emit(OpCodes.Ldfld, field); 
       ilgen.Emit(OpCodes.Ret); 
       MethodBuilder setNameBuilder = legacyBuilder.DefineMethod(string.Concat("set_", p.PropName), getAttr, null, new Type[] { p.PropType }); 
       ilgen = setNameBuilder.GetILGenerator(); 
       ilgen.Emit(OpCodes.Ldarg_0); 
       ilgen.Emit(OpCodes.Ldarg_1); 
       ilgen.Emit(OpCodes.Stfld, field); ilgen.Emit(OpCodes.Ret); 
       nameProp.SetGetMethod(getNameBuilder); 
       nameProp.SetSetMethod(setNameBuilder); 
      } 
      Type objType = Type.GetType("System.Object"); 
      ConstructorInfo objCtor = objType.GetConstructor(Type.EmptyTypes); 
      ilgen.Emit(OpCodes.Ldarg_0); 
      ilgen.Emit(OpCodes.Call, objCtor); 
      ilgen.Emit(OpCodes.Ret); 
      legacyBuilder.CreateType(); 
      asmBuilder.Save(library); 
     } 


    } 

,并使用此代码这样

List<DynamicLibraryProperties> props = new List<DynamicLibraryProperties>(); 
      props.Add(new DynamicLibraryProperties 
          { 
           PropName = "201203", PropType = typeof(float),DefaultValue = "0" 
          }); 
      props.Add(new DynamicLibraryProperties { PropName = "201204", PropType = typeof(float) ,DefaultValue = "0"}); 

      GenerateDynamicClass.GenerateLegacyStructureObject("test", "test", props); 

现在我想创建Test类的实例并为属性值设置值,但我不知道该怎么做,请帮助我,谢谢大家。

回答

2

为此,您可以使用Activator.CreateInstance,因为您需要测试类的Type。 更改方法如下。

public static Type GenerateLegacyStructureObject(string libraryName, string className, List<DynamicLibraryProperties> properties) 
{ 
    //your code 
    Type t = legacyBuilder.CreateType(); 
    asmBuilder.Save(library); 
    return t; 
} 

然后使用它像这样

Type testType = GenerateDynamicClass.GenerateLegacyStructureObject("test", "test", props); 
object test = Activator.CreateInstance(testType); 

希望这有助于

+0

不客气@Pouya –