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

+6
source share
3 answers

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); } } 
+9
source

What you ask is very unreasonable. How would the compiler ever know if T1 can be converted to T2? It seems like asking for terrible runtime errors, even if possible. *

(* I do not think this is possible because you are trying to combine reflection with nested generic types.)

0
source

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.

0
source

All Articles