/// <summary> /// 创建表示指定的静态或实例方法的的委托。如果是实例方法,需要将实例对象作为第一个参数; /// </summary> /// <param name="method">描述委托要表示的静态或实例方法的 <see cref="MethodInfo"/>。</param> /// <returns>表示指定的静态或实例方法的委托。</returns> /// <remarks>如果是静态方法,则第一个参数无效。对于可变参数方法,只支持固定参数。</remarks> /// <exception cref="ArgumentNullException"><paramref name="method"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentException"><paramref name="method"/> 是开放构造方法。</exception> /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="method"/>。</exception> public static MethodInvoker CreateDelegate(this MethodInfo method) { CommonExceptions.CheckArgumentNull(method, "method"); Contract.Ensures(Contract.Result <MethodInvoker>() != null); if (method.ContainsGenericParameters) { // 不能对开放构造方法执行绑定。 throw CommonExceptions.BindOpenConstructedMethod("method"); } DynamicMethod dlgMethod = new DynamicMethod("MethodInvoker", typeof(object), new[] { typeof(object), typeof(object[]) }, method.Module, true); ILGenerator il = dlgMethod.GetILGenerator(); Contract.Assume(il != null); ParameterInfo[] parameters = method.GetParametersNoCopy(); int len = parameters.Length; // 参数数量检测。 if (len > 0) { il.EmitCheckArgumentNull(1, "parameters"); il.Emit(OpCodes.Ldarg_1); il.EmitCheckTargetParameterCount(parameters.Length); } // 加载实例对象。 if (!method.IsStatic) { il.EmitLoadInstance(method, typeof(object), true); } bool optimizeTailcall = true; // 加载方法参数。 for (int i = 0; i < len; i++) { il.Emit(OpCodes.Ldarg_1); il.EmitInt(i); Type paramType = parameters[i].ParameterType; if (paramType.IsByRef) { paramType = paramType.GetElementType(); Converter converter = il.GetConversion(typeof(object), paramType, ConversionType.Explicit); Console.WriteLine(converter); if (converter.NeedEmit) { il.Emit(OpCodes.Ldelem_Ref); converter.Emit(true); LocalBuilder local = il.DeclareLocal(paramType); il.Emit(OpCodes.Stloc, local); il.Emit(OpCodes.Ldloca, local); optimizeTailcall = false; } else { il.Emit(OpCodes.Ldelema, paramType); } } else { il.Emit(OpCodes.Ldelem_Ref); il.EmitConversion(typeof(object), paramType, true, ConversionType.Explicit); } } // 调用函数。 il.EmitInvokeMethod(method, null, typeof(object), optimizeTailcall); return((MethodInvoker)dlgMethod.CreateDelegate(typeof(MethodInvoker))); }