前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >动态创建类

动态创建类

作者头像
用户6362579
发布2019-09-29 17:41:46
2.8K0
发布2019-09-29 17:41:46
举报
文章被收录于专栏:小神仙小神仙
代码语言:javascript
复制
  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     }  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档