1.

  1. class ClassHelperDemo
  2. {
  3. public static void Main()
  4. {
  5. #region 演示一:动态生成类。
  6. //生成一个类t。
  7. Type t = ClassHelper.BuildType("MyClass");
  8. #endregion
  9.  
  10. #region 演示二:动态添加属性到类。
  11. //先定义两个属性。
  12. List<ClassHelper.CustPropertyInfo> lcpi = new List<ClassHelper.CustPropertyInfo>();
  13. ClassHelper.CustPropertyInfo cpi;
  14.  
  15. cpi = new ClassHelper.CustPropertyInfo("System.String", "Name1");
  16. lcpi.Add(cpi);
  17. cpi = new ClassHelper.CustPropertyInfo("System.String", "Name2");
  18. lcpi.Add(cpi);
  19.  
  20. //再加入上面定义的两个属性到我们生成的类t。
  21. t = ClassHelper.AddProperty(t, lcpi);
  22.  
  23. //把它显示出来。
  24. DispProperty(t);
  25.  
  26. //再定义两个属性。
  27. lcpi.Clear();
  28. cpi = new ClassHelper.CustPropertyInfo("System.Int32", "Orther1");
  29. lcpi.Add(cpi);
  30. cpi = new ClassHelper.CustPropertyInfo("System.Int32", "Orther2");
  31. lcpi.Add(cpi);
  32.  
  33. //再加入上面定义的两个属性到我们生成的类t。
  34. t = ClassHelper.AddProperty(t, lcpi);
  35.  
  36. //再把它显示出来,看看有没有增加到4个属性。
  37. DispProperty(t);
  38. #endregion
  39.  
  40. #region 演示三:动态从类里删除属性。
  41. //把'S1'属性从类t中删除。
  42. t = ClassHelper.DeleteProperty(t, "Name1");
  43. //显示出来,可以看到'S1'不见了。
  44. DispProperty(t);
  45.  
  46. #endregion
  47.  
  48. #region 演示四:动态获取和设置属性值。
  49. //先生成一个类t的实例o。
  50. object o = ClassHelper.CreateInstance(t);
  51.  
  52. //给S2,I2属性赋值。
  53. ClassHelper.SetPropertyValue(o, "Name2", "abcd");
  54. ClassHelper.SetPropertyValue(o, "Orther2", );
  55.  
  56. //再把S2,I2的属性值显示出来。
  57. Console.WriteLine("Name2 = {0}", ClassHelper.GetPropertyValue(o, "Name2"));
  58. Console.WriteLine("Orther2 = {0}", ClassHelper.GetPropertyValue(o, "Orther2"));
  59. #endregion
  60.  
  61. Console.Read();
  62. Console.ReadKey();
  63. }
  64.  
  65. public static void DispProperty(Type t)
  66. {
  67. Console.WriteLine("ClassName '{0}'", t.Name);
  68. foreach (PropertyInfo pInfo in t.GetProperties())
  69. {
  70. Console.WriteLine("Has Property '{0}'", pInfo.ToString());
  71. }
  72. Console.WriteLine("");
  73. }
  74. }

ClassHelperDemo

