public static Expression GetParamsMatch(Type type, Expression instance, string membername, List <Expression> args) { // assume params var methodInfos = type.GetMethods().Where(x => x.Name == membername); var matchScore = new List <Tuple <MethodInfo, int> >(); foreach (var info in methodInfos.OrderByDescending(m => m.GetParameters().Count())) { var parameterInfos = info.GetParameters(); var lastParam = parameterInfos.Last(); var newArgs = args.Take(parameterInfos.Length - 1).ToList(); var paramArgs = args.Skip(parameterInfos.Length - 1).ToList(); int i = 0; int k = 0; foreach (var expression in newArgs) { k += TypeConversion.CanConvert(expression.Type, parameterInfos[i].ParameterType); i++; } if (k > 0) { if (Attribute.IsDefined(lastParam, typeof(ParamArrayAttribute))) { k += paramArgs.Sum(arg => TypeConversion.CanConvert(arg.Type, lastParam.ParameterType.GetElementType())); } } matchScore.Add(new Tuple <MethodInfo, int>(info, k)); } var info2 = matchScore.OrderBy(x => x.Item2).FirstOrDefault(x => x.Item2 >= 0); if (info2 != null) { var parameterInfos2 = info2.Item1.GetParameters(); var lastParam2 = parameterInfos2.Last(); var newArgs2 = args.Take(parameterInfos2.Length - 1).ToList(); var paramArgs2 = args.Skip(parameterInfos2.Length - 1).ToList(); for (int i = 0; i < parameterInfos2.Length - 1; i++) { newArgs2[i] = TypeConversion.Convert(newArgs2[i], parameterInfos2[i].ParameterType); } var targetType = lastParam2.ParameterType.GetElementType(); newArgs2.Add(Expression.NewArrayInit(targetType, paramArgs2.Select(x => TypeConversion.Convert(x, targetType)))); return(Expression.Call(instance, info2.Item1, newArgs2)); } return(null); }