How to cast Expression> to Expression>

后端 未结 4 1805
借酒劲吻你
借酒劲吻你 2020-11-29 02:12

I\'ve been searching but I can\'t find how to cast from the type

Expression>

to the type:

Exp         


        
相关标签:
4条回答
  • 2020-11-29 02:38

    Based on the code from Jon (thanks btw) you can take it one step further for complete flexibility:

    public static Expression<Func<TModel, TToProperty>> Cast<TModel, TFromProperty, TToProperty>(Expression<Func<TModel, TFromProperty>> expression)
    {
        Expression converted = Expression.Convert(expression.Body, typeof(TToProperty));
    
        return Expression.Lambda<Func<TModel, TToProperty>>(converted, expression.Parameters);
    }
    
    0 讨论(0)
  • 2020-11-29 02:45

    You can't just cast between them, as they're not the same kind of thing. However, you can effectively add a conversion within the expression tree:

    using System;
    using System.Linq.Expressions;
    
    class Test
    {
        // This is the method you want, I think
        static Expression<Func<TInput,object>> AddBox<TInput, TOutput>
            (Expression<Func<TInput, TOutput>> expression)
        {
            // Add the boxing operation, but get a weakly typed expression
            Expression converted = Expression.Convert
                 (expression.Body, typeof(object));
            // Use Expression.Lambda to get back to strong typing
            return Expression.Lambda<Func<TInput,object>>
                 (converted, expression.Parameters);
        }
    
        // Just a simple demo
        static void Main()
        {
            Expression<Func<string, DateTime>> x = text => DateTime.Now;
            var y = AddBox(x);        
            object dt = y.Compile()("hi");
            Console.WriteLine(dt);
        }        
    }
    
    0 讨论(0)
  • 2020-11-29 02:51

    Just define the out TResult as object and compile the expression, it works for all data types;

    Expression<Func<string, object>> dateExp = text => DateTime.Now;
    object dt = dateExp.Compile()("hi");
    Console.WriteLine(dt);
    

    Fiddle sample here

    0 讨论(0)
  • 2020-11-29 03:01

    The answers from Rob and Jon Skeet have one problem.

    You get something like x => Convert(x.PropertyName), but often for instance for ASP.NET MVC you want an expression like this x => x.PropertyName

    So Expression.Convert is "polluting" the expression for some cases.

    Solution:

    public static class LambdaExpressionExtensions
    {
        public static Expression<Func<TInput, object>> ToUntypedPropertyExpression<TInput, TOutput> (this Expression<Func<TInput, TOutput>> expression)
        {
            var memberName = ((MemberExpression)expression.Body).Member.Name;
    
            var param = Expression.Parameter(typeof(TInput));
            var field = Expression.Property(param, memberName);
            return Expression.Lambda<Func<TInput, object>>(field, param);
        }
    }
    

    Usage:

    Expression<Func<T, DateTime>> expression = ...;
    Expression<Func<T, object>> expr = expression.ToUntypedPropertyExpression();
    
    0 讨论(0)
提交回复
热议问题