Convert Expression> to Expression dynamically

前端 未结 3 1768
野的像风
野的像风 2020-12-30 12:48

I cannot find the way to convert from Expression> to Expression>. Since Im using a lot of reflection, in fact, what I rea

相关标签:
3条回答
  • 2020-12-30 13:26

    What your asking for is very unwise. How would the compiler ever know if T1 is can be converted to T2? Seems like asking for awful run-time errors even if it is possible.*

    (*I don't think its possible since you are trying to combine refection with nested generic types.)

    0 讨论(0)
  • 2020-12-30 13:38

    It looks like you want to combine 2 expressions - T2 to T1 conversion and than call to expr with given result.

    This question discusses Combining two expressions (Expression<Func<T, bool>>) in general. For your case I think you need Expression.Call to construct conversion expression and than again to call original expression with result of conversion.

    0 讨论(0)
  • 2020-12-30 13:42

    Is this what you're looking for? There are two flavors of the method: the first lets you pass in the new input type as an argument; the second lets you pass in the input type as a generic parameter and get a strongly typed LambdaExpression.

        public static LambdaExpression ChangeInputType<T, TResult>(Expression<Func<T, TResult>> expression, Type newInputType)
        {
            if (!typeof(T).IsAssignableFrom(newInputType))
                throw new Exception(string.Format("{0} is not assignable from {1}.", typeof(T), newInputType));
            var beforeParameter = expression.Parameters.Single();
            var afterParameter = Expression.Parameter(newInputType, beforeParameter.Name);
            var visitor = new SubstitutionExpressionVisitor(beforeParameter, afterParameter);
            return Expression.Lambda(visitor.Visit(expression.Body), afterParameter);
        }
    
        public static Expression<Func<T2, TResult>> ChangeInputType<T1, T2, TResult>(Expression<Func<T1, TResult>> expression)
        {
            if (!typeof(T1).IsAssignableFrom(typeof(T2)))
                throw new Exception(string.Format("{0} is not assignable from {1}.", typeof(T1), typeof(T2)));
            var beforeParameter = expression.Parameters.Single();
            var afterParameter = Expression.Parameter(typeof(T2), beforeParameter.Name);
            var visitor = new SubstitutionExpressionVisitor(beforeParameter, afterParameter);
            return Expression.Lambda<Func<T2, TResult>>(visitor.Visit(expression.Body), afterParameter);
        }
    
        public class SubstitutionExpressionVisitor : ExpressionVisitor
        {
            private Expression before, after;
            public SubstitutionExpressionVisitor(Expression before, Expression after)
            {
                this.before = before;
                this.after = after;
            }
            public override Expression Visit(Expression node)
            {
                return node == before ? after : base.Visit(node);
            }
        }
    
    0 讨论(0)
提交回复
热议问题