private MethodBase FindMatch(MethodBase[] methodCandidates, BindingFlags bindingAttr, Type[] types, ParameterModifier[] modifiers) { // Try the default binder first. Never gives false positive, but will fail to detect methods w/ parameter array because // it will not expand the formal parameter list when checking against actual parameters. var result = Type.DefaultBinder.SelectMethod(bindingAttr, methodCandidates, types, modifiers); // Could be false negative, check for parameter array and if so condense it back to an array before re-checking. if (result == null) { foreach (var method in methodCandidates) { var methodInfo = method as MethodInfo; var formalParams = methodInfo.GetParameters(); if (MethodResolver.HaveParameterArray(formalParams)) // Check if the last parameter of method is marked w/ "params" attribute { var elementType = formalParams[formalParams.Length - 1].ParameterType.GetElementType(); var allCompatible = true; // There could be more actual parameters than formal parameters, because the formal parameter is a params T'[] for some T'. // So, check that each actual parameter starting at position [formalParams.Length - 1] is compatible with T'. for (var i = formalParams.Length - 1; i < types.Length - 1; i++) { if (!TypeHelper.AreTypesCompatible(types[i], elementType)) { allCompatible = false; break; } } if (!allCompatible) { continue; } // Condense the actual parameter back to an array. var typeArray = new Type[formalParams.Length]; for (var i = 0; i < typeArray.Length - 1; i++) { typeArray[i] = types[i]; } typeArray[typeArray.Length - 1] = elementType.MakeArrayType(); // Recheck the condensed array var newFound = Type.DefaultBinder.SelectMethod(bindingAttr, new MethodBase[] { methodInfo }, typeArray, modifiers); if (result != null && newFound != null) { var type = newFound.ReflectedType.Name; var name = newFound.Name; var bindingType = bindingAttr == staticBindingFlags ? staticString : instanceString; throw FxTrace.Exception.AsError(new AmbiguousMatchException(SR.DuplicateMethodFound(type, bindingType, name, this.parentActivity.DisplayName))); } else { result = newFound; } } } } return(result); }
private MethodBase FindMatch(MethodBase[] methodCandidates, BindingFlags bindingAttr, Type[] types, ParameterModifier[] modifiers) { MethodBase base2 = Type.DefaultBinder.SelectMethod(bindingAttr, methodCandidates, types, modifiers); if (base2 == null) { foreach (MethodBase base3 in methodCandidates) { MethodInfo info = base3 as MethodInfo; ParameterInfo[] parameters = info.GetParameters(); if (MethodResolver.HaveParameterArray(parameters)) { Type elementType = parameters[parameters.Length - 1].ParameterType.GetElementType(); bool flag = true; for (int i = parameters.Length - 1; i < (types.Length - 1); i++) { if (!System.Runtime.TypeHelper.AreTypesCompatible(types[i], elementType)) { flag = false; break; } } if (flag) { Type[] typeArray = new Type[parameters.Length]; for (int j = 0; j < (typeArray.Length - 1); j++) { typeArray[j] = types[j]; } typeArray[typeArray.Length - 1] = elementType.MakeArrayType(); MethodBase base4 = Type.DefaultBinder.SelectMethod(bindingAttr, new MethodBase[] { info }, typeArray, modifiers); if ((base2 != null) && (base4 != null)) { string name = base4.ReflectedType.Name; string str2 = base4.Name; string str3 = (bindingAttr == MethodResolver.staticBindingFlags) ? MethodResolver.staticString : MethodResolver.instanceString; throw FxTrace.Exception.AsError(new AmbiguousMatchException(System.Activities.SR.DuplicateMethodFound(name, str3, str2, this.parentActivity.DisplayName))); } base2 = base4; } } } } return(base2); }