反射

在.NET中程序集是基本的部署单元,可以使用System.Reflection命名空间,通过编程来获取类型元数据等信息。

类型元数据的必要性:

.NET平台使用元数据完整地描述类型,包括类、接口、结构、委托、枚举。比如说创建一个自动属性,编译器生成私有的支持字段和get_PropertyName()和set_PropertyName两个方法,前提是创建的是读写属性。

元数据使用Assembly标记描述程序集信息,使用TypeDef标记描述定义类型的信息,TypeRef标记描述引用类型的信息,AssemblyRef描述引用的程序集信息,使用User Strings来记录程序中使用的字符串字面量:

如Console.WriteLine(“会被记录吗”);

“会被记录吗”就会被添加到UserString标记下。

   反射

使用反射服务,就是通过编程的方式,得到类型的元数据信息。通过反射,得到给定的dll或exe程序集中所有类型的列表,这个列表包括制定类型定义的方法、字段、属性和事件。

通过System.Reflection命名空间来读取.Net元数据,使用System.Type类。如何获取Type引用:

l  使用typeof(ClassName);

l  使用实例GetType方法,如:

ClassName obj=new ClassName();

Type t=obj.GetType();

l  使用静态GetType方法,如:

Type t=Type.GetType(“NameSpace.ClassName”);

首先Type是一个抽象类,不能创建一个Type对象,因为抽象类无法实例化。

反射的过程

应用反射技术,首先应该引用System.Reflection命名空间。通过Type.GetMethods()返回MethodInfo数组实现反射方法,通过Type.GetProperties()返回PropertyInfo数组实现属性反射,通过Type.GetFields()返回FieldInfo数组实现字段反射。通过Type.GetInterfaces()返回Type数组,也就是该类型所支持的接口数组,实现接口反射。通过Type.BaseType()等等获取类型的其他信息。

注意反射类型所实现的接口时,返回的是Type数组,而不是什么InterFaceInfo数组。

之前通过Type.GetMethods()方法获取MethodInfo,继而MethodInfo.GetParameters()来获取ParameterInfo,实现反射方法的参数。

动态加载程序集

使用Assembly类型的Load和LoadFrom方法动态记载程序集。Assembly asm=Assembly.Load(“ASMName“);

asm.FullName获取程序集基本信息

asm.GetTypes()得到Type数组,为程序集中定义的类型。

使用Assembly.LoadFrom方法,指定程序集的绝对路径。

反射共享程序集

GAC全局程序集缓存,可以使用gacutil.exe将具有强名称的程序集添加到全局程序集缓存。这些程序集由计算机上的很多应用程序共享,比如:System.Windows.Forms.

晚期绑定

用于构建可扩展程序。

Type t=asm.GetType(“AsmName.ClassName”);

Object o=Activator.CreateInstance(t);

如是,我们在不引入命名空间的前提下,创建了一个实例对象。如ClassName为Car,创建一个BMW的实例。

不能够使用BMW+”.”操作符获取Car类的成员,需要借助反射的方法。

MethodInfo method=t.GetMethod(“Accelerate”);

method.Invoke(BMW,null);

即完成调用BMW的加速方法。

调用有参数的方法,如下:

method.Invoke(BMW,new object[]{true,2});

 

总结:

反射:通过编程的方式来获取类型的元数据信息。

元数据的必要性:.NET平台使用元数据来描述类型信息。

怎样实现反射:获取Type引用,调用方法属性即可。

反射程序集:需要动态加载,获取Assembly引用asm。asm.GetTypes再获取Type引用,进一步反射类型。

晚期绑定:在不引入命名空间的前提下,声明dll中的类实例对象。也需要先通过反射来获取Type引用。

流程图:

 

posted @ 2015-05-13 21:51  SharpL  阅读(306)  评论(0编辑  收藏  举报