protected override bool Convert(MethodBase method, object[] args, out object[] convertedArgs) { convertedArgs = new object[method.DeclareParamCount()]; //Note:if there is args omit(opt/var), use default value or empty array to adjust the number of args. if (args.Length >= convertedArgs.Length) { if (method.IsVarArgs())//Note:Pass in args is more than declare, try convert and build vararg array. { if (!TryConvertArgumentArray(method, args, convertedArgs, convertedArgs.Length - 1)) return false; return TryBuildVarArgArray(method, args, convertedArgs); } else if (args.Length == convertedArgs.Length)//Note:if equal, it might be exact match. return TryConvertArgumentArray(method, args, convertedArgs, args.Length); } else//Note:Check with optarg/vararg, both is possible { if (method.IsOptArg(args.Length) || method.IsVarArgs()) { if (!TryConvertArgumentArray(method, args, convertedArgs, args.Length)) return false; if (method.IsVarArgs()) { RetrieveOptArgDefault(method, convertedArgs, args.Length, method.DeclareParamCount() - args.Length - 1); return TryBuildVarArgArray(method, args, convertedArgs); } else { RetrieveOptArgDefault(method, convertedArgs, args.Length, method.DeclareParamCount() - args.Length); return true; } } } return false; }
private void FindBetterCandidate(object[] args, MethodBase mi, object[] converted_args) { if (_candidate.IsVarArgs() && mi.IsVarArgs()) { //Note: if both candidate and current method isVarArgs, choose the one has more parameter if (_candidate.DeclareParamCount() < mi.DeclareParamCount()) SaveCurrentFound(mi, converted_args); } else if (!_candidate.IsVarArgs() && !mi.IsVarArgs()) { //Note:if both not VarArgs, choose exact match one, otherwise is ambiguous call // (in case both can fit with opt param, it's ambiguous call). if (_candidate.DeclareParamCount() == args.Length) { //Note:Saved candidate is better, nothing to do. } else if (mi.DeclareParamCount() == args.Length) SaveCurrentFound(mi, converted_args); else ThrowHelper.ThrowAmbiguousMethod(_r.BoundType, mi.Name); } else if (_candidate.IsVarArgs() && !mi.IsVarArgs())//Note:Prefer NonVarArgs method SaveCurrentFound(mi, converted_args); //Note:else if (!_candidate.IsVarArgs() && mi.IsVarArgs()) Prefer NonVarArgs method, candidate is better, do nothing }