2009-10-07 17 views
16

これは、私の言語仲間の協力者からインスピレーションを得て、彼らのために使い勝手が良さそうだと思っています。.net 4.0表現木の良いユースケースは?

今、私はこれらの概念が実用的な理由をいくつか取り除くと、もっと簡単に流れる傾向があることを知っています。

現時点では、Linqプロバイダを作成することが唯一の目的であるようです。

それは?これに他の利点はありますか?

+3

http://stackoverflow.com/questions/403088/practical-use-of-expression-trees –

答えて

15

表現木は、コードデータのように扱えるので、非常に強力です。ユーザーはデータを構築し、保存して後でそのデータに戻すことに慣れています。

エクスプレッションツリーを使用すると、同じことをコードで実行できます。たとえば、ユーザーの入力(チェックボックス、数値範囲など)を取り、それを式ツリーに変換することができます。その後、その式ツリーを実行したり、後で使用するために保存することができます。とてもかっこいい。

データフィルタの構築と保存、データマッピングの保存などのレポートに関する実用的な使い方を考えてみましょう。別の実用的な使用方法は、ユーザー定義のルールに基づいてアプリケーション内のカスタムワークフローをサポートすることです。

ここに、アイデアを流すべき式のツリー(http://code.msdn.microsoft.com/exprserialization)をシリアル化するMSDNコードがあります。

+0

クール!これは私の考え方に合った答えです。素晴らしい例! フレームワークの他の部分でこれがどのように使用されているのかを見てきました。だから、これはWPFで多く使われていますか? – KevinDeus

+0

ありがとうございます。喜んで助けた。私はWPFについて(おそらく多すぎる)、ラムダやエクスプレッションツリーのような魅力的な関数型プログラミングの概念がいかにコアにあるのだろうと考えました。問題はWPFが.NET 3.0でリリースされ、LINQが.NET 3.5でリリースされたことです。今後は、WPF/Silverlightチームがリタールすることを願っています。 XAMLはすべての文字列以外はOKです:)。 Relectorを起動し、System.Windows.DataTriggerなどのために何をしなければならないかを確認します。彼らの嘆きはLINQの触媒になっているかもしれません。 –

3

.NET 4.0式ツリーはまた、あなたが実行可能なコードにドメイン言語を変換するために式ツリーを使用することができDLR ASTの

1

私は、ドメイン固有の言語ASTを表現木に変換する良い経験をしました。 ANTLRツリーアダプターでは、文法から直接式ツリーを作成することもかなり簡単です。

4

問題を探している解決策はありますか?

表現木は、変換可能なデータ構造としてコードを表示できるため、言語間の変換に最適です。Linq SQLが現在最も強力です。

DSLとは別の用途(変換)は並列化(分割)であり、その例ではPLINQです。

+0

はいソリューション探しを持っていますtwitterのような問題のために:) – Surya

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のように)、式ツリーを使用する必要があります。 それほど多くの人が自分の言語を持っているわけではありません。他のユースケースは何ですか?それらの1つは、実行時に動的コードを生成することです。ここに例があります:Generating Dynamic Methods with Expression Trees in Visual Studio 2010。動的メソッドを作成するためにMSILを生成する代わりにETを使用する方法について説明します。 実際、.NET 3.5でもLINQ以外のエクスプレッションツリーにはいくつかのユースケースがありますが、これらの投稿はまだ作成されていません。

1

私はいくつかの例here

(フォーマット壊れたコードについて申し訳ありません)

関連する問題