2013-03-04 116 views
6

我無法找到從表達式< Func鍵< T1轉換的方式,布爾> >表達式< Func鍵< T2,布爾> >。由於我使用了大量的反射,實際上,我真正需要的是一種採用類型參數並執行轉換的方法。轉換表達<Func鍵<T1,bool>>表達式<Func鍵<T2,bool>動態

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限定過濾器表達式衍生>

+0

'我真正需要的是一種採用類型參數並執行轉換的方法。「 - 什麼? bool是什麼?你需要轉換方法嗎?還是有條件的?我不明白 – 2013-03-04 22:59:43

+1

'T1'和'T2'如何相關?有甚至有辦法在它們之間進行轉換嗎? – cdhowie 2013-03-04 23:00:16

+0

T2源自T1。 – Hernan 2013-03-04 23:10:47

回答

9

這是你在找什麼?這個方法有兩種風格:第一種可以讓你傳入新的輸入類型作爲參數;第二種方法允許您將輸入類型作爲泛型參數傳遞,並獲得強類型的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); 
     } 
    } 
+2

優秀!正是我所期待的。謝謝!!!! – Hernan 2013-03-05 04:38:35

+0

當T2不從T1繼承時,可能會做出類似表達式嗎? – 2018-02-26 16:01:16

0

你要求的是非常不明智的。編譯器如何知道T1是否可以轉換爲T2?好像要求可怕的運行時錯誤,即使它是可能的。*

(*我不因爲你想恢復體力與嵌套泛型類型組合認爲其可能的。)

+0

T2源自T1 – Hernan 2013-03-04 23:09:35

相關問題