internal static MethodBase SelectMethod()

in src/TestFramework/Extension.Desktop/RuntimeTypeHelper.cs [119:236]


        internal static MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
        {
            if (match == null)
            {
                throw new ArgumentNullException(nameof(match));
            }

            int i;
            int j;

            Type[] realTypes = new Type[types.Length];
            for (i = 0; i < types.Length; i++)
            {
                realTypes[i] = types[i].UnderlyingSystemType;
            }

            types = realTypes;

            // If there are no methods to match to, then return null, indicating that no method
            // matches the criteria
            if (match.Length == 0)
            {
                return null;
            }

            // Find all the methods that can be described by the types parameter.
            // Remove all of them that cannot.
            int curIdx = 0;
            for (i = 0; i < match.Length; i++)
            {
                ParameterInfo[] par = match[i].GetParameters();
                if (par.Length != types.Length)
                {
                    continue;
                }

                for (j = 0; j < types.Length; j++)
                {
                    Type pCls = par[j].ParameterType;

                    if (pCls.ContainsGenericParameters)
                    {
                        if (pCls.IsArray != types[j].IsArray)
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (pCls == types[j])
                        {
                            continue;
                        }

                        if (pCls == typeof(object))
                        {
                            continue;
                        }
                        else
                        {
                            if (!pCls.IsAssignableFrom(types[j]))
                            {
                                break;
                            }
                        }
                    }
                }

                if (j == types.Length)
                {
                    match[curIdx++] = match[i];
                }
            }

            if (curIdx == 0)
            {
                return null;
            }

            if (curIdx == 1)
            {
                return match[0];
            }

            // Walk all of the methods looking the most specific method to invoke
            int currentMin = 0;
            bool ambig = false;
            int[] paramOrder = new int[types.Length];
            for (i = 0; i < types.Length; i++)
            {
                paramOrder[i] = i;
            }

            for (i = 1; i < curIdx; i++)
            {
                int newMin = FindMostSpecificMethod(match[currentMin], paramOrder, null, match[i], paramOrder, null, types, null);
                if (newMin == 0)
                {
                    ambig = true;
                }
                else
                {
                    if (newMin == 2)
                    {
                        currentMin = i;
                        ambig = false;
                        currentMin = i;
                    }
                }
            }

            if (ambig)
            {
                throw new AmbiguousMatchException();
            }

            return match[currentMin];
        }