本文介绍了转换表达式< Func< T1,bool>>.表达式< Func< T2,布尔>动态地的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到从Expression< Func< T1,bool>>转换的方法.表达式< Func< T2,bool>.实际上,由于Im进行了大量的反射,所以我真正需要的是一种使用类型参数并执行转换的方法.

public object Convert(Expression<Func<T1,bool>> expr, Type t);

T2源自T1

public class T1 {
     int FamilyId {get; set;}
}

public class T2 : T1 {
     ... other properties
}

我正在基类上定义一个过滤器表达式

Expression<Func<T1,bool>> filter = p => p.FamilyId == [some value]

我要应用于列表< T2>

解决方案

这是您要找的东西吗?该方法有两种形式:第一种使您可以将新的输入类型作为参数传递;第二种方法使您可以将新的输入类型作为参数传递.第二种方法使您可以将输入类型作为通用参数传递,并获得强类型的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);
        }
    }

I cannot find the way to convert from Expression<Func<T1,bool>> to Expression<Func<T2,bool>>. Since Im using a lot of reflection, in fact, what I really need is a method which takes a type parameter and performs the conversion.

public object Convert(Expression<Func<T1,bool>> expr, Type t);

T2 is derived from T1

public class T1 {
     int FamilyId {get; set;}
}

public class T2 : T1 {
     ... other properties
}

I am defining a filter expression on the base class

Expression<Func<T1,bool>> filter = p => p.FamilyId == [some value]

that i want to apply to a List<T2>

解决方案

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);
        }
    }

这篇关于转换表达式&lt; Func&lt; T1,bool&gt;&gt;.表达式&lt; Func&lt; T2,布尔&gt;动态地的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 09:42