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 }