反射是日常编码中不可或缺的重要特性但是大规模应用又会造成性能问题,因此很多人都写了提升反射速度的辅助类库。在.net1.1时代主要应用Emit自己构造IL,这需要你精通IL而且还不能怕麻烦。而在.net2.0时代由于引入了泛型使我们可以利用泛型委托来减少一部分IL Emit过程(详见这里),但是泛型是编译时确定的而我们更多的应用是在运行时得到或设置对象的属性,及动态执行方法。好在.net2.0又新增了一个辅助类DynamicMethod来帮助我们进行Emit编程(详见这里)。如今.net3.5了微软又给了我们更强大的武器Expression Tree(详见这里和这里),利用它我们就可以避免使用复杂的IL而可以从更抽象更高级的角度来动态Emit我们需要的东西。是不是觉得.net发展越来越人性化呢易用话呢?就在我写这篇文章的时候c#4.0的duck type估计已经出炉了,到时候Emit这技术也没多大用了完全都是微软替们我们搞定了(虽然编程的门槛降低了程序员越来越多了但我相信这些底层技术还是很有必要学习的,因为底层技术是一种解决问题的思路就像算法)。
首先我要说明一下快速反射的原理:用委托来间接操作我们要Get,Set的属性、字段和要动态执行的方法。下面我以得到字段的值来举例说明。假设有一个User类定义如下:
- public class User
- {
- public int _age;
- public int Age
- {
- get{ return this._age; }
- set{ this._age = value;}
- }
- }
用传统的反射方法是这样的:
- User u = new User();
- u.Age = 26;
- PropertyInfo p = typeof(Employee).GetProperty("Age");
- int age = Convert.ToInt32(p.GetValue(u, null));
而使用快速反射的思路我们就要先拿到访问属性Age的MethodInfo然后构建一个Delegate,然后我们就能以调用函数的速度来动态取得Age属性