public override MethodBase SelectMethod(BindingFlags bindingAttr,MethodBase[] match,Type[] types,ParameterModifier[] modifiers)
{
int i;
int j;
Type[] realTypes = new Type[types.Length];
for (i=0;i<types.Length;i++) {
realTypes[i] = types[i].UnderlyingSystemType;
if (!(realTypes[i] is RuntimeType))
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"types");
}
types = realTypes;
// We don't automatically jump out on exact match.
if (match == null || match.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"),"match");
// 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++) {
//Console.WriteLine(match[i]);
ParameterInfo[] par = match[i].GetParametersNoCopy();
if (par.Length != types.Length)
continue;
for (j=0;j<types.Length;j++) {
Type pCls = par[j].ParameterType;
//Console.WriteLine(pCls);
if (pCls == types[j])
continue;
if (pCls == typeof(Object))
continue;
if (pCls.IsPrimitive) {
if (!(types[j].UnderlyingSystemType is RuntimeType) ||
!CanConvertPrimitive((RuntimeType)types[j].UnderlyingSystemType,(RuntimeType)pCls.UnderlyingSystemType))
break;
}
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(Environment.GetResourceString("RFLCT.Ambiguous"));
return match[currentMin];
}