动态方法 DynamicMehthodHelper

参考原文:http://www.codeproject.com/Articles/14593/A-General-Fast-Method-Invoker

public static class DynamicMehthodHelper
{
	public delegate object FastInvokeHandler(object target, object[] argsValue);

	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++)
		{
			if (ps[i].ParameterType.IsByRef)
				paramTypes[i] = ps[i].ParameterType.GetElementType();
			else
				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], true);
		}
		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]);
		}
		if (!methodInfo.IsStatic)
		{
			il.Emit(OpCodes.Ldarg_0);
		}
		for (int i = 0; i < paramTypes.Length; i++)
		{
			if (ps[i].ParameterType.IsByRef)
			{
				il.Emit(OpCodes.Ldloca_S, locals[i]);
			}
			else
			{
				il.Emit(OpCodes.Ldloc, locals[i]);
			}
		}
		if (methodInfo.IsStatic)
		{
			il.EmitCall(OpCodes.Call, methodInfo, null);
		}
		else
		{
			il.EmitCall(OpCodes.Callvirt, methodInfo, null);
		}
		if (methodInfo.ReturnType == typeof(void))
		{
			il.Emit(OpCodes.Ldnull);
		}
		else
		{
			EmitBoxIfNeeded(il, methodInfo.ReturnType);
		}
		for (int i = 0; i < paramTypes.Length; i++)
		{
			if (ps[i].ParameterType.IsByRef)
			{
				il.Emit(OpCodes.Ldarg_1);
				EmitFastInt(il, i);
				il.Emit(OpCodes.Ldloc, locals[i]);
				if (locals[i].LocalType.IsValueType)
				{
					il.Emit(OpCodes.Box, locals[i].LocalType);
				}
				il.Emit(OpCodes.Stelem_Ref);
			}
		}
		il.Emit(OpCodes.Ret);
		return (FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler));
	}

	private static void EmitCastToReference(ILGenerator il, System.Type type)
	{
		if (type.IsValueType)
		{
			il.Emit(OpCodes.Unbox_Any, type);
		}
		else
		{
			il.Emit(OpCodes.Castclass, type);
		}
	}

	private static void EmitBoxIfNeeded(ILGenerator il, System.Type type)
	{
		if (type.IsValueType)
		{
			il.Emit(OpCodes.Box, type);
		}
	}

	private static void EmitFastInt(ILGenerator il, int value)
	{
		switch (value)
		{
			case -1:
				il.Emit(OpCodes.Ldc_I4_M1);
				return;
			case 0:
				il.Emit(OpCodes.Ldc_I4_0);
				return;
			case 1:
				il.Emit(OpCodes.Ldc_I4_1);
				return;
			case 2:
				il.Emit(OpCodes.Ldc_I4_2);
				return;
			case 3:
				il.Emit(OpCodes.Ldc_I4_3);
				return;
			case 4:
				il.Emit(OpCodes.Ldc_I4_4);
				return;
			case 5:
				il.Emit(OpCodes.Ldc_I4_5);
				return;
			case 6:
				il.Emit(OpCodes.Ldc_I4_6);
				return;
			case 7:
				il.Emit(OpCodes.Ldc_I4_7);
				return;
			case 8:
				il.Emit(OpCodes.Ldc_I4_8);
				return;
		}
		if (value > -129 && value < 128)
		{
			il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
		}
		else
		{
			il.Emit(OpCodes.Ldc_I4, value);
		}
	}
}
posted @   wesson2019  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示