将Expression <Func >动态转换为Expression <Func

我找不到从Expression <Func >转换为Expression <Func >的方法。 因为我使用了大量的reflection,实际上,我真正需要的是一种采用类型参数并执行转换的方法。

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

T2来自T1

 public class T1 { int FamilyId {get; set;} } public class T2 : T1 { ... other properties } 

我在基类上定义了一个filter表达式

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

我想申请List

这是你在找什么? 该方法有两种forms:第一种允许您将新输入类型作为参数传递; 第二个允许您将输入类型作为generics参数传递,并获得强类型的LambdaExpression。

  public static LambdaExpression ChangeInputType(Expression> 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> ChangeInputType(Expression> 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>(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); } } 

你的要求是非常不明智的。 编译器如何知道T1是否可以转换为T2? 似乎即使有可能也要求可怕的运行时错误。*

(*我认为它不可能,因为你试图将refection与嵌套generics类型结合起来。)

看起来你想要组合2个表达式 – T2T1转换,而不是用给定的结果调用expr

这个问题讨论了一般结合两个表达式(Expression >) 。 对于您的情况,我认为您需要Expression.Call来构建转换表达式,而不是再次使用转换结果调用原始表达式。