internal static MethodCandidate InferGenericMethod(ApplicableCandidate /*!*/ candidate, ActualArguments /*!*/ actualArgs) { OverloadInfo target = candidate.Method.Overload; Assert.NotNull(target); Debug.Assert(target.IsGenericMethodDefinition); Debug.Assert(target.IsGenericMethod && target.ContainsGenericParameters); List <DynamicMetaObject /*!*/> args = GetAllArguments(candidate, actualArgs); if (args == null) { return(null); } Dictionary <Type, List <Type> > dependencies = GetDependencyMapping(target); Type[] genArgs = GetSortedGenericArguments(target, dependencies); Dictionary <Type, ArgumentInputs> inputs = GetArgumentToInputMapping(candidate.Method, args); // now process the inputs var binding = new Dictionary <Type, Type>(); var restrictions = new Dictionary <DynamicMetaObject, BindingRestrictions>(); bool noMethod = false; foreach (Type t in genArgs) { if (!inputs.TryGetValue(t, out ArgumentInputs inps)) { continue; } Type bestType = inps.GetBestType(candidate.Method.Resolver, binding, restrictions); if (bestType == null) { // we conflict with possible constraints noMethod = true; break; } } if (!noMethod) { // finally build a new MethodCandidate for the generic method genArgs = GetGenericArgumentsForInferedMethod(target, binding); if (genArgs == null) { // not all types we're inferred return(null); } OverloadInfo newMethod = target.MakeGenericMethod(genArgs); List <ParameterWrapper> newWrappers = CreateNewWrappers(candidate.Method, newMethod, target); List <ArgBuilder> argBuilders = CreateNewArgBuilders(candidate.Method, newMethod); if (argBuilders == null) { // one or more arg builders don't support type inference return(null); } if (restrictions.Count == 0) { restrictions = null; } // create the new method candidate return(candidate.Method.ReplaceMethod(newMethod, newWrappers, argBuilders, restrictions)); } return(null); }