internal static int FindMostSpecific()

in src/TestFramework/Extension.Desktop/RuntimeTypeHelper.cs [316:425]


        internal static int FindMostSpecific(
            ParameterInfo[] p1,
            int[] paramOrder1,
            Type paramArrayType1,
            ParameterInfo[] p2,
            int[] paramOrder2,
            Type paramArrayType2,
            Type[] types,
            object[] args)
        {
            // A method using params is always less specific than one not using params
            if (paramArrayType1 != null && paramArrayType2 == null)
            {
                return 2;
            }

            if (paramArrayType2 != null && paramArrayType1 == null)
            {
                return 1;
            }

            bool p1Less = false;
            bool p2Less = false;

            for (int i = 0; i < types.Length; i++)
            {
                if (args != null && args[i] == Type.Missing)
                {
                    continue;
                }

                Type c1, c2;

                // If a param array is present, then either
                //      the user re-ordered the parameters in which case
                //          the argument to the param array is either an array
                //              in which case the params is conceptually ignored and so paramArrayType1 == null
                //          or the argument to the param array is a single element
                //              in which case paramOrder[i] == p1.Length - 1 for that element
                //      or the user did not re-order the parameters in which case
                //          the paramOrder array could contain indexes larger than p.Length - 1
                ////          so any index >= p.Length - 1 is being put in the param array

                if (paramArrayType1 != null && paramOrder1[i] >= p1.Length - 1)
                {
                    c1 = paramArrayType1;
                }
                else
                {
                    c1 = p1[paramOrder1[i]].ParameterType;
                }

                if (paramArrayType2 != null && paramOrder2[i] >= p2.Length - 1)
                {
                    c2 = paramArrayType2;
                }
                else
                {
                    c2 = p2[paramOrder2[i]].ParameterType;
                }

                if (c1 == c2)
                {
                    continue;
                }

                if (c1.ContainsGenericParameters || c2.ContainsGenericParameters)
                {
                    continue;
                }

                switch (FindMostSpecificType(c1, c2, types[i]))
                {
                    case 0:
                        return 0;
                    case 1:
                        p1Less = true;
                        break;
                    case 2:
                        p2Less = true;
                        break;
                }
            }

            // Two way p1Less and p2Less can be equal.  All the arguments are the
            //  same they both equal false, otherwise there were things that both
            //  were the most specific type on....
            if (p1Less == p2Less)
            {
                // it's possible that the 2 methods have same sig and  default param in which case we match the one
                // with the same number of args but only if they were exactly the same (that is p1Less and p2Lees are both false)
                if (!p1Less && p1.Length != p2.Length && args != null)
                {
                    if (p1.Length == args.Length)
                    {
                        return 1;
                    }
                    else if (p2.Length == args.Length)
                    {
                        return 2;
                    }
                }

                return 0;
            }
            else
            {
                return (p1Less == true) ? 1 : 2;
            }
        }