之前在做消息的自动注册机时,发现用反射获到的MethodInfo也是可以转成委托的,于是抽空整理了一下,写了一些用于优化反射的工具类和方法。
0.测试数据
以下数据为访问10000000次得到的结果,单位为毫秒可以看到,优化的效果还是很明显的。
直接访问 | 使用反射访问 | 优化反射访问 | |
---|---|---|---|
属性Get | 49 | 1961 | 143 |
属性Set | 42 | 2380 | 79 |
空方法调用 | 33 | 1389 | 33 |
1.PropertyInfo优化
代码很简单,不做过多说明了,直接附在下面。属性的优化用了个类封装了一下,适用于Get,Set都是public的情况,如果有不是public的需要可以修改一下。
public class PropertyWrapper<T>
{
private Action<T> setter;
private Func<T> getter;
public T Value
{
get
{
return getter();
}
set
{
setter(value);
}
}
public PropertyWrapper(object target, PropertyInfo propertyInfo)
{
var methodInfo = propertyInfo.GetSetMethod();
var @delegate = Delegate.CreateDelegate(typeof(Action<T>), target, methodInfo);
setter = (Action<T>)@delegate;
methodInfo = propertyInfo.GetGetMethod();
@delegate = Delegate.CreateDelegate(typeof(Func<T>), target, methodInfo);
getter = (Func<T>)@delegate;
}
}
2.MethodInfo优化
方法的优化直接用工具方法返回委托了。
public static class Utility
{
public static Action MethodWrapperAction(object target, MethodInfo methodInfo)
{
return (Action)Delegate.CreateDelegate(typeof(Action), target, methodInfo);
}
public static Action<T> MethodWrapperAction<T>(object target, MethodInfo methodInfo)
{
return (Action<T>)Delegate.CreateDelegate(typeof(Action<T>), target, methodInfo);
}
public static Action<T1, T2> MethodWrapperAction<T1, T2>(object target, MethodInfo methodInfo)
{
return (Action<T1, T2>)Delegate.CreateDelegate(typeof(Action<T1, T2>), target, methodInfo);
}
public static Action<T1,T2,T3> MethodWrapperAction<T1, T2, T3>(object target, MethodInfo methodInfo)
{
return (Action<T1, T2, T3>)Delegate.CreateDelegate(typeof(Action<T1, T2, T3>), target, methodInfo);
}
public static Func<TReslut> MethodWrapperFunc<TReslut>(object target, MethodInfo methodInfo)
{
return (Func<TReslut>)Delegate.CreateDelegate(typeof(Func<TReslut>), target, methodInfo);
}
public static Func<T1, TReslut> MethodWrapperFunc<T1, TReslut>(object target, MethodInfo methodInfo)
{
return (Func<T1, TReslut>)Delegate.CreateDelegate(typeof(Func<T1, TReslut>), target, methodInfo);
}
public static Func<T1, T2, TReslut> MethodWrapperFunc<T1, T2, TReslut>(object target, MethodInfo methodInfo)
{
return (Func<T1, T2, TReslut>)Delegate.CreateDelegate(typeof(Func<T1, T2, TReslut>), target, methodInfo);
}
public static Func<T1, T2, T3, Reslut> MethodWrapperFunc<T1, T2, T3, Reslut>(object target, MethodInfo methodInfo)
{
return (Func<T1, T2, T3, Reslut>)Delegate.CreateDelegate(typeof(Func<T1, T2, T3, Reslut>), target, methodInfo);
}
}
4.总结
之前一直纠结一个问题,在属性的get和set都为public时,有什么理由让我不用字段用属性呢。之前看某本书(忘记叫啥了)从编译级别阐述了一个理由。这次可以从反射的角度回答,当你需要使用反射访问变量时,属性比字段好优化。