今天,无意中有发现了一个绝对简单的方案,适合不懂Emit的人群,而且简单到只需要一个泛型方法就可以了。
下面请出今天的主角:Delegate,相信大家应该都很熟悉这个类,所有的委托类都是继承自它。但是它的作用可不仅仅是一个基类而已哦。它还拥有众多的静态方法可供我们使用,这次用到的就是一个叫CreateDelegate的方法。
看一下这个方法的声明:public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method);当然还有很多重载,今天,就用这个最简单的。
关于这个方法,可以查阅MSDN的说明。简单的说,主要作用就是将一个MethodInfo实例变成一个type所指定的委托的实例。怎么做到的?用了两个CLR实现的方法(就是[MethodImpl(MethodImplOptions.InternalCall)]),因此实现方式不得而知。运用这个方法,可以非常简单的用下面这段代码实现一个将MethodInfo变成一个具体类型的委托:
static T GetDelegate<T>(object instance, MethodInfo methodInfo)
where T : class
{
return Delegate.CreateDelegate(typeof(T), instance, methodInfo) as T;
}
where T : class
{
return Delegate.CreateDelegate(typeof(T), instance, methodInfo) as T;
}
简单吧,调用的时候,就只需要把T指定为符合MethodInfo所指向方法的签名一致的一个具体的Delegate类型,当是实例方法时,通过Instance传入实例,否则传空,MethodInfo就穿入反射获得的方法。一切就这么简单。
至于性能,这个方式几乎接近直接调用(至少在我看来已经是属于误差的级别了)。