32 public override MethodBase
SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
35 foreach (var method
in match)
36 if (MatchParameterTypes(method.GetParameters(), types))
37 match[matchCount++] = method;
42 var bestMatch = match[0];
43 var ambiguous =
false;
44 for (
int i = 1; i < matchCount; i++)
45 SelectBestMatch(match[i], types,
ref bestMatch,
ref ambiguous);
48 throw new AmbiguousMatchException();
53 static bool MatchParameterTypes(ParameterInfo[] parameters, Type[] types)
55 if (parameters.Length != types.Length)
58 for (
int i = 0; i < parameters.Length; i++)
60 var sourceType = types[i];
61 var targetType = parameters[i].ParameterType;
62 if (sourceType != targetType
63 && !targetType.IsAssignableFrom(sourceType)
64 && !IsAllowedPrimitiveConversion(sourceType, targetType))
73 switch (MatchSignatures(currentBest, candidate, types))
79 currentBest = candidate;
83 if (currentBest.MethodSignature.MatchParameterTypes(candidate.MethodSignature))
85 int depth1 = GetInheritanceDepth(currentBest.DeclaringType);
86 int depth2 = GetInheritanceDepth(candidate.DeclaringType);
91 else if (depth1 < depth2)
94 currentBest = candidate;
102 static int GetInheritanceDepth(
Type type)
108 type = type.BaseType;
115 var sig1 = mb1.MethodSignature;
116 var sig2 = mb2.MethodSignature;
117 var gb1 = mb1 as IGenericBinder ?? mb1.DeclaringType;
118 var gb2 = mb2 as IGenericBinder ?? mb2.DeclaringType;
119 for (
int i = 0; i < sig1.GetParameterCount(); i++)
121 var type1 = sig1.GetParameterType(gb1, i);
122 var type2 = sig2.GetParameterType(gb2, i);
124 return MatchTypes(type1, type2, types[i]);
130 static int MatchSignatures(PropertySignature sig1, PropertySignature sig2,
Type[] types)
132 for (
int i = 0; i < sig1.ParameterCount; i++)
134 var type1 = sig1.GetParameter(i);
135 var type2 = sig2.GetParameter(i);
137 return MatchTypes(type1, type2, types[i]);
143 static int MatchTypes(
Type type1,
Type type2,
Type type)
150 var conv = type1.IsAssignableFrom(type2);
151 return conv == type2.IsAssignableFrom(type1) ? 0 : conv ? 2 : 1;
154 static bool IsAllowedPrimitiveConversion(
Type source,
Type target)
157 if (!source.IsPrimitive || !target.IsPrimitive)
160 var sourceType =
Type.GetTypeCode(source);
161 var targetType =
Type.GetTypeCode(target);
167 case TypeCode.UInt16:
168 case TypeCode.UInt32:
170 case TypeCode.UInt64:
172 case TypeCode.Single:
173 case TypeCode.Double:
182 case TypeCode.UInt16:
184 case TypeCode.UInt32:
186 case TypeCode.UInt64:
188 case TypeCode.Single:
189 case TypeCode.Double:
200 case TypeCode.Single:
201 case TypeCode.Double:
206 case TypeCode.UInt16:
209 case TypeCode.UInt32:
211 case TypeCode.UInt64:
213 case TypeCode.Single:
214 case TypeCode.Double:
224 case TypeCode.Single:
225 case TypeCode.Double:
230 case TypeCode.UInt32:
233 case TypeCode.UInt64:
235 case TypeCode.Single:
236 case TypeCode.Double:
245 case TypeCode.Single:
246 case TypeCode.Double:
251 case TypeCode.UInt64:
254 case TypeCode.Single:
255 case TypeCode.Double:
263 case TypeCode.Single:
264 case TypeCode.Double:
269 case TypeCode.Single:
272 case TypeCode.Double:
282 public override PropertyInfo
SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers)
286 foreach (var property
in match)
288 if (indexes ==
null || MatchParameterTypes(property.GetIndexParameters(), indexes))
290 if (returnType !=
null)
292 if (property.PropertyType.IsPrimitive)
294 if (!IsAllowedPrimitiveConversion(returnType, property.PropertyType))
299 if (!property.PropertyType.IsAssignableFrom(returnType))
304 match[matchCount++] = property;
314 var bestMatch = match[0];
315 var ambiguous =
false;
316 for (
int i = 1; i < matchCount; i++)
318 var best = MatchTypes(bestMatch.PropertyType, match[i].PropertyType, returnType);
320 if (best == 0 && indexes !=
null)
321 best = MatchSignatures(bestMatch.PropertySignature, match[i].PropertySignature, indexes);
325 var depth1 = GetInheritanceDepth(bestMatch.DeclaringType);
326 var depth2 = GetInheritanceDepth(match[i].DeclaringType);
327 if (bestMatch.Name == match[i].Name && depth1 != depth2)
343 bestMatch = match[i];
348 throw new AmbiguousMatchException();