public override PropertyInfo SelectProperty(BindingFlags bindingAttr,PropertyInfo[] match,Type returnType,
Type[] indexes,ParameterModifier[] modifiers)
{
int i,j = 0;
if (match == null || match.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"),"match");
// Find all the properties that can be described by type indexes parameter
int CurIdx = 0;
int indexesLength = (indexes != null) ? indexes.Length : 0;
for (i=0;i<match.Length;i++) {
if (indexes != null)
{
ParameterInfo[] par = match[i].GetIndexParameters();
if (par.Length != indexesLength)
continue;
for (j=0;j<indexesLength;j++) {
Type pCls = par[j]. ParameterType;
// If the classes exactly match continue
if (pCls == indexes[j])
continue;
if (pCls == typeof(Object))
continue;
if (pCls.IsPrimitive) {
if (!(indexes[j].UnderlyingSystemType is RuntimeType) ||
!CanConvertPrimitive((RuntimeType)indexes[j].UnderlyingSystemType,(RuntimeType)pCls.UnderlyingSystemType))
break;
}
else {
if (!pCls.IsAssignableFrom(indexes[j]))
break;
}
}
}
if (j == indexesLength) {
if (returnType != null) {
if (match[i].PropertyType.IsPrimitive) {
if (!(returnType.UnderlyingSystemType is RuntimeType) ||
!CanConvertPrimitive((RuntimeType)returnType.UnderlyingSystemType,(RuntimeType)match[i].PropertyType.UnderlyingSystemType))
continue;
}
else {
if (!match[i].PropertyType.IsAssignableFrom(returnType))
continue;
}
}
match[CurIdx++] = match[i];
}
}
if (CurIdx == 0)
return null;
if (CurIdx == 1)
return match[0];
// Walk all of the properties looking the most specific method to invoke
int currentMin = 0;
bool ambig = false;
int[] paramOrder = new int[indexesLength];
for (i=0;i<indexesLength;i++)
paramOrder[i] = i;
for (i=1;i<CurIdx;i++) {
int newMin = FindMostSpecificType(match[currentMin].PropertyType, match[i].PropertyType,returnType);
if (newMin == 0 && indexes != null)
newMin = FindMostSpecific(match[currentMin].GetIndexParameters(),
paramOrder,
null,
match[i].GetIndexParameters(),
paramOrder,
null,
indexes,
null);
if (newMin == 0)
{
newMin = FindMostSpecificProperty(match[currentMin], match[i]);
if (newMin == 0)
ambig = true;
}
if (newMin == 2) {
ambig = false;
currentMin = i;
}
}
if (ambig)
throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.Ambiguous"));
return match[currentMin];
}