private void PatchMethodRef(MethodBody body, Action <TypeReference> onReplace, MethodReference meth, Instruction instr) { TypeReference declaringType; TypeReference returnType; var methDef = meth as MethodDefinition ?? meth.TryResolve(); var genRef = meth as GenericInstanceMethod; var methDeclType = meth.DeclaringType.IsGenericInstance ? meth.DeclaringType : methDef?.DeclaringType ?? meth.DeclaringType; var methRetType = meth.ReturnType.IsGenericInstance ? meth.ReturnType : methDef?.ReturnType ?? meth.ReturnType; if (TryGetValue(body.Method, methDeclType, out declaringType)) { onReplace(methDeclType); } if (TryGetValue(body.Method, methRetType, out returnType)) { onReplace(methRetType); } TypeReference tempType; var genArgs = new TypeReference[0]; if (genRef != null && (genArgs = genRef.GenericArguments.Select( a => TryGetValue(body.Method, a, out tempType) ? tempType : null).ToArray()).Any()) { foreach (var arg in genArgs.Where(a => a != null)) { onReplace(arg); } } if (returnType == null && declaringType == null && genArgs.All(a => a == null)) { return; } var newMeth = new MethodReference(meth.Name, returnType ?? meth.ReturnType, declaringType ?? meth.DeclaringType) { CallingConvention = meth.CallingConvention, ExplicitThis = meth.ExplicitThis, HasThis = meth.HasThis }; foreach (var parm in meth.Parameters) { TypeReference ptype; if (TryGetValue(body.Method, parm.ParameterType, out ptype)) { onReplace(parm.ParameterType); } var mparm = new ParameterDefinition(parm.Name, parm.Attributes, ptype ?? parm.ParameterType); newMeth.Parameters.Add(mparm); } if (genRef == null) { instr.Operand = newMeth; return; } var genMeth = new GenericInstanceMethod(methDef) { ReturnType = returnType ?? genRef.ReturnType }; for (var i = 0; i < genRef.GenericArguments.Count; i++) { var genArg = genArgs[i] ?? genRef.GenericArguments[i]; genMeth.GenericArguments.Add(genArg); } instr.Operand = genMeth; }