关闭

反射学习总结

标签: 反射
438人阅读 评论(0) 收藏 举报
分类:

反射学习总结

         一个类中的成员包括字段、属性、方法和事件,这些成员都是这个类的元数据。反射就是在一个类的外部或它所在程序集外部,通过这个类的元数据,创建一个这个类的类型的对象,然后访问其中的成员。例如:有一个Person类,我们可以通过以下两种方法获得这个类的类型的对象:

         第一种方法,用typeof()方法获取:Type tp = typeof(Person);

         第二种方法,用对象获取:Person p = new Person();  Type tp = p.GetType();

         Type类是实现反射的一个很重要的类,它描述的是一个类的类型。我们可以通过Type类中的一些方法获得一个类的所有成员,包括private修饰的成员。这些成员可以用一个抽象类MemberInfo来表示,MemberInfo类的子类FieldInfo、PropertyInfo、MethodInfo、EventInfo分别用来存储类中的字段信息、属性信息、方法信息和事件信息。对于方法成员来说,我们可以调用MethodInfo类的对象的Invoke方法,来执行存储在这个对象中的方法。对于数据成员来说,每个存储该成员的信息的类中都有一个获取该数据的GetValue方法和设置该数据的SetValue方法。我们还可以通过Type类中的方法来判断类和类之间的关系以及类的特征,比如是否是静态和或抽象类等。

         反射用于很多地方,比如说VS的智能提示功能、反编译器等,但一般在支持插件的程序中都要用到。插件和主程序是两个不同的程序集,并且插件是否存在对于主程序的运行和使用都不会产生影响,但只要有插件连接到主程序中,主程序就会响应插件的功能。这就要求我们不能在代码中通过手动添加引用来把插件加载到主程序中,而只能动态添加对插件的使用。因为手动添加耦合性太高,并且对于主程序来说,这个插件是非要不可的,而且主程序的代码还要改动。使用反射之后,如果有插件,就会使用插件,如果没有,也不影响主程序,并且添加对插件的使用后,不会改动主程序的任何代码。因此,反射还能够很好的起到解耦的作用,即降低程序集之间的耦合性。

         要使用反射来动态加载插件,我们需要在主程序中有一个加载程序集的方法。程序集是.NET中的概念,一个dll文件或exe文件就是一个程序集,程序集可以看成是相关类打的一个包。它里面主要包含有类型元数据、程序集元数据、IL代码、资源文件,每个程序集都有自己的名称、版本等信息,这些信息可以通过AssemblyInfo.cs文件来自定义。加载一个程序集要用到Assembly类的LoadFile方法,这个方法需要一个插件的全路径作为参数。加载之后,就利用这个类的另一个方法GetTypes获得该程序集中定义的所有的类。这个方法返回一个Type类型的对象的集合,遍历这个集合,根据集合中对象的类型创建该类型的实例。创建实例时使用Activator类的CreateInstance方法,它返回一个object类型的对象。通过这些对象所在类中的方法,我们就可以使用插件的功能了。

         对比两种处理程序集的方式,传统手动添加引用的程序性能较高,但程序缺少灵活性和扩展性;使用反射动态添加引用会使程序灵活性大大提高,但是需要在使用插件时,才将IL代码转换为二进制代码,这会使程序性能降低。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:49557次
    • 积分:899
    • 等级:
    • 排名:千里之外
    • 原创:39篇
    • 转载:11篇
    • 译文:0篇
    • 评论:3条