2010-10-20 70 views
2

我只是在學習表達式樹的早期過程中。用BinaryExpression解析表達式和

據我瞭解,有關它們的好處是,他們可以當它們被用作參數進行解析,所以例如:

Foo.Bar(x => x.Process == "On" && x.Name == "Goofy") 

但我怎麼能解析表達式時,也確實是內?

也許我誤解了這一切,但後來我看不到使用表達式的原因?我現在已經瀏覽了將近數百個網站,他們都試圖解釋表達式樹是什麼,他們都成功了,希望他們從來沒有解釋過用法是什麼 - 除了簡單的解釋「表達式樹沒有編譯....」

回答

0

我已經使用表達式來構建一個微不足道的域特定語言。這在我工作的實際應用中使用,所以它不是玩具項目。

我基本上創建了一個流暢的界面,可以讓我建立Predicate<T>代表,是這樣的:

Predicate<MyClass> condition = (new ConditionBuilder()).GreaterThanConst(9) 
                 .And() 
                 .LessThanConst(4) 
                 .ToPredicate(); 

每個方法都增加了相關表達到當前的樹。比ToPredicate編譯表達式到委託。

GreaterThanConst方法看起來是這樣的:(?成長)

public ConditionBuilder GreaterThan(object constant) 
{ 
    condition = Expression.GreaterThan(Expression.Parameter(constant.GetType()), Expression.Constant(constant)); 
    return this; 
} 

哪裏condition是持有多數民衆贊成在建的樹中的成員。

要分析你的表情,你需要寫類似:

Expression<Func<YourClass, bool>> expr = x => x.Process == "On" && x.Name == "Goofy"; 

那麼你可以看看,雖然已生成並看看有什麼有表達式樹。

+0

感謝你爲這個......嗯,是的,我沒有想象像擴展 公共靜態布爾吧(這個富富,表達>表達式) { ... } 然後查看錶達式樹,計算false或true,然後返回。 我在正確的軌道上嗎? – Janus007 2010-10-20 23:13:27

+0

我不知道爲什麼你需要一個表達式樹。如果你打算做的只是返回結果,那麼傳遞它自己的'Func'會更有意義。 – 2010-10-21 08:31:51

+0

我受到以下啓發: \t NServiceBus.Configure.With()。Log4Net(a => a。YourProperty =「value」); 設置這樣的屬性:) – Janus007 2010-10-21 08:49:24

1

表達式以樹的形式表示代碼。樹的每個節點代表代碼的一部分。例如,樹在你的問題lambda表達式的身體是類似的東西:

BinaryExpression (AndAlso) 
    .Left = BinaryExpression (Equal) 
    .Left = MemberExpression (x.Process) 
     .Expression = ParameterExpression (x) 
     .Member = MemberInfo (Process) 
    .Right = ConstantExpression ("On") 
    .Right = BinaryExpression (Equal) 
    .Left = MemberExpression (x.Name) 
     .Expression = ParameterExpression (x) 
     .Member = MemberInfo (Name) 
    .Right = ConstantExpression ("Goofy") 

通常情況下,用式的代碼不被執行,甚至沒有編譯:它進行分析,提取一些來自它的信息,將其轉換爲另一個表達式,甚至生成完全不同的東西(例如Linq to SQL或Entity Framework中的SQL查詢)。這對於編譯代碼來說是不可能的,因爲無法分析它(至少不容易)。

+0

謝謝你澄清這一點,這正是我所希望的:)它確實回答了我的最後一個問題。 – Janus007 2010-10-20 23:00:29