예제 #1
0
        private static MethodRecognitionResult TryCallMethod(MethodInfo method, Type[] typeArguments, Expression[] positionalArguments, IDictionary <string, Expression> namedArguments)
        {
            var parameters = method.GetParameters();

            int castCount = 0;

            if (parameters.Length < positionalArguments.Length)
            {
                return(null);
            }
            var args = new Expression[parameters.Length];

            Array.Copy(positionalArguments, args, positionalArguments.Length);
            int namedArgCount = 0;

            for (int i = positionalArguments.Length; i < args.Length; i++)
            {
                if (namedArguments?.ContainsKey(parameters[i].Name) == true)
                {
                    args[i] = namedArguments[parameters[i].Name];
                    namedArgCount++;
                }
                else if (parameters[i].HasDefaultValue)
                {
                    castCount++;
                    args[i] = Expression.Constant(parameters[i].DefaultValue, parameters[i].ParameterType);
                }
                else
                {
                    return(null);
                }
            }

            // some named arguments were not used
            if (namedArguments != null && namedArgCount != namedArguments.Count)
            {
                return(null);
            }

            int automaticTypeArgs = 0;

            // resolve generic parameters
            if (method.ContainsGenericParameters)
            {
                var typeArgs = new Type[method.GetGenericArguments().Length];
                if (typeArguments != null)
                {
                    if (typeArguments.Length > typeArgs.Length)
                    {
                        return(null);
                    }
                    Array.Copy(typeArguments, typeArgs, typeArgs.Length);
                }
                for (int i = 0; i < typeArgs.Length; i++)
                {
                    if (typeArgs[i] == null)
                    {
                        // try to resolve from arguments
                        var arg = Array.FindIndex(parameters, p => p.ParameterType.IsGenericParameter && p.ParameterType.GenericParameterPosition == i);
                        automaticTypeArgs++;
                        if (arg >= 0)
                        {
                            typeArgs[i] = args[arg].Type;
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                method     = method.MakeGenericMethod(typeArgs);
                parameters = method.GetParameters();
            }
            else if (typeArguments != null)
            {
                return(null);
            }

            // cast arguments
            for (int i = 0; i < args.Length; i++)
            {
                var casted = TypeConversion.ImplicitConversion(args[i], parameters[i].ParameterType);
                if (casted == null)
                {
                    return(null);
                }
                if (casted != args[i])
                {
                    castCount++;
                    args[i] = casted;
                }
            }

            return(new MethodRecognitionResult
            {
                CastCount = castCount,
                AutomaticTypeArgCount = automaticTypeArgs,
                Method = method,
                Arguments = args
            });
        }
 public CastedExpressionBindingProperty ConvertExpressionToType(ParsedExpressionBindingProperty expr, ExpectedTypeBindingProperty expectedType = null) =>
 new CastedExpressionBindingProperty(TypeConversion.ImplicitConversion(expr.Expression, expectedType?.Type ?? typeof(object), throwException: true, allowToString: true));