Beispiel #1
0
        /// <summary>
        /// Gets which function member is better. (§ 14.4.2.2)
        /// </summary>
        /// <returns>0 if neither method is better. 1 if c1 is better. 2 if c2 is better.</returns>
        int GetBetterFunctionMember(Candidate c1, Candidate c2)
        {
            int  length = Math.Min(Math.Min(c1.Parameters.Count, c2.Parameters.Count), arguments.Count);
            bool foundBetterParamIn1 = false;
            bool foundBetterParamIn2 = false;

            for (int i = 0; i < length; i++)
            {
                if (arguments[i] == null)
                {
                    continue;
                }
                int res = MemberLookupHelper.GetBetterConversion(arguments[i], c1.Parameters[i].ReturnType, c2.Parameters[i].ReturnType);
                if (res == 1)
                {
                    foundBetterParamIn1 = true;
                }
                if (res == 2)
                {
                    foundBetterParamIn2 = true;
                }
            }
            if (foundBetterParamIn1 && !foundBetterParamIn2)
            {
                return(1);
            }
            if (foundBetterParamIn2 && !foundBetterParamIn1)
            {
                return(2);
            }
            if (foundBetterParamIn1 && foundBetterParamIn2)
            {
                return(0);                // ambigous
            }
            // If none conversion is better than any other, it is possible that the
            // expanded parameter lists are the same:
            for (int i = 0; i < length; i++)
            {
                if (!object.Equals(c1.Parameters[i].ReturnType, c2.Parameters[i].ReturnType))
                {
                    // if expanded parameters are not the same, neither function member is better
                    return(0);
                }
            }

            // the expanded parameters are the same, apply the tie-breaking rules from the spec:

            // if one method is generic and the other non-generic, the non-generic is better
            bool m1IsGeneric = c1.TypeParameterCount > 0;
            bool m2IsGeneric = c2.TypeParameterCount > 0;

            if (m1IsGeneric && !m2IsGeneric)
            {
                return(2);
            }
            if (m2IsGeneric && !m1IsGeneric)
            {
                return(1);
            }

            // for params parameters: non-expanded calls are better
            if (c1.IsExpanded && !c2.IsExpanded)
            {
                return(2);
            }
            if (c2.IsExpanded && !c1.IsExpanded)
            {
                return(1);
            }

            // if the number of parameters is different, the one with more parameters is better
            // this occurs when only when both methods are expanded
            if (c1.OriginalMethod.Parameters.Count > c2.OriginalMethod.Parameters.Count)
            {
                return(1);
            }
            if (c2.OriginalMethod.Parameters.Count > c1.OriginalMethod.Parameters.Count)
            {
                return(2);
            }

            IReturnType[] m1ParamTypes = new IReturnType[c1.Parameters.Count];
            IReturnType[] m2ParamTypes = new IReturnType[c2.Parameters.Count];
            for (int i = 0; i < m1ParamTypes.Length; i++)
            {
                m1ParamTypes[i] = c1.Parameters[i].ReturnType;
                m2ParamTypes[i] = c2.Parameters[i].ReturnType;
            }
            return(GetMoreSpecific(m1ParamTypes, m2ParamTypes));
        }