int BetterConversion(Type s, Type t1, Type t2) { IType sType = compilation.FindType(s); IType t1Type = compilation.FindType(t1); IType t2Type = compilation.FindType(t2); return(conversions.BetterConversion(sType, t1Type, t2Type)); }
/// <summary> /// Returns 1 if c1 is better than c2; 2 if c2 is better than c1; or 0 if neither is better. /// </summary> int BetterFunctionMember(Candidate c1, Candidate c2) { // prefer applicable members (part of heuristic that produces a best candidate even if none is applicable) if (c1.ErrorCount == 0 && c2.ErrorCount > 0) { return(1); } if (c1.ErrorCount > 0 && c2.ErrorCount == 0) { return(2); } // C# 4.0 spec: ยง7.5.3.2 Better function member bool c1IsBetter = false; bool c2IsBetter = false; for (int i = 0; i < arguments.Length; i++) { int p1 = c1.ArgumentToParameterMap[i]; int p2 = c2.ArgumentToParameterMap[i]; if (p1 >= 0 && p2 < 0) { c1IsBetter = true; } else if (p1 < 0 && p2 >= 0) { c2IsBetter = true; } else if (p1 >= 0 && p2 >= 0) { switch (conversions.BetterConversion(arguments[i], c1.ParameterTypes[p1], c2.ParameterTypes[p2])) { case 1: c1IsBetter = true; break; case 2: c2IsBetter = true; break; } } } if (c1IsBetter && !c2IsBetter) { return(1); } if (!c1IsBetter && c2IsBetter) { return(2); } // prefer members with less errors (part of heuristic that produces a best candidate even if none is applicable) if (c1.ErrorCount < c2.ErrorCount) { return(1); } if (c1.ErrorCount > c2.ErrorCount) { return(2); } if (!c1IsBetter && !c2IsBetter) { // we need the tie-breaking rules // non-generic methods are better if (!c1.IsGenericMethod && c2.IsGenericMethod) { return(1); } else if (c1.IsGenericMethod && !c2.IsGenericMethod) { return(2); } // non-expanded members are better if (!c1.IsExpandedForm && c2.IsExpandedForm) { return(1); } else if (c1.IsExpandedForm && !c2.IsExpandedForm) { return(2); } // prefer the member with less arguments mapped to the params-array int r = c1.ArgumentsPassedToParamsArray.CompareTo(c2.ArgumentsPassedToParamsArray); if (r < 0) { return(1); } else if (r > 0) { return(2); } // prefer the member where no default values need to be substituted if (!c1.HasUnmappedOptionalParameters && c2.HasUnmappedOptionalParameters) { return(1); } else if (c1.HasUnmappedOptionalParameters && !c2.HasUnmappedOptionalParameters) { return(2); } // compare the formal parameters r = MoreSpecificFormalParameters(c1, c2); if (r != 0) { return(r); } // prefer non-lifted operators ILiftedOperator lift1 = c1.Member as ILiftedOperator; ILiftedOperator lift2 = c2.Member as ILiftedOperator; if (lift1 == null && lift2 != null) { return(1); } if (lift1 != null && lift2 == null) { return(2); } } return(0); }