1 public class CreateClassHelper 2 { 3 /// <summary> 4 /// 根据列名创建自定义类型 5 /// 属性名称在列名前添加前缀 prdfix 6 /// </summary> 7 /// <param name="columnNames">用来创建属性的列名</param> 8 /// <param name="prdfix">属性名称在列名前添加的前缀</param> 9 /// <returns></returns> 10 public static Type CreateClass(string[] columnNames, string prdfix=null) 11 { 12 13 DynamicTypeBuilder dyClass = new DynamicTypeBuilder("dy");//创建动态类,dy可以随便替换 14 //ColInfos为已经取到的列信息集合 15 foreach (string name in columnNames) 16 { 17 try 18 { 19 dyClass.AppendPublicProperty(prdfix + name, typeof(string));//同时动态添加公共属性到自定义类 20 } 21 catch (Exception ex) 22 { 23 LogHelper.log4net_Error(ex.Message.ToString(), null); 24 } 25 } 26 Type dyType = dyClass.CreateDynamicType();//创建自定义类 27 return dyType; 28 } 29 } 30 public class DynamicTypeBuilder 31 { 32 TypeBuilder tb; 33 /// <summary> 34 /// 构造函数 35 /// </summary> 36 /// <param name="typeNm">动态类型的名称</param> 37 public DynamicTypeBuilder(string typeNm) 38 { 39 // 在 Silverlight 中 AssemblyBuilderAccess 没有 RunAndSave 40 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( 41 new AssemblyName("TempAssembly"), AssemblyBuilderAccess.Run); 42 43 ModuleBuilder mb = ab.DefineDynamicModule("TempModule"); 44 this.tb = mb.DefineType(typeNm, TypeAttributes.Public); 45 } 46 /// <summary> 47 /// 添加一个public的可读写属性,并且会创建对应的名为 propertyNm + "Field" 的私有字段 48 /// </summary> 49 /// <param name="propertyNm"></param> 50 /// <param name="type"></param> 51 public void AppendPublicProperty(string propertyNm, Type type) 52 { 53 this.AppendPublicProperty(propertyNm, type, true, true); 54 } 55 /// <summary> 56 /// 添加一个public属性,并且会创建对应的名为 propertyNm + "Field" 的私有字段 57 /// </summary> 58 /// <param name="propertyNm"></param> 59 /// <param name="type"></param> 60 /// <param name="canGet">是否实现getter</param> 61 /// <param name="canSet">是否实现setter</param> 62 public void AppendPublicProperty(string propertyNm, Type type, bool canGet, bool canSet) 63 { 64 FieldBuilder field = this.tb.DefineField(string.Format("{0}Field", propertyNm), type, FieldAttributes.Private); 65 66 PropertyBuilder property = tb.DefineProperty(propertyNm, PropertyAttributes.HasDefault, type, null); 67 68 MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; 69 70 if (canGet) 71 { 72 MethodBuilder getAccessor = tb.DefineMethod(string.Format("get_{0}", propertyNm), getSetAttr, type, Type.EmptyTypes); 73 ILGenerator getIL = getAccessor.GetILGenerator(); 74 // For an instance property, argument default is the instance. Load the 75 // instance, then load the private field and return, leaving the 76 // field value on the stack. 77 getIL.Emit(OpCodes.Ldarg_0); 78 getIL.Emit(OpCodes.Ldfld, field); 79 getIL.Emit(OpCodes.Ret); 80 property.SetGetMethod(getAccessor); 81 } 82 83 if (canSet) 84 { 85 MethodBuilder setAccessor = tb.DefineMethod(string.Format("set_{0}", propertyNm), getSetAttr, null, new Type[] { type }); 86 setAccessor.DefineParameter(1, ParameterAttributes.None, "value"); 87 ILGenerator setIL = setAccessor.GetILGenerator(); 88 // Load the instance and then the numeric argument, then store the 89 // argument in the field. 90 setIL.Emit(OpCodes.Ldarg_0); 91 setIL.Emit(OpCodes.Ldarg_1); 92 setIL.Emit(OpCodes.Stfld, field); 93 setIL.Emit(OpCodes.Ret); 94 property.SetSetMethod(setAccessor); 95 } 96 } 97 /// <summary> 98 /// 在添加完各个 public 属性之后,调用此方法以完成对动态类型的定义并加载之, 99 /// 此后通过 Activator.CreateInstance() 便可实例化动态类型 100 /// </summary> 101 /// <returns></returns> 102 public Type CreateDynamicType() 103 { 104 return this.tb.CreateType(); 105 } 106 }