private static void GenerateInvokeMethodIl(MethodDefinition method, Type[] paramTypes, ParameterInfo[] parameters, MethodInfo proxyOnGetMethod) { var il = method.GetILGenerator(); var argsLocal = il.DeclareLocal(typeof(object[])); il.Emit(OpCodes.Ldc_I4, paramTypes.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, argsLocal); foreach (var param in parameters) { il.Emit(OpCodes.Ldloc, argsLocal); il.Emit(OpCodes.Ldc_I4, param.Position); il.Emit(OpCodes.Ldarg, param.Position + 1); // +1 since Ldarg0 means this if (param.ParameterType.IsValueType) il.Emit(OpCodes.Box, param.ParameterType); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod")); il.Emit(OpCodes.Castclass, typeof(MethodInfo)); //il.Emit(OpCodes.Ldstr, targetMethod.Name); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Callvirt, proxyOnGetMethod); if (method.ReturnType == typeof(void)) il.Emit(OpCodes.Pop); else if (method.ReturnType.IsValueType) il.Emit(OpCodes.Unbox_Any, method.ReturnType); else if (method.ReturnType != typeof(object)) il.Emit(OpCodes.Castclass, method.ReturnType); il.Emit(OpCodes.Ret); }
private static bool BaseTypeHasMatchingPublicMethod(Type baseDef, MethodInfo targetMethod) { return baseDef.GetMethods() .Any( x => x.Name == targetMethod.Name && x.ReturnType == targetMethod.ReturnType && x.GetParameters() .Select(y => y.ParameterType) .SequenceEqual(targetMethod.GetParameters().Select(y => y.ParameterType))); }
private static void CopyGenericMethodParameters(MethodInfo targetMethod, MethodDefinition method, Dictionary<Type, Type> genArgMapping, Func<Type, Type> typeReplacer) { if (targetMethod.IsGenericMethodDefinition) { var targetGenArgs = targetMethod.GetGenericArguments(); var items = method.DefineGenericParameters(targetGenArgs.Select(x => x.Name).ToArray()).Zip(targetGenArgs, (paramBuilder, target) => new { paramBuilder, target }) .ToList(); foreach (var arg in items) { arg.paramBuilder.SetGenericParameterAttributes(arg.target.GenericParameterAttributes); genArgMapping[arg.target] = arg.paramBuilder; } foreach (var arg in items) { IEnumerable<Type> interfaceConstraints = arg.target.GetGenericParameterConstraints().Select(typeReplacer).ToList(); if (arg.target.BaseType != null) { var baseTypeFixed = typeReplacer(arg.target.BaseType); if (!baseTypeFixed.IsInterface) arg.paramBuilder.SetBaseTypeConstraint(baseTypeFixed); else { //arg.paramBuilder.SetBaseTypeConstraint(typeof(object)); interfaceConstraints = interfaceConstraints.Append(baseTypeFixed); } //if (arg.target.BaseType.IsGenericParameter) //{ // interfaceConstraints = interfaceConstraints.Except(arg.target.BaseType.GetInterfaces()); //} } arg.paramBuilder.SetInterfaceConstraints(interfaceConstraints.ToArray()); } } }