原文:https://cloud.tencent.com/developer/article/1129356
一、对C#反射机制的理解
二、概念理解后,必须找到方法去完成,给出管理的主要语法
三、最终给出实用的例子,反射出来dll中的方法编程
参考: C#反射,MSDN编程指南c#
反射是一个程序集发现及运行的过程,经过反射能够获得.exe或.dll等程序集内部的信息。使用反射能够看到一个程序集内部的接口、类、方法、字段、属性、特性等等信息。在System.Reflection命名空间内包含多个反射经常使用的类,下面表格列出了经常使用的几个类。
类型 做用
Assembly 经过此类能够加载操纵一个程序集,并获取程序集内部信息
EventInfo 该类保存给定的事件信息
FieldInfo 该类保存给定的字段信息
MethodInfo 该类保存给定的方法信息
MemberInfo 该类是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多个公用行为
Module 该类可使你能访问多个程序集中的给定模块
ParameterInfo 该类保存给定的参数信息
PropertyInfo 该类保存给定的属性信息设计
1、System.Reflection.Assembly类
经过Assembly能够动态加载程序集,并查看程序集的内部信息,其中最经常使用的就是Load()这个方法。
Assembly assembly=Assembly.Load("MyAssembly");
利用Assembly的object CreateInstance(string) 方法能够反射建立一个对象,参数0为类名。
2、System.Type类
Type是最经常使用到的类,经过Type能够获得一个类的内部信息,也能够经过它反射建立一个对象。通常有三个经常使用的方法可获得Type对象。code
//利用typeof() 获得Type对象 Type type=typeof(Example); //利用System.Object.GetType() 获得Type对象 Example example=new Example(); Type type=example.GetType(); //利用System.Type.GetType() 获得Type对象 Type type=Type.GetType("MyAssembly.Example",false,true);
注意参数0是类名,参数1表示若找不到对应类时是否抛出异常,参数1表示类名是否区分大小写
例子:
咱们最多见的是利用反射与Activator结合来建立对象。对象
Assembly assembly= Assembly.Load("MyAssembly"); Type type=assembly.GetType("Example"); object obj=Activator.CreateInstance(type);
3、反射方法
1.经过 System.Reflection.MethodInfo能查找到类里面的方法接口
Type type=typeof(Example); MethodInfo[] listMethodInfo=type.GetMethods(); foreach(MethodInfo methodInfo in listMethodInfo) Cosole.WriteLine("Method name is "+methodInfo.Name);
2.咱们也能经过反射方法执行类里面的方法2.咱们也能经过反射方法执行类里面的方法事件
Assembly assembly= Assembly.Load("MyAssembly"); Type type=assembly.GetType("Example"); object obj=Activator.CreateInstance(type); MethodInfo methodInfo=type.GetMethod("Hello World"); //根据方法名获取MethodInfo对象 methodInfo.Invoke(obj,null); //参数1类型为object[],表明Hello World方法的对应参数,输入值为null表明没有参数
4、反射属性
1.经过 System.Reflection.PropertyInfo 能查找到类里面的属性
经常使用的方法有GetValue(object,object[]) 获取属性值和 SetValue(object,object,object[]) 设置属性值ip
Type type=typeof(Example); PropertyInfo[] listPropertyInfo=type.GetProperties(); foreach(PropertyInfo propertyInfo in listPropertyInfo) Cosole.WriteLine("Property name is "+ propertyInfo.Name);
2.咱们也能够经过如下方法设置或者获取一个对象的属性值2.咱们也能够经过如下方法设置或者获取一个对象的属性值get
Assembly assembly=Assembly.Load("MyAssembly"); Type type=assembly.GetType("Example"); object obj=Activator.CreateInstance(type); PropertyInfo propertyInfo=obj.GetProperty("Name"); //获取Name属性对象 var name=propertyInfo.GetValue(obj,null); //获取Name属性的值 PropertyInfo propertyInfo2=obj.GetProperty("Age"); //获取Age属性对象 propertyInfo.SetValue(obj,34,null); //把Age属性设置为34
5、反射字段
经过 System.Reflection.FieldInfo 能查找到类里面的字段
它包括有两个经常使用方法SetValue(object ,object )和GetValue(object) 由于使用方法与反射属性很是类似,在此再也不多做介绍string
6、反射特性
经过System.Reflection.MemberInfo的GetCustomAttributes(Type,bool)就可反射出一个类里面的特性,如下例子能够反射出一个类的全部特性
Type type=typeof("Example"); object[] typeAttributes=type.GetCustomAttributes(false); //获取Example类的特性 foreach(object attribute in typeAttributes) Console.WriteLine("Attributes description is "+attribute.ToString());
经过下面例子,能够获取Example类Name属性的全部特性经过下面例子,能够获取Example类Name属性的全部特性
public class Example { [DataMemberAttribute] publics string Name {get;set;} .................. } Type type = typeof(Example); PropertyInfo propertyInfo=type.GetProperty("Name"); //获取Example类的Name属性 foreach (object attribute in propertyInfo.GetCustomAttributes(false)) //遍历Name属性的全部特性 Console.WriteLine(“Property attribute: "+attribute.ToString());
总结:
Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的区别
在C#中,咱们要使用反射,首先要搞清楚如下命名空间中几个类的关系:
System.Reflection命名空间
(1) AppDomain:应用程序域,能够将其理解为一组程序集的逻辑容器
(2) Assembly:程序集类
(3) Module:模块类
(4) Type:使用反射获得类型信息的最核心的类
他们之间是一种从属关系,也就是说,一个AppDomain能够包含N个Assembly,一个Assembly能够包含N个Module,而一个Module能够包含N个Type.
1,Assembly.Load()
这个方法经过程序集的长名称(包括程序集名,版本信息,语言文化,公钥标记)来加载程序集的,会加载此程序集引用的其余程序集,通常状况下都应该优先使用 这个方法,他的执行效率比LoadFrom要高不少,并且不会形成重复加载的问题(缘由在第2点上说明)
使用这个方法的时候, CLR会应用必定的策略来查找程序集,实际上CLR按以下的顺序来定位程序集:
⑴若是程序集有强名称,在首先在全局程序集缓(GAC)中查找程序集。
⑵若是程序集的强名称没有正确指定或GAC中找不到,那么经过配置文件中的
⑶若是没有指定强名称或是在GAC中找不到,CLR会探测特定的文件夹:
假设你的应用程序目录是C:\AppDir,