Пример #1
0
        internal static object ComparisonValueFromExpression(this Expression expression, out Type type, out bool cachable)
        {
            type     = null;
            cachable = false;

            if (expression == null)
            {
                return(null);
            }

            switch (expression)
            {
            case LambdaExpression lambdaExpression:
                type = lambdaExpression.Parameters.FirstOrDefault()?.Type;
                break;

            case MemberExpression memberExpression:
                type = memberExpression.Member.DeclaringType;
                break;

            case MethodCallExpression methodCallExpression:
                // special case F# method call expressions on FuncConvert
                // that are used to convert F# quotations representing lambda expressions, to expressions.
                // https://github.com/dotnet/fsharp/blob/7adaacf150dd79f072efe42d43168c9cd6edbced/src/fsharp/FSharp.Core/Linq.fs#L796
                //
                // For example:
                //
                // type Doc = { Message: string; State: string }
                // let field (f:Expr<'a -> 'b>) =
                //     Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToExpression f
                //     |> Nest.Field.op_Implicit
                //
                // let fieldExpression = field <@ fun (d: Doc) -> d.Message @>
                //
                if (methodCallExpression.Method.DeclaringType.FullName == "Microsoft.FSharp.Core.FuncConvert" &&
                    methodCallExpression.Arguments.FirstOrDefault() is LambdaExpression lambda)
                {
                    type = lambda.Parameters.FirstOrDefault()?.Type;
                }
                else
                {
                    throw new Exception($"Unsupported {nameof(MethodCallExpression)}: {expression}");
                }
                break;

            default:
                throw new Exception(
                          $"Expected {nameof(LambdaExpression)}, {nameof(MemberExpression)} or "
                          + $"{nameof(MethodCallExpression)}, received: {expression.GetType().Name}");
            }

            var visitor  = new ToStringExpressionVisitor();
            var toString = visitor.Resolve(expression);

            cachable = visitor.Cachable;
            return(toString);
        }
Пример #2
0
        internal static object ComparisonValueFromExpression(this Expression expression, out Type type, out bool cachable)
        {
            type     = null;
            cachable = false;

            if (expression == null)
            {
                return(null);
            }

            if (!(expression is LambdaExpression lambda))
            {
                throw new Exception($"Not a lambda expression: {expression}");
            }

            type = lambda.Parameters.FirstOrDefault()?.Type;
            var visitor  = new ToStringExpressionVisitor();
            var toString = visitor.Resolve(expression);

            cachable = visitor.Cachable;
            return(toString);
        }