XML之自动生成类,添加,修改,删除类的属性
1.
- class ClassHelperDemo
- {
- public static void Main()
- {
- #region 演示一:动态生成类。
- //生成一个类t。
- Type t = ClassHelper.BuildType("MyClass");
- #endregion
- #region 演示二:动态添加属性到类。
- //先定义两个属性。
- List<ClassHelper.CustPropertyInfo> lcpi = new List<ClassHelper.CustPropertyInfo>();
- ClassHelper.CustPropertyInfo cpi;
- cpi = new ClassHelper.CustPropertyInfo("System.String", "Name1");
- lcpi.Add(cpi);
- cpi = new ClassHelper.CustPropertyInfo("System.String", "Name2");
- lcpi.Add(cpi);
- //再加入上面定义的两个属性到我们生成的类t。
- t = ClassHelper.AddProperty(t, lcpi);
- //把它显示出来。
- DispProperty(t);
- //再定义两个属性。
- lcpi.Clear();
- cpi = new ClassHelper.CustPropertyInfo("System.Int32", "Orther1");
- lcpi.Add(cpi);
- cpi = new ClassHelper.CustPropertyInfo("System.Int32", "Orther2");
- lcpi.Add(cpi);
- //再加入上面定义的两个属性到我们生成的类t。
- t = ClassHelper.AddProperty(t, lcpi);
- //再把它显示出来,看看有没有增加到4个属性。
- DispProperty(t);
- #endregion
- #region 演示三:动态从类里删除属性。
- //把'S1'属性从类t中删除。
- t = ClassHelper.DeleteProperty(t, "Name1");
- //显示出来,可以看到'S1'不见了。
- DispProperty(t);
- #endregion
- #region 演示四:动态获取和设置属性值。
- //先生成一个类t的实例o。
- object o = ClassHelper.CreateInstance(t);
- //给S2,I2属性赋值。
- ClassHelper.SetPropertyValue(o, "Name2", "abcd");
- ClassHelper.SetPropertyValue(o, "Orther2", );
- //再把S2,I2的属性值显示出来。
- Console.WriteLine("Name2 = {0}", ClassHelper.GetPropertyValue(o, "Name2"));
- Console.WriteLine("Orther2 = {0}", ClassHelper.GetPropertyValue(o, "Orther2"));
- #endregion
- Console.Read();
- Console.ReadKey();
- }
- public static void DispProperty(Type t)
- {
- Console.WriteLine("ClassName '{0}'", t.Name);
- foreach (PropertyInfo pInfo in t.GetProperties())
- {
- Console.WriteLine("Has Property '{0}'", pInfo.ToString());
- }
- Console.WriteLine("");
- }
- }
ClassHelperDemo
2.
- class ClassHelper
- {
- #region 公有方法
- /// <summary>
- /// 根据类的类型型创建类实例。
- /// </summary>
- /// <param name="t">将要创建的类型。</param>
- /// <returns>返回创建的类实例。</returns>
- public static object CreateInstance(Type t)
- {
- return Activator.CreateInstance(t);
- }
- /// <summary>
- /// 根据类的名称,属性列表创建型实例。
- /// </summary>
- /// <param name="className">将要创建的类的名称。</param>
- /// <param name="lcpi">将要创建的类的属性列表。</param>
- /// <returns>返回创建的类实例</returns>
- public static object CreateInstance(string className, List<CustPropertyInfo> lcpi)
- {
- Type t = BuildType(className);
- t = AddProperty(t, lcpi);
- return Activator.CreateInstance(t);
- }
- /// <summary>
- /// 根据属性列表创建类的实例,默认类名为DefaultClass,由于生成的类不是强类型,所以类名可以忽略。
- /// </summary>
- /// <param name="lcpi">将要创建的类的属性列表</param>
- /// <returns>返回创建的类的实例。</returns>
- public static object CreateInstance(List<CustPropertyInfo> lcpi)
- {
- return CreateInstance("DefaultClass", lcpi);
- }
- /// <summary>
- /// 根据类的实例设置类的属性。
- /// </summary>
- /// <param name="classInstance">将要设置的类的实例。</param>
- /// <param name="propertyName">将要设置属性名。</param>
- /// <param name="propertSetValue">将要设置属性值。</param>
- public static void SetPropertyValue(object classInstance, string propertyName, object propertSetValue)
- {
- classInstance.GetType().InvokeMember(propertyName, BindingFlags.SetProperty,
- null, classInstance, new object[] { Convert.ChangeType(propertSetValue, propertSetValue.GetType()) });
- }
- /// <summary>
- /// 根据类的实例获取类的属性。
- /// </summary>
- /// <param name="classInstance">将要获取的类的实例</param>
- /// <param name="propertyName">将要设置的属性名。</param>
- /// <returns>返回获取的类的属性。</returns>
- public static object GetPropertyValue(object classInstance, string propertyName)
- {
- return classInstance.GetType().InvokeMember(propertyName, BindingFlags.GetProperty,
- null, classInstance, new object[] { });
- }
- /// <summary>
- /// 创建一个没有成员的类型的实例,类名为"DefaultClass"。
- /// </summary>
- /// <returns>返回创建的类型的实例。</returns>
- public static Type BuildType()
- {
- return BuildType("DefaultClass");
- }
- /// <summary>
- /// 根据类名创建一个没有成员的类型的实例。
- /// </summary>
- /// <param name="className">将要创建的类型的实例的类名。</param>
- /// <returns>返回创建的类型的实例。</returns>
- public static Type BuildType(string className)
- {
- AppDomain myDomain = Thread.GetDomain();
- AssemblyName myAsmName = new AssemblyName();
- myAsmName.Name = "MyDynamicAssembly";
- //创建一个永久程序集,设置为AssemblyBuilderAccess.RunAndSave。
- AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,AssemblyBuilderAccess.RunAndSave);
- //创建一个永久单模程序块。
- ModuleBuilder myModBuilder =myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");
- //创建TypeBuilder。
- TypeBuilder myTypeBuilder = myModBuilder.DefineType(className,TypeAttributes.Public);
- //创建类型。
- Type retval = myTypeBuilder.CreateType();
- //保存程序集,以便可以被Ildasm.exe解析,或被测试程序引用。
- myAsmBuilder.Save(myAsmName.Name + ".dll");
- return retval;
- }
- /// <summary>
- /// 添加属性到类型的实例,注意:该操作会将其它成员清除掉,其功能有待完善。
- /// </summary>
- /// <param name="classType">指定类型的实例。</param>
- /// <param name="lcpi">表示属性的一个列表。</param>
- /// <returns>返回处理过的类型的实例。</returns>
- public static Type AddProperty(Type classType, List<CustPropertyInfo> lcpi)
- {
- //合并先前的属性,以便一起在下一步进行处理。
- MergeProperty(classType, lcpi);
- //把属性加入到Type。
- return AddPropertyToType(classType, lcpi);
- }
- /// <summary>
- /// 添加属性到类型的实例,注意:该操作会将其它成员清除掉,其功能有待完善。
- /// </summary>
- /// <param name="classType">指定类型的实例。</param>
- /// <param name="cpi">表示一个属性。</param>
- /// <returns>返回处理过的类型的实例。</returns>
- public static Type AddProperty(Type classType, CustPropertyInfo cpi)
- {
- List<CustPropertyInfo> lcpi = new List<CustPropertyInfo>();
- lcpi.Add(cpi);
- //合并先前的属性,以便一起在下一步进行处理。
- MergeProperty(classType, lcpi);
- //把属性加入到Type。
- return AddPropertyToType(classType, lcpi);
- }
- /// <summary>
- /// 从类型的实例中移除属性,注意:该操作会将其它成员清除掉,其功能有待完善。
- /// </summary>
- /// <param name="classType">指定类型的实例。</param>
- /// <param name="cpi">要移除的属性。</param>
- /// <returns>返回处理过的类型的实例。</returns>
- public static Type DeleteProperty(Type classType, string propertyName)
- {
- List<string> ls = new List<string>();
- ls.Add(propertyName);
- //合并先前的属性,以便一起在下一步进行处理。
- List<CustPropertyInfo> lcpi = SeparateProperty(classType, ls);
- //把属性加入到Type。
- return AddPropertyToType(classType, lcpi);
- }
- /// <summary>
- /// 从类型的实例中移除属性,注意:该操作会将其它成员清除掉,其功能有待完善。
- /// </summary>
- /// <param name="classType">指定类型的实例。</param>
- /// <param name="lcpi">要移除的属性列表。</param>
- /// <returns>返回处理过的类型的实例。</returns>
- public static Type DeleteProperty(Type classType, List<string> ls)
- {
- //合并先前的属性,以便一起在下一步进行处理。
- List<CustPropertyInfo> lcpi = SeparateProperty(classType, ls);
- //把属性加入到Type。
- return AddPropertyToType(classType, lcpi);
- }
- #endregion
- #region 私有方法
- /// <summary>
- /// 把类型的实例t和lcpi参数里的属性进行合并。
- /// </summary>
- /// <param name="t">实例t</param>
- /// <param name="lcpi">里面包含属性列表的信息。</param>
- private static void MergeProperty(Type t, List<CustPropertyInfo> lcpi)
- {
- CustPropertyInfo cpi;
- foreach (PropertyInfo pi in t.GetProperties())
- {
- cpi = new CustPropertyInfo(pi.PropertyType.FullName, pi.Name);
- lcpi.Add(cpi);
- }
- }
- /// <summary>
- /// 从类型的实例t的属性移除属性列表lcpi,返回的新属性列表在lcpi中。
- /// </summary>
- /// <param name="t">类型的实例t。</param>
- /// <param name="lcpi">要移除的属性列表。</param>
- private static List<CustPropertyInfo> SeparateProperty(Type t, List<string> ls)
- {
- List<CustPropertyInfo> ret = new List<CustPropertyInfo>();
- CustPropertyInfo cpi;
- foreach (PropertyInfo pi in t.GetProperties())
- {
- foreach (string s in ls)
- {
- if (pi.Name != s)
- {
- cpi = new CustPropertyInfo(pi.PropertyType.FullName, pi.Name);
- ret.Add(cpi);
- }
- }
- }
- return ret;
- }
- /// <summary>
- /// 把lcpi参数里的属性加入到myTypeBuilder中。注意:该操作会将其它成员清除掉,其功能有待完善。
- /// </summary>
- /// <param name="myTypeBuilder">类型构造器的实例。</param>
- /// <param name="lcpi">里面包含属性列表的信息。</param>
- private static void AddPropertyToTypeBuilder(TypeBuilder myTypeBuilder, List<CustPropertyInfo> lcpi)
- {
- FieldBuilder customerNameBldr;
- PropertyBuilder custNamePropBldr;
- MethodBuilder custNameGetPropMthdBldr;
- MethodBuilder custNameSetPropMthdBldr;
- MethodAttributes getSetAttr;
- ILGenerator custNameGetIL;
- ILGenerator custNameSetIL;
- // 属性Set和Get方法要一个专门的属性。这里设置为Public。
- getSetAttr =
- MethodAttributes.Public | MethodAttributes.SpecialName |
- MethodAttributes.HideBySig;
- // 添加属性到myTypeBuilder。
- foreach (CustPropertyInfo cpi in lcpi)
- {
- //定义字段。
- customerNameBldr = myTypeBuilder.DefineField(cpi.FieldName,
- Type.GetType(cpi.Type),
- FieldAttributes.Private);
- //定义属性。
- //最后一个参数为null,因为属性没有参数。
- custNamePropBldr = myTypeBuilder.DefineProperty(cpi.PropertyName,
- PropertyAttributes.HasDefault,
- Type.GetType(cpi.Type),
- null);
- //定义Get方法。
- custNameGetPropMthdBldr =
- myTypeBuilder.DefineMethod(cpi.GetPropertyMethodName,
- getSetAttr,
- Type.GetType(cpi.Type),
- Type.EmptyTypes);
- custNameGetIL = custNameGetPropMthdBldr.GetILGenerator();
- custNameGetIL.Emit(OpCodes.Ldarg_0);
- custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr);
- custNameGetIL.Emit(OpCodes.Ret);
- //定义Set方法。
- custNameSetPropMthdBldr =
- myTypeBuilder.DefineMethod(cpi.SetPropertyMethodName,
- getSetAttr,
- null,
- new Type[] { Type.GetType(cpi.Type) });
- custNameSetIL = custNameSetPropMthdBldr.GetILGenerator();
- custNameSetIL.Emit(OpCodes.Ldarg_0);
- custNameSetIL.Emit(OpCodes.Ldarg_1);
- custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr);
- custNameSetIL.Emit(OpCodes.Ret);
- //把创建的两个方法(Get,Set)加入到PropertyBuilder中。
- custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr);
- custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr);
- }
- }
- /// <summary>
- /// 把属性加入到类型的实例。
- /// </summary>
- /// <param name="classType">类型的实例。</param>
- /// <param name="lcpi">要加入的属性列表。</param>
- /// <returns>返回处理过的类型的实例。</returns>
- public static Type AddPropertyToType(Type classType, List<CustPropertyInfo> lcpi)
- {
- AppDomain myDomain = Thread.GetDomain();
- AssemblyName myAsmName = new AssemblyName();
- myAsmName.Name = "MyDynamicAssembly";
- //创建一个永久程序集,设置为AssemblyBuilderAccess.RunAndSave。
- AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,
- AssemblyBuilderAccess.RunAndSave);
- //创建一个永久单模程序块。
- ModuleBuilder myModBuilder =
- myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");
- //创建TypeBuilder。
- TypeBuilder myTypeBuilder = myModBuilder.DefineType(classType.FullName,
- TypeAttributes.Public);
- //把lcpi中定义的属性加入到TypeBuilder。将清空其它的成员。其功能有待扩展,使其不影响其它成员。
- AddPropertyToTypeBuilder(myTypeBuilder, lcpi);
- //创建类型。
- Type retval = myTypeBuilder.CreateType();
- //保存程序集,以便可以被Ildasm.exe解析,或被测试程序引用。
- myAsmBuilder.Save(myAsmName.Name + ".dll");
- return retval;
- }
- #endregion
- #region 辅助类
- /// <summary>
- /// 自定义的属性信息类型。
- /// </summary>
- public class CustPropertyInfo
- {
- private string propertyName;
- private string type;
- /// <summary>
- /// 空构造。
- /// </summary>
- public CustPropertyInfo() { }
- /// <summary>
- /// 根据属性类型名称,属性名称构造实例。
- /// </summary>
- /// <param name="type">属性类型名称。</param>
- /// <param name="propertyName">属性名称。</param>
- public CustPropertyInfo(string type, string propertyName)
- {
- this.type = type;
- this.propertyName = propertyName;
- }
- /// <summary>
- /// 获取或设置属性类型名称。
- /// </summary>
- public string Type
- {
- get { return type; }
- set { type = value; }
- }
- /// <summary>
- /// 获取或设置属性名称。
- /// </summary>
- public string PropertyName
- {
- get { return propertyName; }
- set { propertyName = value; }
- }
- /// <summary>
- /// 获取属性字段名称。
- /// </summary>
- public string FieldName
- {
- get { return propertyName.Substring(, ).ToLower() + propertyName.Substring(); }
- }
- /// <summary>
- /// 获取属性在IL中的Set方法名。
- /// </summary>
- public string SetPropertyMethodName
- {
- get { return "set_" + PropertyName; }
- }
- /// <summary>
- /// 获取属性在IL中的Get方法名。
- /// </summary>
- public string GetPropertyMethodName
- {
- get { return "get_" + PropertyName; }
- }
- }
- #endregion
- }
ClassHelper
XML之自动生成类,添加,修改,删除类的属性的更多相关文章
- vue-tree 组织架构图/树形图自动生成(含添加、删除、修改)
项目中用代码生成组织架构图 有新增,编辑,删除的功能 生成树形图的组件git-hub地址: https://github.com/tower1229/Vue-Tree-Char ...
- JavaWeb_day03_员工信息添加修改删除
day03员工的添加,修改,删除 修改功能 思路 : 点击修改员工数据之后,跳转到单行文本,查询要修改的员工id的全部信息,主键id设置为readonly,其余的都可以修改, 修改之后,提交按钮,提交 ...
- @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的
出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙(子循),目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu @property 的本质是什么? @ ...
- 打通前后端全栈开发node+vue进阶【课程学习系统项目实战详细讲解】(3):用户添加/修改/删除 vue表格组件 vue分页组件
第三章 建议学习时间8小时 总项目预计10章 学习方式:详细阅读,并手动实现相关代码(如果没有node和vue基础,请学习前面的vue和node基础博客[共10章] 演示地址:后台:demo ...
- SpringBoot定时任务升级篇(动态添加修改删除定时任务)
需求缘起:在发布了<Spring Boot定时任务升级篇>之后得到不少反馈,其中有一个反馈就是如何动态添加修改删除定时任务?那么我们一起看看具体怎么实现,先看下本节大纲: (1)思路说明: ...
- 原生js添加和删除类
原生js添加和删除类: this.className +=" "; this.className = this.className.replace(" 原来的类" ...
- 利用在线工具根据JSon数据自动生成对应的Java实体类
如果你希望根据JSon数据自动生成对应的Java实体类,并且希望能进行变量的重命名,那么“JSON To Java”一定适合你.(下面的地址需要FQ) https://jsontojava.appsp ...
- T4 模板自动生成带注释的实体类文件
T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll 生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 如果你没有 ...
- Web 1三级联动 下拉框 2添加修改删除 弹框
Web 三级联动 下拉框 using System; using System.Collections.Generic; using System.Linq; using System.Web; u ...
- 原生JS动态添加和删除类
原生JS动态添加和删除类 由于需要, 给按钮组监听点击事件(要求用事件委托),当有一个按钮被点击时,相应的给该按钮添加一个类(激活类),其他没有点击的按钮就要移出该类 添加和和删除类有三种方法 首先等 ...
随机推荐
- linux下主机用户管理(完整详情)
(一) 创建新用户 useradd命令(也可以使用adduser)用来创建新的用户帐号,其命令格式如下: 表4-19 useradd命令常用选项 常用现象意 义 -d设置新用户的登陆目录 -e设置新用 ...
- java中数组复制的两种方式
在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...
- OpenStack Paste.ini详解(二)
接着OpenStack Paste.ini详解(一),接下来就分析request被paste.ini处理的流程 WSGI server接收到URL形式的request时,这些request首先会被Pa ...
- Java的大数计算BigNumber
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...
- UML常用关系
转载自:http://justsee.iteye.com/blog/808799和http://www.uml.org.cn/oobject/201104212.asp 关系(4种):泛化关系,实现关 ...
- Spring - JPA 一对一, 一对多, 多对多关联
现在有三个类:One Many Much One类 Much类 @Entity public class Much { @Id @GeneratedValue private Integer id; ...
- Mycat 配置说明(schema.xml )
Schema.xml 作为 MyCat中重要的配置文件之一,管理着 MyCat的逻辑库.表.分片规则.DataNode以 及DataSource.弄懂这些配置,是正确使用MyCat的前提. schem ...
- 使用Mifare卡加密数据 笔记
Mifare 是最常用的射频卡,具体介绍网上太多,我就不说了.,很多城市的最早的地铁公交卡都是用这种卡,后来被破解后都换成智能卡了. 但是由于技术成熟,使用方便,成本低,现在很多小区门禁卡,停车卡,食 ...
- java-线程实现方式
实现方式: 1,继承Thread类 public class ThreadTest extends Thread { @Override public void run() { System.out. ...
- Webpack 引入bootstrap
Bootstrap中是一种事实上的界面标准,标准到现在的网站大量的使用它.如果可以使用webpack引入的bootstrap.css,就可以一个npm install完成项目的依赖,而不必手工的添加到 ...