2.

  1. class ClassHelper
  2. {
  3. #region 公有方法
  4. /// <summary>
  5. /// 根据类的类型型创建类实例。
  6. /// </summary>
  7. /// <param name="t">将要创建的类型。</param>
  8. /// <returns>返回创建的类实例。</returns>
  9. public static object CreateInstance(Type t)
  10. {
  11. return Activator.CreateInstance(t);
  12. }
  13.  
  14. /// <summary>
  15. /// 根据类的名称,属性列表创建型实例。
  16. /// </summary>
  17. /// <param name="className">将要创建的类的名称。</param>
  18. /// <param name="lcpi">将要创建的类的属性列表。</param>
  19. /// <returns>返回创建的类实例</returns>
  20. public static object CreateInstance(string className, List<CustPropertyInfo> lcpi)
  21. {
  22. Type t = BuildType(className);
  23. t = AddProperty(t, lcpi);
  24. return Activator.CreateInstance(t);
  25. }
  26.  
  27. /// <summary>
  28. /// 根据属性列表创建类的实例,默认类名为DefaultClass,由于生成的类不是强类型,所以类名可以忽略。
  29. /// </summary>
  30. /// <param name="lcpi">将要创建的类的属性列表</param>
  31. /// <returns>返回创建的类的实例。</returns>
  32. public static object CreateInstance(List<CustPropertyInfo> lcpi)
  33. {
  34. return CreateInstance("DefaultClass", lcpi);
  35. }
  36.  
  37. /// <summary>
  38. /// 根据类的实例设置类的属性。
  39. /// </summary>
  40. /// <param name="classInstance">将要设置的类的实例。</param>
  41. /// <param name="propertyName">将要设置属性名。</param>
  42. /// <param name="propertSetValue">将要设置属性值。</param>
  43. public static void SetPropertyValue(object classInstance, string propertyName, object propertSetValue)
  44. {
  45. classInstance.GetType().InvokeMember(propertyName, BindingFlags.SetProperty,
  46. null, classInstance, new object[] { Convert.ChangeType(propertSetValue, propertSetValue.GetType()) });
  47. }
  48.  
  49. /// <summary>
  50. /// 根据类的实例获取类的属性。
  51. /// </summary>
  52. /// <param name="classInstance">将要获取的类的实例</param>
  53. /// <param name="propertyName">将要设置的属性名。</param>
  54. /// <returns>返回获取的类的属性。</returns>
  55. public static object GetPropertyValue(object classInstance, string propertyName)
  56. {
  57. return classInstance.GetType().InvokeMember(propertyName, BindingFlags.GetProperty,
  58. null, classInstance, new object[] { });
  59. }
  60.  
  61. /// <summary>
  62. /// 创建一个没有成员的类型的实例,类名为"DefaultClass"。
  63. /// </summary>
  64. /// <returns>返回创建的类型的实例。</returns>
  65. public static Type BuildType()
  66. {
  67. return BuildType("DefaultClass");
  68. }
  69.  
  70. /// <summary>
  71. /// 根据类名创建一个没有成员的类型的实例。
  72. /// </summary>
  73. /// <param name="className">将要创建的类型的实例的类名。</param>
  74. /// <returns>返回创建的类型的实例。</returns>
  75. public static Type BuildType(string className)
  76. {
  77.  
  78. AppDomain myDomain = Thread.GetDomain();
  79. AssemblyName myAsmName = new AssemblyName();
  80. myAsmName.Name = "MyDynamicAssembly";
  81.  
  82. //创建一个永久程序集,设置为AssemblyBuilderAccess.RunAndSave。
  83. AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,AssemblyBuilderAccess.RunAndSave);
  84.  
  85. //创建一个永久单模程序块。
  86. ModuleBuilder myModBuilder =myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");
  87.  
  88. //创建TypeBuilder。
  89. TypeBuilder myTypeBuilder = myModBuilder.DefineType(className,TypeAttributes.Public);
  90.  
  91. //创建类型。
  92. Type retval = myTypeBuilder.CreateType();
  93.  
  94. //保存程序集,以便可以被Ildasm.exe解析,或被测试程序引用。
  95. myAsmBuilder.Save(myAsmName.Name + ".dll");
  96. return retval;
  97. }
  98.  
  99. /// <summary>
  100. /// 添加属性到类型的实例,注意:该操作会将其它成员清除掉,其功能有待完善。
  101. /// </summary>
  102. /// <param name="classType">指定类型的实例。</param>
  103. /// <param name="lcpi">表示属性的一个列表。</param>
  104. /// <returns>返回处理过的类型的实例。</returns>
  105. public static Type AddProperty(Type classType, List<CustPropertyInfo> lcpi)
  106. {
  107. //合并先前的属性,以便一起在下一步进行处理。
  108. MergeProperty(classType, lcpi);
  109. //把属性加入到Type。
  110. return AddPropertyToType(classType, lcpi);
  111. }
  112.  
  113. /// <summary>
  114. /// 添加属性到类型的实例,注意:该操作会将其它成员清除掉,其功能有待完善。
  115. /// </summary>
  116. /// <param name="classType">指定类型的实例。</param>
  117. /// <param name="cpi">表示一个属性。</param>
  118. /// <returns>返回处理过的类型的实例。</returns>
  119. public static Type AddProperty(Type classType, CustPropertyInfo cpi)
  120. {
  121. List<CustPropertyInfo> lcpi = new List<CustPropertyInfo>();
  122. lcpi.Add(cpi);
  123. //合并先前的属性,以便一起在下一步进行处理。
  124. MergeProperty(classType, lcpi);
  125. //把属性加入到Type。
  126. return AddPropertyToType(classType, lcpi);
  127. }
  128.  
  129. /// <summary>
  130. /// 从类型的实例中移除属性,注意:该操作会将其它成员清除掉,其功能有待完善。
  131. /// </summary>
  132. /// <param name="classType">指定类型的实例。</param>
  133. /// <param name="cpi">要移除的属性。</param>
  134. /// <returns>返回处理过的类型的实例。</returns>
  135. public static Type DeleteProperty(Type classType, string propertyName)
  136. {
  137. List<string> ls = new List<string>();
  138. ls.Add(propertyName);
  139.  
  140. //合并先前的属性,以便一起在下一步进行处理。
  141. List<CustPropertyInfo> lcpi = SeparateProperty(classType, ls);
  142. //把属性加入到Type。
  143. return AddPropertyToType(classType, lcpi);
  144. }
  145.  
  146. /// <summary>
  147. /// 从类型的实例中移除属性,注意:该操作会将其它成员清除掉,其功能有待完善。
  148. /// </summary>
  149. /// <param name="classType">指定类型的实例。</param>
  150. /// <param name="lcpi">要移除的属性列表。</param>
  151. /// <returns>返回处理过的类型的实例。</returns>
  152. public static Type DeleteProperty(Type classType, List<string> ls)
  153. {
  154. //合并先前的属性,以便一起在下一步进行处理。
  155. List<CustPropertyInfo> lcpi = SeparateProperty(classType, ls);
  156. //把属性加入到Type。
  157. return AddPropertyToType(classType, lcpi);
  158. }
  159. #endregion
  160.  
  161. #region 私有方法
  162. /// <summary>
  163. /// 把类型的实例t和lcpi参数里的属性进行合并。
  164. /// </summary>
  165. /// <param name="t">实例t</param>
  166. /// <param name="lcpi">里面包含属性列表的信息。</param>
  167. private static void MergeProperty(Type t, List<CustPropertyInfo> lcpi)
  168. {
  169. CustPropertyInfo cpi;
  170. foreach (PropertyInfo pi in t.GetProperties())
  171. {
  172. cpi = new CustPropertyInfo(pi.PropertyType.FullName, pi.Name);
  173. lcpi.Add(cpi);
  174. }
  175. }
  176.  
  177. /// <summary>
  178. /// 从类型的实例t的属性移除属性列表lcpi,返回的新属性列表在lcpi中。
  179. /// </summary>
  180. /// <param name="t">类型的实例t。</param>
  181. /// <param name="lcpi">要移除的属性列表。</param>
  182. private static List<CustPropertyInfo> SeparateProperty(Type t, List<string> ls)
  183. {
  184. List<CustPropertyInfo> ret = new List<CustPropertyInfo>();
  185. CustPropertyInfo cpi;
  186. foreach (PropertyInfo pi in t.GetProperties())
  187. {
  188. foreach (string s in ls)
  189. {
  190. if (pi.Name != s)
  191. {
  192. cpi = new CustPropertyInfo(pi.PropertyType.FullName, pi.Name);
  193. ret.Add(cpi);
  194. }
  195. }
  196. }
  197.  
  198. return ret;
  199. }
  200.  
  201. /// <summary>
  202. /// 把lcpi参数里的属性加入到myTypeBuilder中。注意:该操作会将其它成员清除掉,其功能有待完善。
  203. /// </summary>
  204. /// <param name="myTypeBuilder">类型构造器的实例。</param>
  205. /// <param name="lcpi">里面包含属性列表的信息。</param>
  206. private static void AddPropertyToTypeBuilder(TypeBuilder myTypeBuilder, List<CustPropertyInfo> lcpi)
  207. {
  208. FieldBuilder customerNameBldr;
  209. PropertyBuilder custNamePropBldr;
  210. MethodBuilder custNameGetPropMthdBldr;
  211. MethodBuilder custNameSetPropMthdBldr;
  212. MethodAttributes getSetAttr;
  213. ILGenerator custNameGetIL;
  214. ILGenerator custNameSetIL;
  215.  
  216. // 属性Set和Get方法要一个专门的属性。这里设置为Public。
  217. getSetAttr =
  218. MethodAttributes.Public | MethodAttributes.SpecialName |
  219. MethodAttributes.HideBySig;
  220.  
  221. // 添加属性到myTypeBuilder。
  222. foreach (CustPropertyInfo cpi in lcpi)
  223. {
  224. //定义字段。
  225. customerNameBldr = myTypeBuilder.DefineField(cpi.FieldName,
  226. Type.GetType(cpi.Type),
  227. FieldAttributes.Private);
  228.  
  229. //定义属性。
  230. //最后一个参数为null,因为属性没有参数。
  231. custNamePropBldr = myTypeBuilder.DefineProperty(cpi.PropertyName,
  232. PropertyAttributes.HasDefault,
  233. Type.GetType(cpi.Type),
  234. null);
  235.  
  236. //定义Get方法。
  237. custNameGetPropMthdBldr =
  238. myTypeBuilder.DefineMethod(cpi.GetPropertyMethodName,
  239. getSetAttr,
  240. Type.GetType(cpi.Type),
  241. Type.EmptyTypes);
  242.  
  243. custNameGetIL = custNameGetPropMthdBldr.GetILGenerator();
  244.  
  245. custNameGetIL.Emit(OpCodes.Ldarg_0);
  246. custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr);
  247. custNameGetIL.Emit(OpCodes.Ret);
  248.  
  249. //定义Set方法。
  250. custNameSetPropMthdBldr =
  251. myTypeBuilder.DefineMethod(cpi.SetPropertyMethodName,
  252. getSetAttr,
  253. null,
  254. new Type[] { Type.GetType(cpi.Type) });
  255.  
  256. custNameSetIL = custNameSetPropMthdBldr.GetILGenerator();
  257.  
  258. custNameSetIL.Emit(OpCodes.Ldarg_0);
  259. custNameSetIL.Emit(OpCodes.Ldarg_1);
  260. custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr);
  261. custNameSetIL.Emit(OpCodes.Ret);
  262.  
  263. //把创建的两个方法(Get,Set)加入到PropertyBuilder中。
  264. custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr);
  265. custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr);
  266. }
  267. }
  268.  
  269. /// <summary>
  270. /// 把属性加入到类型的实例。
  271. /// </summary>
  272. /// <param name="classType">类型的实例。</param>
  273. /// <param name="lcpi">要加入的属性列表。</param>
  274. /// <returns>返回处理过的类型的实例。</returns>
  275. public static Type AddPropertyToType(Type classType, List<CustPropertyInfo> lcpi)
  276. {
  277. AppDomain myDomain = Thread.GetDomain();
  278. AssemblyName myAsmName = new AssemblyName();
  279. myAsmName.Name = "MyDynamicAssembly";
  280.  
  281. //创建一个永久程序集,设置为AssemblyBuilderAccess.RunAndSave。
  282. AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,
  283. AssemblyBuilderAccess.RunAndSave);
  284.  
  285. //创建一个永久单模程序块。
  286. ModuleBuilder myModBuilder =
  287. myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");
  288. //创建TypeBuilder。
  289. TypeBuilder myTypeBuilder = myModBuilder.DefineType(classType.FullName,
  290. TypeAttributes.Public);
  291.  
  292. //把lcpi中定义的属性加入到TypeBuilder。将清空其它的成员。其功能有待扩展,使其不影响其它成员。
  293. AddPropertyToTypeBuilder(myTypeBuilder, lcpi);
  294.  
  295. //创建类型。
  296. Type retval = myTypeBuilder.CreateType();
  297.  
  298. //保存程序集,以便可以被Ildasm.exe解析,或被测试程序引用。
  299. myAsmBuilder.Save(myAsmName.Name + ".dll");
  300. return retval;
  301. }
  302. #endregion
  303.  
  304. #region 辅助类
  305. /// <summary>
  306. /// 自定义的属性信息类型。
  307. /// </summary>
  308. public class CustPropertyInfo
  309. {
  310. private string propertyName;
  311. private string type;
  312.  
  313. /// <summary>
  314. /// 空构造。
  315. /// </summary>
  316. public CustPropertyInfo() { }
  317.  
  318. /// <summary>
  319. /// 根据属性类型名称,属性名称构造实例。
  320. /// </summary>
  321. /// <param name="type">属性类型名称。</param>
  322. /// <param name="propertyName">属性名称。</param>
  323. public CustPropertyInfo(string type, string propertyName)
  324. {
  325. this.type = type;
  326. this.propertyName = propertyName;
  327. }
  328.  
  329. /// <summary>
  330. /// 获取或设置属性类型名称。
  331. /// </summary>
  332. public string Type
  333. {
  334. get { return type; }
  335. set { type = value; }
  336. }
  337.  
  338. /// <summary>
  339. /// 获取或设置属性名称。
  340. /// </summary>
  341. public string PropertyName
  342. {
  343. get { return propertyName; }
  344. set { propertyName = value; }
  345. }
  346.  
  347. /// <summary>
  348. /// 获取属性字段名称。
  349. /// </summary>
  350. public string FieldName
  351. {
  352. get { return propertyName.Substring(, ).ToLower() + propertyName.Substring(); }
  353. }
  354.  
  355. /// <summary>
  356. /// 获取属性在IL中的Set方法名。
  357. /// </summary>
  358. public string SetPropertyMethodName
  359. {
  360. get { return "set_" + PropertyName; }
  361. }
  362.  
  363. /// <summary>
  364. /// 获取属性在IL中的Get方法名。
  365. /// </summary>
  366. public string GetPropertyMethodName
  367. {
  368. get { return "get_" + PropertyName; }
  369. }
  370. }
  371. #endregion
  372. }

