public static MethodInfo GetRealMethodInfoFromGeneric(MethodInfo method, object[] args) { try { var generics = new Dictionary <Type, Type>(); var parameters = method.GetParameters(); var parsedArgs = MockingUtil.GetTypesFromArguments(args); for (int i = 0; i < args.Length; i++) { MockingUtil.GetGenericsTypesFromActualType(parameters[i].ParameterType, parsedArgs[i], generics); } var genericArgs = method.GetGenericArguments().Select(x => generics[x]).ToArray(); return(method.MakeGenericMethod(genericArgs)); } catch { return(null); } }
internal static MethodInfo GetMethodByName(Type type, Type returnType, string memberName, ref object[] args) { if (type.IsProxy()) { type = type.BaseType; } var candidateMethods = type.GetAllMethods() .Where(m => m.Name == memberName) .Concat(type.GetAllProperties() .Where(p => p.Name == memberName) .SelectMany(p => new[] { p.GetGetMethod(true), p.GetSetMethod(true) }) .Where(m => m != null)) .Select(m => { if (m.IsGenericMethodDefinition && returnType != typeof(void) && m.GetGenericArguments().Length == 1 && m.ReturnType.ContainsGenericParameters) { var generics = new Dictionary <Type, Type>(); if (MockingUtil.GetGenericsTypesFromActualType(m.ReturnType, returnType, generics)) { return(m.MakeGenericMethod(generics.Values.Single())); } } return(m); }) .ToArray(); MethodInfo mockedMethod = null; if (candidateMethods.Length == 1) { var singleCandidate = candidateMethods[0]; var returnTypeMatches = ReturnTypeMatches(returnType, singleCandidate); var argsIgnored = args == null || args.Length == 0; if (returnTypeMatches && argsIgnored) { mockedMethod = singleCandidate; args = mockedMethod.GetParameters() .Select(p => { var byref = p.ParameterType.IsByRef; var paramType = byref ? p.ParameterType.GetElementType() : p.ParameterType; if (paramType.IsPointer) { paramType = typeof(IntPtr); } var isAny = (Expression)typeof(ArgExpr).GetMethod("IsAny").MakeGenericMethod(paramType).Invoke(null, null); if (byref) { isAny = ArgExpr.Ref(isAny); } return(isAny); }) .ToArray(); } } if (mockedMethod == null) { mockedMethod = FindMethodBySignature(candidateMethods, returnType, args); if (mockedMethod == null && returnType == typeof(void)) { mockedMethod = FindMethodBySignature(candidateMethods, null, args); } } if (mockedMethod == null) { var mockedProperty = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) .FirstOrDefault(property => property.Name == memberName); if (mockedProperty != null) { var getter = mockedProperty.GetGetMethod(true); if (getter != null && getter.ArgumentsMatchSignature(args)) { mockedMethod = getter; } if (mockedMethod == null) { var setter = mockedProperty.GetSetMethod(true); if (setter != null && setter.ArgumentsMatchSignature(args)) { mockedMethod = setter; } } if (mockedMethod == null) { throw new MissingMemberException(BuildMissingMethodMessage(type, mockedProperty, memberName)); } } } if (mockedMethod == null) { throw new MissingMemberException(BuildMissingMethodMessage(type, null, memberName)); } if (mockedMethod.ContainsGenericParameters) { mockedMethod = MockingUtil.GetRealMethodInfoFromGeneric(mockedMethod, args); } if (mockedMethod.DeclaringType != mockedMethod.ReflectedType) { mockedMethod = GetMethodByName(mockedMethod.DeclaringType, returnType, memberName, ref args); } return(mockedMethod); }