普通反射方法
MethodInfo methodInfo = typeof(Person).GetMethod("Say");
methodInfo.Invoke(new Person(), new object[]{"hello"});
快速反射方法
FastInvokeHandler fastInvoker = GetMethodInvoker(methodInfo); fastInvoker(new Person(), new object[]{"hello"});
实现,首先需要定义一个委托:
public delegate object FastInvokeHandler(object target, object[] paramters);
public static FastInvokeHandler GetMethodInvoker(MethodInfo methodInfo) { DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module); ILGenerator il = dynamicMethod.GetILGenerator(); ParameterInfo[] ps = methodInfo.GetParameters(); Type[] paramTypes = new Type[ps.Length]; for (int i = 0; i < paramTypes.Length; i++) { paramTypes[i] = ps[i].ParameterType; } LocalBuilder[] locals = new LocalBuilder[paramTypes.Length]; for (int i = 0; i < paramTypes.Length; i++) { locals[i] = il.DeclareLocal(paramTypes[i]); } for (int i = 0; i < paramTypes.Length; i++) { il.Emit(OpCodes.Ldarg_1); EmitFastInt(il, i); il.Emit(OpCodes.Ldelem_Ref); EmitCastToReference(il, paramTypes[i]); il.Emit(OpCodes.Stloc, locals[i]); } il.Emit(OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) { il.Emit(OpCodes.Ldloc, locals[i]); } il.EmitCall(OpCodes.Call, methodInfo, null); if (methodInfo.ReturnType == typeof(void)) il.Emit(OpCodes.Ldnull); else EmitBoxIfNeeded(il, methodInfo.ReturnType); il.Emit(OpCodes.Ret); FastInvokeHandler invoder = (FastInvokeHandler)dynamicMethod.CreateDelegate( typeof(FastInvokeHandler)); return invoder; }
Well, I think this is a general way that can be used instead of most of the reflection methods to get about 50 times performance improvement. Any suggestions for improvements are welcome.
Extra advantage (reminded by MaxGuernsey): If an exception occurs in your code, FastInovker
would throw the original one, but the Method.Invoke
would throw a TargetInvocationException
.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here
Luyan China Member |
I am currently working for a .NET framework names AgileFramework. It's introduction at here: http://www.agilelabs.cn/agileframework Now I'm living in China. I have been designing and developing .NET based software applications for 5+ years. |