反射是.NET中一个非常重要的特性。通过反射,配合元数据。可以实现很多面向对象无法实现的灵活性。从而,也改变了一些我们固有的编程习惯。比如,使用空的Interface对类型分组。
学习反射,最重要的是需要了解元数据这个概念。元数据是用来描述一个类型或类型成员的数据。从而使一个类型或成员能够声明自己的特性,而不是在运行时的对象来生名字对的特性。
比较常见的使用反射的地方有:
1. 使用名字(而不是在编译时)决定调用类型的成员
纯粹的这种需求很少,除非进行一些非常高级的开发。例如,写自己的脚本引擎等。
2. 绕过编译时的一些验证
比如对私有成员或属性的访问。
3. 描述类型或成员的特性
比如:属性声明自己是否可以被IDE的DesignTime访问。
4. 动态构造对象的实例
可以实现简单的根据配置文件进行对象构造。
5. 注入
通过动态生成类型的方式,实现运行时对已有类型进行扩展。
个人认为,上面的顺序可以初步的看成一个对反射不了解的人学习反射由浅入深的阶段。我没有看过PetShop的源代码,但是,我想PetShop中大量使用反射的目的,主要就是上面的第四条和第五条。
关于反射的缺点,首当其冲的,就是它比较难以理解。因此,没有特别明确的需求的情况下,应该尽量避免使用。
其次,性能是反射的一个很重要的缺点。一般来说,使用反射来调用方法或操作属性的性能约为直接使用的100倍左右。(采用注入Emit和动态程序集Dynamic Assembly可以提高这里的性能,这个属于更高级的话题了)因此,更需要慎重使用了。
对于要求灵活性非常高的场所,可以考虑使用反射。比如,我写的一个序列化的功能,因为需要能够适应各种类型,并且能够将类型中的属性都存储起来。所以,大量的采用了反射的机制。