private MethodInvoker GetMethodInvoker(MethodInfo method) { Type declaringType; int num2; bool flag = false; bool flag2 = false; bool flag3 = false; MethodInfo methodToCall = method; int index = 0; DynamicMethod method2 = new DynamicMethod(method.Name, typeof(object), new Type[] { typeof(object), typeof(object[]) }, typeof(Adapter).Module, true); ILGenerator iLGenerator = method2.GetILGenerator(); ParameterInfo[] parameters = method.GetParameters(); int num3 = 0; if ((!method.IsStatic && method.DeclaringType.IsValueType) && !method.IsVirtual) { flag = true; num3++; } foreach (ParameterInfo info2 in parameters) { if (info2.IsOut || info2.ParameterType.IsByRef) { flag2 = true; num3++; } } LocalBuilder[] builderArray = null; Type returnType = method.ReturnType; if (num3 > 0) { if (flag2 && (returnType != typeof(void))) { num3++; flag3 = true; } builderArray = new LocalBuilder[num3]; index = 0; if (flag) { declaringType = method.DeclaringType; builderArray[index] = iLGenerator.DeclareLocal(declaringType); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Unbox_Any, declaringType); iLGenerator.Emit(OpCodes.Stloc, builderArray[index]); index++; } for (num2 = 0; num2 < parameters.Length; num2++) { declaringType = parameters[num2].ParameterType; if (parameters[num2].IsOut || declaringType.IsByRef) { if (declaringType.IsByRef) { declaringType = declaringType.GetElementType(); } builderArray[index] = iLGenerator.DeclareLocal(declaringType); iLGenerator.Emit(OpCodes.Ldarg_1); EmitLdc(iLGenerator, num2); iLGenerator.Emit(OpCodes.Ldelem_Ref); if (declaringType.IsValueType) { iLGenerator.Emit(OpCodes.Unbox_Any, declaringType); } else if (declaringType != typeof(object)) { iLGenerator.Emit(OpCodes.Castclass, declaringType); } iLGenerator.Emit(OpCodes.Stloc, builderArray[index]); index++; } } if (flag3) { builderArray[index] = iLGenerator.DeclareLocal(returnType); } } index = 0; if (!method.IsStatic) { if (method.DeclaringType.IsValueType) { if (method.IsVirtual) { declaringType = FindInterfaceForMethod(method, out methodToCall); if (declaringType == null) { this.useReflection = true; return(null); } iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Castclass, declaringType); } else { iLGenerator.Emit(OpCodes.Ldloca, builderArray[index]); index++; } } else { iLGenerator.Emit(OpCodes.Ldarg_0); } } num2 = 0; while (num2 < parameters.Length) { declaringType = parameters[num2].ParameterType; if (declaringType.IsByRef) { iLGenerator.Emit(OpCodes.Ldloca, builderArray[index]); index++; } else if (parameters[num2].IsOut) { iLGenerator.Emit(OpCodes.Ldloc, builderArray[index]); index++; } else { iLGenerator.Emit(OpCodes.Ldarg_1); EmitLdc(iLGenerator, num2); iLGenerator.Emit(OpCodes.Ldelem_Ref); if (declaringType.IsValueType) { iLGenerator.Emit(OpCodes.Unbox_Any, declaringType); } else if (declaringType != typeof(object)) { iLGenerator.Emit(OpCodes.Castclass, declaringType); } } num2++; } iLGenerator.Emit(method.IsStatic ? OpCodes.Call : OpCodes.Callvirt, methodToCall); if (flag3) { iLGenerator.Emit(OpCodes.Stloc, builderArray[builderArray.Length - 1]); } if (flag2) { index = flag ? 1 : 0; for (num2 = 0; num2 < parameters.Length; num2++) { declaringType = parameters[num2].ParameterType; if (parameters[num2].IsOut || declaringType.IsByRef) { if (declaringType.IsByRef) { declaringType = declaringType.GetElementType(); } iLGenerator.Emit(OpCodes.Ldarg_1); EmitLdc(iLGenerator, num2); iLGenerator.Emit(OpCodes.Ldloc, builderArray[index]); if (declaringType.IsValueType) { iLGenerator.Emit(OpCodes.Box, declaringType); } iLGenerator.Emit(OpCodes.Stelem_Ref); index++; } } } if (returnType == typeof(void)) { iLGenerator.Emit(OpCodes.Ldnull); } else { if (flag3) { iLGenerator.Emit(OpCodes.Ldloc, builderArray[builderArray.Length - 1]); } Adapter.DoBoxingIfNecessary(iLGenerator, returnType); } iLGenerator.Emit(OpCodes.Ret); return((MethodInvoker)method2.CreateDelegate(typeof(MethodInvoker))); }