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];
}