2011-10-18 16 views
4

產品下面的片段都是相同的輸出。 我明白Func如何用單個參數封裝一個方法,並返回一個布爾值。你可以爲它分配一個 方法,匿名方法或lambda表達式。試圖瞭解表達式樹是什麼

Func<int, bool> deleg = i => i < 5; 
Console.WriteLine("deleg(4) = {0}", deleg(4)); 

下面是使用表達式樹,我還沒有完全理解。我爲什麼要這樣做?它更靈活嗎,它給我什麼優勢?

System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5; 
Func<int, bool> deleg2 = expr.Compile(); 
Console.WriteLine("deleg2(4) = {0}", deleg2(4)); 

回答

5

基本上,表達式樹是一個lambda表達式的主體,它允許你

  • 反思的表達(見什麼在它這麼說)
  • 操縱表達(簡化,擴展(例如添加新功能或修改以處理不同項目)

一旦您Compile()的表達,它是只是另一個代表,你只能調用,不檢查或修改。

每當你想

  • 創建動態表達(我的意思是:構建,不分配)
  • 上表達操作動態

Function<>類型是不夠的。

1

表達式樹的要點是你可以用它們做更多的事情,而不僅僅是將它們編譯成函數。您可以檢查它們,修改它們並將它們編譯爲.net函數以外的其他內容。

例如,Linq2SQL將表達式樹編譯爲SQL代碼。你不能用普通的.net函數來做到這一點。

+0

你如何檢查他們?這個過程叫什麼?例子? – codecompleting

+0

@codecompleting:使用[Expression類](http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx)及其[子類](http: //msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx#inheritanceContinued)。例如,您可以在[本文](http://marlongrech.wordpress.com/2008/01/08/working-with-expression-trees-part-1/)中看到一個小例子。 – sepp2k

1

在您的第一個示例中,您只需對函數的主體進行「硬編碼」並將其分配給委託。

在第二個例子中,賦值構造了一個表達式樹,它是一個對象模型,用於在內存中的數據結構中重新表示代碼。

優點是您可以修改和檢查數據結構。

例如,LINQ2SQL使用該技術將您的表達式轉換爲另一種稱爲SQL的語言。

0

表達式樹是可以通過編程遍歷的常規內存數據結構,並且此類遍歷的結果可以是某些內容,例如您希望發送到數據庫的查詢。詳細瞭解ExpressionVisitor課程,瞭解它是如何完成的。

另一方面,編譯的函數只不過是一串CIL代碼。你仍然可以通過編程來檢查它,但是你並沒有檢查定義,而是 - 它的編譯器輸出。