static bool ParamArrayMatchs(object[] args, int index, Type dest, ArgumentConversions conversions) { var argConversions = new ArgumentConversions(args.Length - index); // check first parameter type matches for (int i = 0, current = index; current < args.Length; i++, current++) { var arg = args[current]; if (arg is null) { if (dest.IsValueType && !IsNullableType(dest)) { return(false); } } else { var src = arg.GetType(); if (!TypeUtils.AreReferenceAssignable(dest, src)) { if (TryImplicitConvert(src, dest, out MethodInfo opImplict) == false) { return(false); } argConversions.Add(new ParamConversion(i, opImplict)); } } } conversions.Add(new ParamArrayConversion(index, dest, argConversions)); return(true); }
public static bool MatchesArguments(this MethodBase method, object[] args, ArgumentConversions conversions) { var parameters = method.GetParameters(); // arg length var length = args.Length; // no arg int argCount = parameters.Length; if (argCount == 0 && length > 0) { return(false); } int i; for (i = 0; i < argCount; i++) { var param = parameters[i]; var dest = param.ParameterType; if (param.IsDefined(typeof(ParamArrayAttribute), false)) { // parameters is extra example print(string, params string[] args) and print('hello') // in this case 2 and 1 if (argCount > length) { conversions.Add(new ParamArrayConversion(i, dest.GetElementType())); return(true); } //No further check required if matchs return(ParamArrayMatchs(args, i, dest.GetElementType(), conversions)); } // matches current index if (i >= length) { // method has one more parameter so skip return(conversions.Recycle()); } var arg = args[i]; if (arg is null) { if (dest.IsValueType && !IsNullableType(dest)) { return(conversions.Recycle()); } } else { var src = arg.GetType(); if (!TypeUtils.AreReferenceAssignable(dest, src)) { if (TryImplicitConvert(src, dest, out MethodInfo opImplict) == false) { return(conversions.Recycle()); } conversions.Add(new ParamConversion(i, opImplict)); } } } if (i == length) { return(true); } return(conversions.Recycle()); }