internal static MethodInformation FindBestMethod( string methodName, MethodInformation[] methods, object[] arguments, out bool expandParamsOnBest) { if (methods.Length == 1 && !methods[0].hasVarArgs && methods[0].parameters.Length == arguments.Length) { expandParamsOnBest = false; return(methods[0]); } List <Adapter.OverloadCandidate> candidates = new List <Adapter.OverloadCandidate>(); for (int index1 = 0; index1 < methods.Length; ++index1) { MethodInformation method = methods[index1]; if (!method.isGeneric) { ParameterInformation[] parameters = method.parameters; if (arguments.Length != parameters.Length) { if (arguments.Length > parameters.Length) { if (!method.hasVarArgs) { continue; } } else if (method.hasOptional || method.hasVarArgs && arguments.Length + 1 == parameters.Length) { if (method.hasOptional) { int num = 0; for (int index2 = 0; index2 < parameters.Length; ++index2) { if (parameters[index2].isOptional) { ++num; } } if (arguments.Length + num < parameters.Length) { continue; } } } else { continue; } } Adapter.OverloadCandidate overloadCandidate = new Adapter.OverloadCandidate(method, arguments.Length); for (int index2 = 0; overloadCandidate != null && index2 < parameters.Length; ++index2) { ParameterInformation parameterInformation = parameters[index2]; if (!parameterInformation.isOptional || arguments.Length > index2) { if (parameterInformation.isParamArray) { Type elementType = parameterInformation.parameterType.GetElementType(); if (parameters.Length == arguments.Length) { ConversionRank argumentConversionRank1 = Adapter.GetArgumentConversionRank(arguments[index2], parameterInformation.parameterType); ConversionRank argumentConversionRank2 = Adapter.GetArgumentConversionRank(arguments[index2], elementType); if (argumentConversionRank2 > argumentConversionRank1) { overloadCandidate.expandedParameters = Adapter.ExpandParameters(arguments.Length, parameters, elementType); overloadCandidate.conversionRanks[index2] = argumentConversionRank2; } else { overloadCandidate.conversionRanks[index2] = argumentConversionRank1; } if (overloadCandidate.conversionRanks[index2] == ConversionRank.None) { overloadCandidate = (Adapter.OverloadCandidate)null; } } else { for (int index3 = index2; index3 < arguments.Length; ++index3) { overloadCandidate.conversionRanks[index3] = Adapter.GetArgumentConversionRank(arguments[index3], elementType); if (overloadCandidate.conversionRanks[index3] == ConversionRank.None) { overloadCandidate = (Adapter.OverloadCandidate)null; break; } } if (overloadCandidate != null) { overloadCandidate.expandedParameters = Adapter.ExpandParameters(arguments.Length, parameters, elementType); } } } else { overloadCandidate.conversionRanks[index2] = Adapter.GetArgumentConversionRank(arguments[index2], parameterInformation.parameterType); if (overloadCandidate.conversionRanks[index2] == ConversionRank.None) { overloadCandidate = (Adapter.OverloadCandidate)null; } } } else { break; } } if (overloadCandidate != null) { candidates.Add(overloadCandidate); } } } if (candidates.Count == 0) { throw new MethodException("MethodCountCouldNotFindBest", (Exception)null, "ExtendedTypeSystem", "MethodArgumentCountException", new object[2] { (object)methodName, (object)arguments.Length }); } Adapter.OverloadCandidate overloadCandidate1 = candidates.Count != 1 ? Adapter.FindBestCandidate(candidates, arguments) : candidates[0]; if (overloadCandidate1 != null) { expandParamsOnBest = overloadCandidate1.expandedParameters != null; return(overloadCandidate1.method); } throw new MethodException("MethodCountCouldNotFindBest", (Exception)null, "ExtendedTypeSystem", "MethodAmbiguousException", new object[2] { (object)methodName, (object)arguments.Length }); }
private static int CompareMethods( Adapter.OverloadCandidate candidate1, Adapter.OverloadCandidate candidate2, object[] arguments) { ParameterInformation[] parameterInformationArray1 = candidate1.expandedParameters != null ? candidate1.expandedParameters : candidate1.parameters; ParameterInformation[] parameterInformationArray2 = candidate2.expandedParameters != null ? candidate2.expandedParameters : candidate2.parameters; int num1 = 0; int length = parameterInformationArray1.Length; int index1 = 0; while (index1 < parameterInformationArray1.Length) { if (candidate1.conversionRanks[index1] < candidate2.conversionRanks[index1]) { num1 -= length; } else if (candidate1.conversionRanks[index1] > candidate2.conversionRanks[index1]) { num1 += length; } else if (candidate1.conversionRanks[index1] == ConversionRank.UnrelatedArrays) { Type elementType = Adapter.EffectiveArgumentType(arguments[index1]).GetElementType(); ConversionRank conversionRank1 = LanguagePrimitives.GetConversionRank(elementType, parameterInformationArray1[index1].parameterType.GetElementType()); ConversionRank conversionRank2 = LanguagePrimitives.GetConversionRank(elementType, parameterInformationArray2[index1].parameterType.GetElementType()); if (conversionRank1 < conversionRank2) { num1 -= length; } else if (conversionRank1 > conversionRank2) { num1 += length; } } ++index1; --length; } if (num1 == 0) { int num2 = parameterInformationArray1.Length; int index2 = 0; while (index2 < parameterInformationArray1.Length) { ConversionRank conversionRank1 = candidate1.conversionRanks[index2]; ConversionRank conversionRank2 = candidate2.conversionRanks[index2]; if (conversionRank1 >= ConversionRank.NullToValue && conversionRank2 >= ConversionRank.NullToValue && conversionRank1 >= ConversionRank.NumericImplicit == conversionRank2 >= ConversionRank.NumericImplicit) { if (conversionRank1 >= ConversionRank.NumericImplicit) { num2 = -num2; } ConversionRank conversionRank3 = LanguagePrimitives.GetConversionRank(parameterInformationArray1[index2].parameterType, parameterInformationArray2[index2].parameterType); ConversionRank conversionRank4 = LanguagePrimitives.GetConversionRank(parameterInformationArray2[index2].parameterType, parameterInformationArray1[index2].parameterType); if (conversionRank3 < conversionRank4) { num1 += num2; } else if (conversionRank3 > conversionRank4) { num1 -= num2; } } ++index2; num2 = Math.Abs(num2) - 1; } } if (num1 != 0) { return(num1); } for (int index2 = 0; index2 < parameterInformationArray1.Length; ++index2) { if (!parameterInformationArray1[index2].parameterType.Equals(parameterInformationArray2[index2].parameterType)) { return(0); } } if (candidate1.expandedParameters != null && candidate2.expandedParameters != null) { return(candidate1.parameters.Length <= candidate2.parameters.Length ? -1 : 1); } if (candidate1.expandedParameters != null) { return(-1); } return(candidate2.expandedParameters == null ? 0 : 1); }