17

これは、言語の第一人者である私の同僚に触発されたもので、良い使い方を見つけられないようでした.

これらの概念は、実用的な理由を理解すれば、より簡単に流れていく傾向があることがわかりました。

現時点では、Linq プロバイダーを作成できるようにすることが唯一の目的のように見えますか?

それですか??これには他に何か利点がありますか?

4

9 に答える 9

18

式ツリーは、コードをデータのように扱うことができるため、非常に強力です。ユーザーは、データを構築し、保存して、後で戻ってくることに慣れています。

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

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

式ツリーのシリアル化に関するMSDNコード( http://code.msdn.microsoft.com/exprserialization )を少し紹介します。これにより、アイデアが流れるようになります。

于 2009-10-07T16:45:11.267 に答える
9

式ツリーを使用して、ドメイン言語を実行可能コードに変換できます。

于 2009-10-07T16:11:57.057 に答える
5

問題を探している解決策ですか?

式ツリーを使用すると、コードを変換可能なデータ構造として提示できるため、言語間の変換に最適です。LinqToSQLは現在最も強力です。

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

于 2009-10-07T16:12:53.703 に答える
3

.NET 4.0 式ツリーは、DLR AST の基礎でもあります

于 2009-10-07T16:09:57.840 に答える
2

簡単な答えは、「いいえ、今は LINQ プロバイダーだけのものではありません」です。まず、動的言語をサポートするために、動的言語ランタイムによって式ツリーが拡張されました。基本的に、(IronPython や IronRuby が行ったように) 独自の動的言語を .NET に移植する場合は、式ツリーを使用する必要があります。OK、多くの人が自分の言語を持っているわけではありません。その他のユースケースは?その 1 つは、実行時に動的コードを生成することです。ここに例があります: Visual Studio 2010 で式ツリーを使用して動的メソッドを生成します。動的メソッドを作成するために、MSIL を生成する代わりに ET を使用する方法について説明します。実際、.NET 3.5 でも LINQ 以外の式ツリーのユース ケースがいくつかありますが、それらの投稿はまだ作成されていません。

于 2009-10-28T19:15:37.313 に答える
1

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

于 2009-10-07T16:12:48.023 に答える
1

この投稿を参照してください:http://codebetter.com/blogs/gregyoung/archive/2009/10/03/delegate-mapper.aspx これは素晴らしいユースケースです。

于 2009-10-07T16:14:34.630 に答える
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();
    }
}
于 2009-10-07T18:29:41.223 に答える
1

ここにはいくつかの例があります

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

于 2009-10-28T19:21:00.217 に答える