Convert expression <Func <T1, bool >> to expression <Func <T2, bool> dynamically
I canβt find a way to convert from Expression <Func <T1, bool β> to the expression <Func <T2, bool>. Since I use a lot of reflection, I actually really need a method that takes a type parameter and does the conversion.
public object Convert(Expression<Func<T1,bool>> expr, Type t); T2 is obtained from T1
public class T1 { int FamilyId {get; set;} } public class T2 : T1 { ... other properties } I define a filter expression in the base class
Expression<Func<T1,bool>> filter = p => p.FamilyId == [some value] which I want to apply to the <T2> list
Is this what you are looking for? There are two variants of the method: the first allows you to pass a new input type as an argument; the second allows you to pass an input type as a generic parameter and get a strongly typed LambdaExpression expression.
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); } } It looks like you want to combine 2 expressions - T2 to T1 conversion and call to expr with the given result.
This question discusses the union of two expressions (Expression <Func <T, bool β) as a whole. For your case, I think you need Expression.Call to create a transform expression and call the original expression again with the result of the transform.