.NET中的反射机制的内容介绍
一.什么是反射:
反射提供的是一种封装程序集、模块和类型的对象。通过反射可以动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
二.为什么使用反射(反射的优点):
使用反射可以使得我们很容易地使用自己或第三方开发的类型来增强应用程序的功能,从而设计出可动态扩展的应用程序。
三.反射的典型应用:
需要使用反射类型的应用程序比较少,我们也应当尽量避免使用它(性能问题)。
反射类型典型地应用于一些类库,这些类库通常需要理解一个类型的定义,以便提供某些丰富的功能。例如,FCL中的序列化机制,它使用反射来确定一个类型中定义了哪些字段,以便获取它们的值并写入字节流在网络上传输(序列化机制参见.NET Remoting相关知识)。
另外,当应用程序需要在运行时加载某个特定的类型或程序集时,需要用到反射。
四.反射的主要用途:
1. 反射程序集(程序集>模块>类型>类型成员)
使用 Assembly定义和加载程序集,获得程序集的相关信息;
实例方法:GetAssemblies()
2. 反射程序集中的模块
使用 Module加载在程序集清单中列出的模块,获得程序集中模块的相关信息;
实例方法:GetModules()
3. 反射模块中的类型
使用Type加载类型,获得模块中的类型信息;
实例方法:GetTypes()
4. 反射类型中的成员
使用MemberInfo加载成员,获得类型中的成员信息。
实例方法:GetMembers()
注意:这里可反射的成员可包括私有成员,可以利用将枚举类型BindingFlags作为参数传给重载的GetMembers方法。但是这种权利不应当被滥用,.NET Reflection采用了CAS机制(代码访问安全机制)保证了这点。(枚举类型BindingFlags的说明详见 MSDN)
反射类型中成员的目的包括:
1)创建一个类型的实例
System.Activator的CreateInstance方法
System.Activator的CreateInstanceFrom方法
System.AppDomain的一些实例方法
例如,CreateInstance, CreateInstanceAndUnwrap, CreateInstanceFrom, CreateInstanceFromAndUnwrap
System.Type 的InvokeMember实例方法
System.Reflection.ConstructorInfo的Invoke实例方法
2)调用一个类型的方法
绑定和调用都执行:System.Type 的InvokeMember实例方法(注意:InvokeMember不支持事件)
绑定和调用分离:(访问频繁时)
可用来绑定成员的类型包括:ConstructorInfo、MethodInfo、FieldInfo、EventInfo、PropertyInfo。
使用 ConstructorInfo 了解以下信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
使用 MethodInfo 了解以下信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。
使用 FieldInfo 了解以下信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
五.为什么不使用反射(反射的缺点):
使用反射来调用方法或者访问字段和属性等会造成性能的下降,原因有四:
1)在查找成员时,绑定操作会导致频繁的字符串比较;
2)在传递参数时,需要先构造一个数组并初始化其中的元素。然后在内部方法调用时,反射机制又要从数组中提取参数,并将它们放到堆栈上;
3)CLR检查传入方法的参数个数与类型带来的性能开销;
4)CLR确保调用者有适当的安全许可来访问成员带来的性能开销。
本文地址:http://www.45fan.com/dnjc/67326.html