苗乙乙:什么是反射
- 编辑:生活小常识 -苗乙乙:什么是反射
程序运行时将exe、dll文件加载到内存并执行一些操作的过程,这个过程称为。
下面这简单例子引入反射的使用,这个例子中定义了一个类并添加一个方法,我将使用反射调用方法。
上面的例子虽然简单,但是已足够说明反射的大致流程:
首先加载程序集
在程序集中查找我们需要的类(发现类型)
生成类实例
找到我们需要使用的,,,等成员类型
最后就是执行我们要执行的动作
因为程序集是个比较大的概念,而这偏离了这篇文章的主题,请移步我的另一篇文章《程序集》。
FCL提供了许多API来获取程序集中的类型,目前常用的API是Assembly中的ExportedTypes、DefinedTypes、GetType等,ExportedTypes属性用来获取公开方法即public类型,DefiedTypes属性用来获取所有类型,GetType方法获取一个指定的类型。
在FCL中提供了几个构造类型实例的机制分散在,,中,如果查看源码的话可以看到内部实现调用的都是。
在FCL中有反射提供了一个类型基类,其派生类如下图所示:
通常使用Type类型来发现成员类型如:Method,Filed,Property,Event等。
.Net 4中可以通过Type.GetTypeInfo扩展方法获取对象以便获取更多功能,相比Type类型TypeInfo代价更高。
下面通过例子来说明如何发现成员:
因为MemberInfo是所有成员类型的基类,那么我们先看一下获取所有的成员类型:
Why?我们只定义了7个成员,结果却显示14个?
如果你了解Event类型那么可以忽略add_OnSay,remove_OnSay。《事件和委托学习总结》
如果你了解Property那么可以忽略get_Name,set_Name。
如果你了解Object那么可以忽略ToString,Equals,GetHasCode,GetType。(所有的引用类型都继承Object)
如果你知道默认构造函数那么可以忽略.ctor。
现在剩下的,,,,5个类是我们定义的,还有2个,没有在上面运行结果中显示,我们发现这个成员有个共同点是:。
如何获取私有成员
我们将代码稍作改动看看效果:
GetMembers,FindMembers内部实现
以下方法均提供了多个重载方法
发现字段(FildInfo)
发现属性(PropertyInfo)
发现方法(MethodInfo)
发现构造器(ConstructorInfo)
发现事件(EventInfo)
调用字段
字段类型通过,方法对来操作
调用属性
属性类型通过,方法来操作
调用方法
方法通过Invoke执行方法
调用事件
调用静态方法
那么在反射得使用过程中,我通常使用两种实现方式来使用反射对象:一种基于接口的编程方式,另一种则是完全的字符串查找方式。所以我将基于接口的方式称为显式反射,这种做法的好处是编程期间我们可以直接使用类型的方法;而另一种基于字符串找好的方式我称它为隐式反射,因为在使用过程中无论得到那种成员类型都是通过字符串查找实现的。
反射一种技术,这种技术可以帮助我们实现一些看起来很酷的编程设计,但这种技术并不完美,它牺牲了效率换来了灵活性。至于这种牺牲的价值当然是仁者见仁智者见智。
苗乙乙:什么是反射