2015-08-14 18 views
1

我有這樣的表達式:Expression<Func<TheObject, int, bool>> myExpression = (myObj, theType) => { myObj.Prop > theType };重建表達

我需要動態重建myExpression到Expression<Func<TheObject, bool>>類型的新的表達和替換「theType」參數從所述第一表達與像一個具體值123:

Expression<Func<TheObject, bool>> myNewExpression = myObj => { myObj.Prop > 123 }; 

我該怎麼做? 溴 菲利普

+0

什麼,你的「動態」的意思是?在運行時? – netaholic

+0

你沒有'E​​xpression's那裏...刪除'{'和'}',**然後**你將有'Expression's(見http://goo.gl/Sl86ie) – xanatos

+0

我有一個方法,第一個表達式作爲參數,整數值作爲委託,這應該返回新的表達式,如:'表達式> RebuildExpression(表達式 > myExpression,Func theInt)' – Philip

回答

1

用一個簡單的表達代用品這是很容易:

這是我爲我自己寫的一個...支持簡單的替換並多內容替換。

using System; 
using System.Collections.Generic; 
using System.Linq.Expressions; 

// A simple expression visitor to replace some nodes of an expression 
// with some other nodes. Can be used with anything, not only with 
// ParameterExpression 
public class SimpleExpressionReplacer : ExpressionVisitor 
{ 
    public readonly Dictionary<Expression, Expression> Replaces; 

    public SimpleExpressionReplacer(Expression from, Expression to) 
    { 
     Replaces = new Dictionary<Expression, Expression> { { from, to } }; 
    } 

    public SimpleExpressionReplacer(Dictionary<Expression, Expression> replaces) 
    { 
     // Note that we should really clone from and to... But we will 
     // ignore this! 
     Replaces = replaces; 
    } 

    public SimpleExpressionReplacer(IEnumerable<Expression> from, IEnumerable<Expression> to) 
    { 
     Replaces = new Dictionary<Expression, Expression>(); 

     using (var enu1 = from.GetEnumerator()) 
     using (var enu2 = to.GetEnumerator()) 
     { 
      while (true) 
      { 
       bool res1 = enu1.MoveNext(); 
       bool res2 = enu2.MoveNext(); 

       if (!res1 || !res2) 
       { 
        if (!res1 && !res2) 
        { 
         break; 
        } 

        if (!res1) 
        { 
         throw new ArgumentException("from shorter"); 
        } 

        throw new ArgumentException("to shorter"); 
       } 

       Replaces.Add(enu1.Current, enu2.Current); 
      } 
     } 
    } 

    public override Expression Visit(Expression node) 
    { 
     Expression to; 

     if (node != null && Replaces.TryGetValue(node, out to)) 
     { 
      return base.Visit(to); 
     } 

     return base.Visit(node); 
    } 
} 

你TheObject

public class TheObject 
{ 
    public int Prop { get; set; } 
} 

然後你只需要更換的第二個參數的表達式的主體和重建Expression<>

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     Expression<Func<TheObject, int, bool>> myExpression = (myObj, theType) => myObj.Prop > theType; 

     int value = 123; 

     var body = myExpression.Body; 

     var body2 = new SimpleExpressionReplacer(myExpression.Parameters[1], Expression.Constant(value)).Visit(body); 

     Expression<Func<TheObject, bool>> myExpression2 = Expression.Lambda<Func<TheObject, bool>>(body2, myExpression.Parameters[0]); 
    } 
} 
+0

太好了,謝謝!完美的作品! – Philip

+0

'SimpleExpressionReplacer'是寫得很好的課程! –