




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、反射帮助类这个帮助类主要是用反射技术来实现的,既然说到反射那我们就来说说反射吧!1、 概念:这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:'程序集(Assembly)、'模块(Module)、'类型(class)组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如: 通常程序员面试题,有这样关于反射的解释:反射可以动态地创建类型的实例,还可以将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。2、 下面我们来说说反
2、射中经常用到的几个类吧!a) Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。i. 下面是关于Assembly类的例子 public void AssemblyTest() Console.WriteLine("-Assembly 类的使用-"); Console.WriteLine();/获取当前所执行代码的程序集信息 Assembly assembly = Assembly.GetExecutingAssembly(); Console.WriteLine("获取程序集的位置:"
3、+ assembly.CodeBase); Console.WriteLine("获取程序集的入口点:"+assembly.EntryPoint); Console.WriteLine("获取程序集的显示名称:"+assembly.FullName); Console.WriteLine("获取包含当前程序集清单的模块:"+assembly.ManifestModule); Console.WriteLine(); /获取当前程序集的名称和信息 AssemblyName assemblyName = assembly.GetName(
4、); Console.WriteLine("获取或设置程序集的简单名称:"+assemblyName.Name); Console.WriteLine("获取程序集的名称:"+assemblyName.FullName); Console.WriteLine("获取或设置程序集的URL位置:"+assemblyName.CodeBase); Console.WriteLine("获取或设置程序集的主版本号、次版本号、内部版本号和修订版本号:"+assemblyName.Version); Console.Write
5、Line(); /获取当前程序集的版本相关信息 Version version = assemblyName.Version; Console.WriteLine("获取当前程序集的主版本号:"+version.Major); Console.WriteLine("获取当前程序集的次版本号:" + version.Minor); Console.WriteLine("获取当前程序集的内部版本号:" + version.Build); Console.WriteLine("获取当前程序集的修订版本号:" + vers
6、ion.MajorRevision); Console.WriteLine(); ii.b) Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。i. 下面是关于Type类的例子:public void TypeTest() Console.WriteLine("-Type类的使用-"); Console.WriteLine(); /设置被检索的类 Type myType = Type.GetType("Demo.PersonClass"); /Type myType =
7、new PersonClass().GetType(); /检索信息 Console.WriteLine("获取当前成员名称:"+myType.Name); Console.WriteLine("获取当前完全限定名(不包括程序信):" + myType.FullName); Console.WriteLine("获取当前Type所在的够命名空间:"+myType.Namespace); Console.WriteLine(); /检索类成员 Console.WriteLine("获取方法相关信息:"+myType.
8、GetMethod("MetName").ToString(); Console.WriteLine("获取属性相关信息:"+myType.GetProperty("Name").ToString();Console.WriteLine("获取字段相关信息:"+ myType.GetField("name",BindingFlags.NonPublic | BindingFlags.Instance).ToString(); Console.WriteLine(); /设定自己为被检索的类 Ty
9、pe thisType = this.GetType(); c) 访问类成员中的常用到的几个类:/ <summary> / 访问类成员± / </summary> public void ClassMemberInfo() /指定被访问的类 /Type myType = Type.GetType("Demo.PersonClass") /或者这样指定被访问的类:这样可以获取属性值但要用到对象实例, PersonClass person = new PersonClass(); Type personType = person.GetType
10、(); Console.WriteLine("-MemberInfo访问类的所有成员-"); Console.WriteLine(); /MemberInfo类:遍历访问类中所有成员 MemberInfo memberInfo = personType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (MemberInfo m in member
11、Info) Console.WriteLine("成员名称:0 - 成员类型:1", m.Name, m.MemberType); Console.WriteLine(); Console.WriteLine("-MethodInfo类访问类的方法-"); Console.WriteLine(); /MethodInfo类:遍历被访问类的方法 MethodInfo methodInfo = personType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.I
12、nstance | BindingFlags.DeclaredOnly); foreach (MethodInfo m in methodInfo) Console.WriteLine("方法名称:0 - 方法类型:1, 2", m.Name, m.ReturnType); Console.WriteLine(); Console.WriteLine("-PropertyInfo类访问属性-"); Console.WriteLine(); /Propertyinfo类:遍历被访问类的属性 PropertyInfo prop = personType.Ge
13、tProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (PropertyInfo p in prop) Console.WriteLine("属性名称:0 属性类型:1 属性值:2", p.Name, p.PropertyType, p.GetValue(person, null); Console.WriteLine(); Console.WriteLine("-FieldInfo
14、类访问字段-");Console.WriteLine(); /FieldInfo类:遍历被访问类的字段 FieldInfo fieldInfo = personType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (FieldInfo f in fieldInfo) Console.WriteLine("字段名称:0 - 字段类型:1", f.Name, f.FieldType
15、); Console.WriteLine(); Console.WriteLine("-ConstructorInfo类访问构造函数-"); Console.WriteLine(); /ConstructorInfo类:遍历被访问类的构造函数 ConstructorInfo constructor = personType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (Con
16、structorInfo c in constructor) Console.WriteLine("构造函数名称:0 - 构造函数类型:1", c.Name, c.MemberType); Console.WriteLine(); Console.WriteLine("-EventInfo类访问类的事件元数据-"); Console.WriteLine(); /EventInfo类:遍历被访问类的事件 EventInfo eventInfo = personType.GetEvents(BindingFlags.Public | BindingFlags
17、.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (EventInfo e in eventInfo) Console.WriteLine("事件名称:0 - 成员类型:1", e.Name, e.MemberType); Console.WriteLine(); Console.WriteLine("-ParameterInfo用于表示参数元数据-"); Console.WriteLine(); /ParameterInfo类:检索PersonClass类中
18、MetName()方法中的参数 MethodInfo method = personType.GetMethod("TestName"); /("TestName")为方法名 ParameterInfo para = method.GetParameters(); int count = 0; foreach (ParameterInfo p in para) count+; Console.WriteLine("参数" +count+ "名称:0, 类型:1", p.Name, p.ParameterType);
19、 Console.WriteLine(); d) 调用类成员/ <summary> / 调用类成员 / 第一种调用方法就是用MethodInfo类调用方法,PropertyInfo类调用属性,FieldInfo类调用字段,EventInfo类调用事件,/ ConstructorInfo类调用构造函数 / 第二种方法就是用Type类的InvokeMember()方法 / </summary> public void OperMembers() /指定被访问的类 PersonClass personClass = new PersonClass(); Type type =
20、 personClass.GetType(); / 或者这样指定被访问类(注意:静态类时(“GetType(“命名空间.类名”)”) /Type type = Type.GetType("Demo.PersonClass"); /操作方法 string strName = new String "我是谁" ; /方法参数的值 MethodInfo methodInfo = type.GetMethod("MetName"); /("MetName")是方法名 methodInfo.Invoke(personClas
21、s, strName); Console.WriteLine("操作方法改变值后为:" + personClass.Name); /操作属性 PropertyInfo property = type.GetProperty("Name"); /("Name")表示属性名 property.SetValue(personClass, "wxy", null); /"wxy"为新值 SetValue为设置属性的值,GetValue为获取属性的值 Console.WriteLine("操作属
22、性改变后的值为:"+personClass.Name); /操作字段 FieldInfo field = type.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance); field.SetValue(personClass, "hehe"); /"hehe" 表示给字段赋的新值 Console.WriteLine("操作字段改变后的值为:"+field.Name ); Console.WriteLine(); /操作事件 Eve
23、ntInfo eventInfo = type.GetEvent("WMShout"); /("WMShout")表示的是事件名 Console.WriteLine("声明该成员的类:"+eventInfo.DeclaringType); Console.WriteLine("事件名称:"+eventInfo.Name); Console.WriteLine("事件类型:"+eventInfo.MemberType); Console.WriteLine(); /操作构造函数 Construct
24、orInfo constructor = type.GetConstructor(System.Type.EmptyTypes); 下面是我封装的一个Helper类,这个类主要用于一个对象给另一个对象赋值(就是一个对象中的属性或字段想要得到与另一个对象相同的值那么就可以可以用这封装的这个类):using System;using ;using System.Linq;using System.Text;using System.Reflection;using System.Collections;using System.IO;namespace ReflectionDemo public
25、class ReflectionHelper / <summary> / 将一个对象中的属性值赋给对应的另一个对象中的属性 / </summary> / <param name="target">被赋值的对象</param> / <param name="initial">赋值的对象</param> public static void GetObjectAttributeAssignmentAnotherObject(object target, object initial) /
26、获取被赋值对象的属性 PropertyInfo propertyInfo1 = target.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); /获取赋值对象的属性 PropertyInfo propertyInfo2 = initial.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlag
27、s.Instance | BindingFlags.DeclaredOnly); foreach (PropertyInfo property in propertyInfo1) /遍历被赋值对象的属性 foreach (PropertyInfo p in propertyInfo2) /遍历赋值对象的属性 /判断被赋值对象与赋值对象中的属性名和属性类型都同那就赋值 if (property.Name = p.Name && property.PropertyType = p.PropertyType && property.CanWrite = true) p
28、roperty.SetValue(target, p.GetValue(initial, null), null); /向对象设置值(SetValue为置,GetValue为获取) / <summary> / 将一个对象中的属性值赋给对应的另一个对象中的属性 / </summary> / <param name="target">被赋值的对象</param> / <param name="initial">赋值的对象</param> / <param name="ht
29、">保存两个对象中不一样的属性(被赋值的保存成Key,赋值的保存成Value)</param> public static void SetObjectAttributes(object target, object initial,Hashtable ht) /获取被赋值对象的属性 PropertyInfo propertyInfo1 = target.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags
30、.DeclaredOnly); /获取赋值对象的属性 PropertyInfo propertyInfo2 = initial.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (PropertyInfo property in propertyInfo1) /遍历被赋值对象的属性 foreach (PropertyInfo p in propertyInfo2) /遍历赋值对象的属性
31、 if (ht.Count > 0) /保证Hashtable中有数据 if (htproperty.Name != null) /判断Hashtable中的key值在Hashtable中是否能找到 if (htproperty.Name.Equals(p.Name) /判断两个对象中和的属性在Hashtable中是否是相对应 property.SetValue(target, p.GetValue(initial, null), null);/赋值(SetValue为设置值,GetValue取值) continue; /判断被赋值对象与赋值对象中的属性名和属性类型都相同那就赋值 if
32、(property.Name = p.Name && property.PropertyType = p.PropertyType && property.CanWrite = true) property.SetValue(target, p.GetValue(initial, null), null); / <summary> / 将一个对象中的字段值赋给对应的另一个对象中的字段 / </summary> / <param name="obj1">需要被赋值的对象</param> / <
33、;param name="obj2">已经有值的对象</param> public static void SetObjectField(object target, object initial) /获取被赋值对象中的字段 FieldInfo fieldInfo1 = target.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); /获取赋值对象中的字段 FieldIn
34、fo fieldInfo2 = initial.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (FieldInfo field in fieldInfo1) foreach (FieldInfo f in fieldInfo2) /判断被赋值对象与赋值对象的名称与类型是否都相同 if (field.Name = f.Name && field.FieldType = f.F
35、ieldType) field.SetValue(target, f.GetValue(initial); /赋值(SetValue为设置值,GetValue为获取值) / <summary> / 将一个对象中的属性值赋给对应的另一个对象中的属性(包含不一样的属性名称,但要一一对应) / </summary> / <param name="target">被赋值对象</param> / <param name="initial">赋值对象</param> / <param na
36、me="dic">这个集合存放两个对象中不一样属性名称的,被赋值对象属性被存放为Key,赋值对象被存放为Value</param> public static void GetObjectAttributeAssignmentAnotherObject(object target, object initial, IDictionary<object, object> dic) /获取被赋值对象的属性 PropertyInfo propertyInfoObj1 = target.GetType().GetProperties(BindingFl
37、ags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);/获取赋值对象的属性 PropertyInfo propertyInfoObj2 = initial.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (PropertyInfo property in pro
38、pertyInfoObj1) /遍历被赋值对象的属性 foreach (PropertyInfo p in propertyInfoObj2) if (dic.Count > 0) /判断dic对象中Key值是否存在,如果不存在但以用了的话那就会出KeyNotFoundException异常 if (property.Name) && dicproperty.Name.Equals(p.Name) property.SetValue(target, p.GetValue(initial, null), null); continue; if (property.Name
39、= p.Name && property.PropertyType = p.PropertyType && property.CanWrite = true) property.SetValue(target, p.GetValue(initial, null), null); 反射在下列情况下很有用:需要访问程序元数据的属性。请参见主题使用反射访问属性。检查和实例化程序集中的类型。在运行时构建新类型。使用 System.Reflection.Emit 中的类。执行后期绑定,访问在运行时创建的类型的方法。请参见主题动态加载和使用类型。反射的一般概念:反射提供了封
40、装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。我觉得这个已经是对反射比较干脆利落的诠释。这里的”动态”二字非常重要,即指的是运行时刻,在运行的时刻我们可以根据程序逻辑或外部要求(比如配置文件等)创建类型的实例,然后实现象用new构造对象一样同等的效果。当然构造了这个实例之后下来的访问和以前就一样。反射的效率:采用反射构造对象的实例,机器明显出现延迟,不言而喻,反射是以牺牲效率为代价的。优点:1.反射是一个非常优秀的代码生成替代工具,能够显著减少代码长度,并缓解应用维护压力。2.可以降低不
41、同模块之间的依赖关系,大大提高可维护性。缺点:反射是以牺牲效率为代价的即消耗性能大。下面是测试反射性能的代码:using System;using ;using System.Linq;using System.Text;namespace WindowsFormsApplication1 public class CTester private double a; public CTester() a = 10; public void test1() a = (a - 0.0001) * 1.0001; public double Geta() return a; using System
42、;using ;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using ;using System.Reflection;namespace WindowsFormsApplication1 public partial class Form1 : Form public Form1() InitializeComponent(); private void Form1_Load(object sender, EventArgs e)
43、 private void button1_Click(object sender, EventArgs e) int dt1 = DateTime.Now.Minute * 60000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; CTester aTest = new CTester(); for (int i = 0; i < 1000; i+) for (int j = 0; j < 100; j+) aTest.test1(); int dt2 = DateTime.Now.Minute * 60000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; int spand = dt2 - dt1; label1.Text = "用掉时间:" + spand.ToString(); label3.Text = "值为:" + aTest.Geta(); /test1(); private void button2_Click(object sender, EventArgs e) int dt1 = DateTime.Now.Minute * 6000
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 畜牧资源利用与疫病防控责任协议
- 营销渠道拓展合作合同内容
- 行政管理中员工行为的心理学分析题及答案
- 游戏行业游戏引擎优化方案
- 施工质检规范试题及答案
- 行政管理心理学与员工心理契约的关联研究试题及答案
- 2025关于餐厅转让合同的范本
- 2025年心理学学习方法试题及答案
- 2025年建筑工程考试的项目管理试题及答案
- 行政管理心理学实践案例分析试题及答案
- 围术期室性早搏处理
- 违反公务用车管理制度谈心谈话记录内容
- 《心理健康教育》课件-关爱心灵拥抱阳光
- 办理证件协议书
- PAC(流产后关爱)项目之流产与避孕培训课件
- 肠道疾病的诊疗培训课件
- 山东省施工现场监理表格目录及格式汇编
- 山西煤炭运销集团三元石窟煤业有限公司矿山矿产资源开发利用、地质环境保护与土地复垦方案
- 团队项目任务完成进度跟进表模板
- 山东省应急管理普法知识竞赛参考题库-中(多选题)
- 色彩与服装色彩搭配
评论
0/150
提交评论