ClassHelper

XML之自动生成类,添加,修改,删除类的属性的更多相关文章

  1. vue-tree 组织架构图/树形图自动生成(含添加、删除、修改)

    项目中用代码生成组织架构图  有新增,编辑,删除的功能            生成树形图的组件git-hub地址: https://github.com/tower1229/Vue-Tree-Char ...

  2. JavaWeb_day03_员工信息添加修改删除

    day03员工的添加,修改,删除 修改功能 思路 : 点击修改员工数据之后,跳转到单行文本,查询要修改的员工id的全部信息,主键id设置为readonly,其余的都可以修改, 修改之后,提交按钮,提交 ...

  3. @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的

    出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙(子循),目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu @property 的本质是什么? @ ...

  4. 打通前后端全栈开发node+vue进阶【课程学习系统项目实战详细讲解】(3):用户添加/修改/删除 vue表格组件 vue分页组件

    第三章 建议学习时间8小时      总项目预计10章 学习方式:详细阅读,并手动实现相关代码(如果没有node和vue基础,请学习前面的vue和node基础博客[共10章] 演示地址:后台:demo ...

  5. SpringBoot定时任务升级篇(动态添加修改删除定时任务)

    需求缘起:在发布了<Spring Boot定时任务升级篇>之后得到不少反馈,其中有一个反馈就是如何动态添加修改删除定时任务?那么我们一起看看具体怎么实现,先看下本节大纲: (1)思路说明: ...

  6. 原生js添加和删除类

    原生js添加和删除类: this.className +=" "; this.className = this.className.replace(" 原来的类" ...

  7. 利用在线工具根据JSon数据自动生成对应的Java实体类

    如果你希望根据JSon数据自动生成对应的Java实体类,并且希望能进行变量的重命名,那么“JSON To Java”一定适合你.(下面的地址需要FQ) https://jsontojava.appsp ...

  8. T4 模板自动生成带注释的实体类文件

    T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll 生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 如果你没有 ...

  9. Web 1三级联动 下拉框 2添加修改删除 弹框

    Web  三级联动 下拉框 using System; using System.Collections.Generic; using System.Linq; using System.Web; u ...

  10. 原生JS动态添加和删除类

    原生JS动态添加和删除类 由于需要, 给按钮组监听点击事件(要求用事件委托),当有一个按钮被点击时,相应的给该按钮添加一个类(激活类),其他没有点击的按钮就要移出该类 添加和和删除类有三种方法 首先等 ...

随机推荐

  1. linux下主机用户管理(完整详情)

    (一) 创建新用户 useradd命令(也可以使用adduser)用来创建新的用户帐号,其命令格式如下: 表4-19 useradd命令常用选项 常用现象意 义 -d设置新用户的登陆目录 -e设置新用 ...

  2. java中数组复制的两种方式

    在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...

  3. OpenStack Paste.ini详解(二)

    接着OpenStack Paste.ini详解(一),接下来就分析request被paste.ini处理的流程 WSGI server接收到URL形式的request时,这些request首先会被Pa ...

  4. Java的大数计算BigNumber

    Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...

  5. UML常用关系

    转载自:http://justsee.iteye.com/blog/808799和http://www.uml.org.cn/oobject/201104212.asp 关系(4种):泛化关系,实现关 ...

  6. Spring - JPA 一对一, 一对多, 多对多关联

    现在有三个类:One Many Much One类 Much类 @Entity public class Much { @Id @GeneratedValue private Integer id; ...

  7. Mycat 配置说明(schema.xml )

    Schema.xml 作为 MyCat中重要的配置文件之一,管理着 MyCat的逻辑库.表.分片规则.DataNode以 及DataSource.弄懂这些配置,是正确使用MyCat的前提. schem ...

  8. 使用Mifare卡加密数据 笔记

    Mifare 是最常用的射频卡,具体介绍网上太多,我就不说了.,很多城市的最早的地铁公交卡都是用这种卡,后来被破解后都换成智能卡了. 但是由于技术成熟,使用方便,成本低,现在很多小区门禁卡,停车卡,食 ...

  9. java-线程实现方式

    实现方式: 1,继承Thread类 public class ThreadTest extends Thread { @Override public void run() { System.out. ...

  10. Webpack 引入bootstrap

    Bootstrap中是一种事实上的界面标准,标准到现在的网站大量的使用它.如果可以使用webpack引入的bootstrap.css,就可以一个npm install完成项目的依赖,而不必手工的添加到 ...