使用委托调用比直接调用慢10%,使用反射是直接调用的600倍,当然这取决于方法内部是否还外拉数据,但是反射转委托调用的好处显而易见
所以我们需要使用反射和泛型方法来动态创建委托,并通过这些委托来调用特定的方法
先创建一个带有返回值的
public class RegisterDemo
{
private static RegisterManager _registerManager ;
public static void GetRegister()
{
MethodInfo methodInfo = typeof(RegisterManager).GetMethod("RegiserScoped", new Type[] { typeof(Type), typeof(Type) });
Func<RegisterManager, object, object, object> Register = MagicMethod<RegisterManager>(methodInfo);
Register(_registerManager, typeof(A), typeof(B));
}
static Func<T, object, object, object> MagicMethod<T>(MethodInfo methodInfo) where T : class
{
MethodInfo genericHelper = typeof(RegisterDemo).GetMethod("MagicMethodHelper", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo constructHelper = genericHelper.MakeGenericMethod(typeof(T), methodInfo.GetParameters()[0].ParameterType, methodInfo.GetParameters()[1].ParameterType,methodInfo.ReturnType);
object ret = constructHelper.Invoke(null, new object[] { methodInfo });
return (Func<T, object, object, object>)ret;
}
static Func<TTarget, object, object, object> MagicMethodHelper<TTarget, TParam1, TParam2, TReturn>(MethodInfo method)
where TTarget : class, new()
{
// 将方法转为委托
Func<TTarget, TParam1, TParam2, TReturn> func = (Func<TTarget, TParam1, TParam2, TReturn>)Delegate.CreateDelegate
(typeof(Func<TTarget, TParam1, TParam2, TReturn>), method);
// 创建一个更弱的委托调用上面的委托
Func<TTarget, object, object, object> ret = (TTarget target, object param1, object param2) => func(target, (TParam1)param1, (TParam2)param2);
return ret;
}
}
public class RegisterManager
{
public string RegiserScoped(Type from,Type to)
{
Console.WriteLine(123);
return "1111";
}
}
public class A
{
}
public class B { }
我们需要理解委托的参数含义,一个目标值,两个参数,一个返回值,注意看我们的RegiserScoped方法
它的返回值是string,目标值是RegisterManager,参数是两个Type,那么我们的委托需要签名,
在MagicMethodHelper方法中返回值是Func<TTarget, object, object, object>
其中TTarget指的是RegisterManager,后面三个object分别指的是两个参数Type,和返回值string
同理,我们写void类型的时候不需要返回值,这个时候用Action
public class RegisterDemo2
{
private static RegisterManager2 _registerManager;
public static void GetRegister()
{
MethodInfo methodInfo = typeof(RegisterManager2).GetMethod("RegiserScoped", new Type[] { typeof(Type), typeof(Type) });
Action<RegisterManager2, object, object> Register = MagicMethod<RegisterManager2>(methodInfo);
Register(_registerManager, typeof(A2), typeof(B2));
}
static Action<T, object, object> MagicMethod<T>(MethodInfo methodInfo) where T : class
{
MethodInfo genericHelper = typeof(RegisterDemo2).GetMethod("MagicMethodHelper", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo constructHelper = genericHelper.MakeGenericMethod(typeof(T), methodInfo.GetParameters()[0].ParameterType, methodInfo.GetParameters()[1].ParameterType);
object ret = constructHelper.Invoke(null, new object[] { methodInfo });
return (Action<T, object, object>)ret;
}
static Action<TTarget, object, object> MagicMethodHelper<TTarget, TParam1, TParam2>(MethodInfo method)
where TTarget : class, new()
{
// 将方法转为委托
Action<TTarget, TParam1, TParam2> action = (Action<TTarget, TParam1, TParam2>)Delegate.CreateDelegate
(typeof(Action<TTarget, TParam1, TParam2>), method);
// 创建一个更弱的委托调用上面的委托
Action<TTarget, object, object> ret = (TTarget target, object param1, object param2) => action(target, (TParam1)param1, (TParam2)param2);
return ret;
}
}
public class RegisterManager2
{
public void RegiserScoped(Type from, Type to)
{
Console.WriteLine(123);
}
}
public class A2
{
}
public class B2
{
}
在RegisterManager2中的RegiserScoped方法没有返回值,所以我们的委托需要用到Action,同上
原文来自
https://codeblog.jonskeet.uk/2008/08/09/making-reflection-fly-and-exploring-delegates/
标签:反射,提高,public,class,typeof,MethodInfo,methodInfo,Type,效率
From: https://www.cnblogs.com/guchen33/p/18075928