Beispiel #1
0
        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);
        }