public NullableConversion(Type to, bool isImplicit, Conversion underlying) : base(to, isImplicit) { UnderlyingConversion = underlying; }
public static CandidateInfo <T> ResolveOverloads <T>(List <Tuple <T, ParameterInfo[]> > overloads, IEnumerable <ArgumentInfo> arguments, NameResolver resolver) where T : MemberInfo { var candidates = overloads.SelectMany(ov => ParserUtil.EvaluateArgumentList(ov.Item1, ov.Item2, arguments, resolver)).ToList(); // Type inference for (int i = 0; i < candidates.Count; i++) { if (candidates[i].Member is MethodInfo && ((MethodInfo)(MemberInfo)candidates[i].Member).IsGenericMethodDefinition) { candidates[i] = TypeInferer.TypeInference(candidates[i], resolver); } } // Remove nulls (entries where type inference failed) and entries that are not applicable (§7.5.3.1 Applicable function member) candidates = candidates.Where(c => c != null && c.Parameters.All(p => p.Mode == ArgumentMode.In ? Conversion.Implicit(p.Argument, p.ParameterType) != null : p.ParameterType == p.Argument.ExpressionType)).ToList(); if (candidates.Count == 0) { return(null); } if (candidates.Count == 1) { return(candidates[0]); } // We have more than one candidate, so need to find the “best” one bool[] cannot = new bool[candidates.Count]; for (int i = 0; i < cannot.Length; i++) { for (int j = i + 1; j < cannot.Length; j++) { int compare = candidates[i].Better(candidates[j]); if (compare != 1) // j is not better { cannot[j] = true; } if (compare != -1) // i is not better { cannot[i] = true; } } } CandidateInfo <T> candidate = null; for (int i = 0; i < cannot.Length; i++) { if (!cannot[i]) { if (candidate == null) { candidate = candidates[i]; } else { // There is more than one applicable candidate — method call is ambiguous return(null); } } } // Either candidate == null, in which case no candidate was better than all others, or this is the successful candidate return(candidate); }