2009-10-07 23 views
16

這一個靈感來自於我的語言專家同事,他似乎無法爲他們找到很好的用處,經過我自己的一些蹩腳嘗試,我不得不同意。什麼是.net 4.0表達式樹的一個很好的用例?

現在我知道這些概念往往一旦你得到一些很好的實際原因下更容易流很多。

目前,它好像它唯一的目的就是讓你寫一個LINQ提供程序?

是嗎?這是否還有其他好處?

+3

http://stackoverflow.com/questions/403088/practical-use-of-expression-trees – 2009-10-07 16:35:51

回答

15

的表達式樹是如此強大,因爲他們讓你把代碼數據。用戶習慣於構建數據,保存並稍後再回來。

表達式樹讓你用代碼做同樣的事情。例如,您可以將用戶的輸入(複選框,數字範圍等)轉換爲表達式樹。然後可以執行該表達式樹,或將其存儲以供以後使用。很酷。

覺得這一報告的實際應用,就像建立和保存數據的過濾器和數據映射。另一個實際用途是根據用戶定義的規則來支持應用程序中的自定義工作流程。

下面是關於序列化表達式樹(http://code.msdn.microsoft.com/exprserialization)的一些MSDN代碼,這些代碼樹應該能夠讓創意流動起來。

+0

酷!這是一個符合我特定思維的答案。很好的例子! 我現在看到如何在框架的其他部分使用它。那麼這在WPF中用了很多? – KevinDeus 2009-10-07 17:52:35

+0

謝謝。很高興這有幫助。我曾經想過(可能太多)關於WPF以及像lambda表達式和表達式樹這樣瘋狂的有用函數式編程概念會成爲核心。問題是WPF與.NET 3.0一起發佈,LINQ在.NET 3.5中發佈。展望未來,我希望WPF/Silverlight團隊能夠重組。除了所有的darn字符串外,XAML都可以。啓動Relector,看看他們爲System.Windows.DataTrigger之類的事情做了些什麼。他們的哀嘆可能是LINQ的催化劑。 – 2009-10-07 19:28:20

3

.NET 4.0表達式樹也是DLR AST的

8

您可以使用表達式樹來變換域語言爲可執行代碼的基礎。

1

我已經有了一個很好的經驗,他們將我的域特定語言AST轉換爲表達式樹。使用ANTLR樹形適配器直接從語法創建表達式樹也很容易。

4

解決方案尋找問題呃?

表達式樹允許您將代碼呈現爲可轉換的數據結構,因此它們非常適合語言之間的轉換Linq To SQL是當前最強大的功能。

除了DSL(這是轉換)以外的其他用途是並行化(正在分離),示例中的空間是PLINQ。

+0

是一個解決辦法尋找對於像twitter這樣的問題:) – Surya 2010-08-09 20:05:17

1

可以使用表達式樹作爲代碼生成器具有更高的抽象水平,那麼組件發射和更快然後CodeCompiler。以下是我用來說服團隊使用它們作爲CodeCompiler的替代品的概念的一些證明。

[TestClass] 
public class WhenINeedToAccessPropertiesByNameHavingATypeReference 
{ 
    public class SomeCategoryData 
    { 
     public DateTime CreatedDate { get; set; } 
    } 

    [TestMethod] 
    public void ICanDoThatWithAnExpressionAndItPerformsWell() 
    { 
     // INIT 

     var someCategoryData = 
      Enumerable.Range(1970, 100).Select(year => 
       new SomeCategoryData { CreatedDate = new DateTime(year, 1, 1) }).Cast<object>(); 
     var t = typeof(SomeCategoryData); // or it can be: t = someCategoryData.First().GetType(); 
     var compiled = Stopwatch.StartNew(); 

     // ACT 

     var filter = AccessPropertyByNameInCompiledMannerSomehow(t, "CreatedDate"); 

     // ASSERT 

     Trace.WriteLine(string.Format("compiled in: {0}", compiled.Elapsed)); 
     Assert.IsTrue(compiled.ElapsedMilliseconds < 3, "compiles fast enough"); 

     var executed = Stopwatch.StartNew(); 

     // ACT 
     List<object> result = null; 
     for (var i = 0; i < 10000; i++) 
     { 
      result = someCategoryData.Where(d => filter(d, new DateTime(2000, 1, 1), new DateTime(2009, 1, 1))) 
       .ToList(); 
     } 
     executed.Stop(); 
     Trace.WriteLine(string.Format("executed in: {0}", executed.Elapsed)); 

     // ASSERT 
     Assert.AreEqual(10, result.Count, "insure compiled code actually works"); 
     Assert.IsTrue(executed.ElapsedMilliseconds < 300, "runs fast enough"); 
    } 

    private static Func<object, DateTime, DateTime, bool> 
     AccessPropertyByNameInCompiledMannerSomehow(Type t, string fieldToFilterBy) 
    { 
     var objectParameter = Expression.Parameter(typeof(object), "p"); 
     var instance = Expression.Convert(objectParameter, t); 
     var lower = Expression.Parameter(typeof(DateTime), "l"); 
     var upper = Expression.Parameter(typeof(DateTime), "u"); 

     var composite = Expression.Lambda<Func<object, DateTime, DateTime, bool>>(
      Expression.And(
       Expression.LessThanOrEqual(
        lower, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ), 
       Expression.GreaterThanOrEqual(
        upper, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ) 
       ), objectParameter, lower, upper 
      ); 

     return composite.Compile(); 
    } 
} 
2

快速回答是「不,現在不只是LINQ提供商」。首先,動態語言運行庫擴展表達式樹以支持動態語言。基本上,如果你想將自己的動態語言移植到.NET上(比如IronPython和IronRuby),你將不得不使用表達式樹。好吧,沒有那麼多人擁有自己的語言。其他用例是什麼?其中之一是在運行時生成動態代碼。我在這裏有一個例子:Generating Dynamic Methods with Expression Trees in Visual Studio 2010。它解釋瞭如何使用ET來代替生成MSIL以創建動態方法。實際上,即使在.NET 3.5中,LINQ以外的表達式樹也有一些用例,但這些帖子尚未寫入。

1

我有幾個例子here

(抱歉斷碼格式)

相關問題