Какой хороший пример использования деревьев выражений .net 4.0? - PullRequest
16 голосов
/ 07 октября 2009

Этот был вдохновлен моим коллегой-лингвистом, который, кажется, не может найти им полезного применения, и после нескольких моих неудачных попыток я должен был согласиться.

Теперь я знаю, что эти концепции имеют тенденцию протекать намного легче, когда у вас есть веские практические причины.

На данный момент кажется, что его единственная цель - позволить вам написать провайдера Linq?

Это что, ?? Есть ли другие преимущества для этого?

Ответы [ 9 ]

16 голосов
/ 07 октября 2009

Дерево выражений настолько мощное, что позволяет обрабатывать код как данные . Пользователи привыкли собирать данные, сохранять их и возвращаться к ним позже.

Деревья выражений позволяют вам делать то же самое с кодом. Например, вы можете взять введенные пользователем данные (флажки, диапазоны номеров и т. Д.) И преобразовать их в дерево выражений. Это дерево выражений затем может быть выполнено или сохранено для последующего использования. Очень круто.

Подумайте о практических применениях в области отчетности, таких как создание и сохранение фильтров данных и сопоставлений данных. Другим практическим применением будет поддержка пользовательских рабочих процессов в вашем приложении на основе определенных пользователем правил.

Вот немного кода MSDN по сериализации деревьев выражений (http://code.msdn.microsoft.com/exprserialization), который должен обеспечить реализацию идей.

8 голосов
/ 07 октября 2009

Деревья выражений можно использовать для преобразования языка домена в исполняемый код.

4 голосов
/ 07 октября 2009

Решение ищет проблему, а?

Деревья выражений позволяют вам представлять код в виде трансформируемой структуры данных, поэтому они идеально подходят для преобразования между языками Linq To SQL, являющимися наиболее мощными в настоящее время.

Другое использование помимо DSL (которое является преобразованием) - распараллеливание (которое разделяется), и примером в этом пространстве является PLINQ.

3 голосов
/ 07 октября 2009

.NET 4.0 Деревья выражений также являются основой для DLR AST

2 голосов
/ 28 октября 2009

Быстрый ответ: «Нет, теперь это не только для поставщиков LINQ». Во-первых, деревья выражений были расширены динамической языковой средой для поддержки динамических языков. По сути, если вы хотите портировать свой собственный динамический язык в .NET (как это сделали IronPython и IronRuby), вам придется использовать деревья выражений. ОК, не так много людей имеют свои языки. Каковы другие варианты использования? Одним из них является генерация динамического кода во время выполнения. У меня есть пример здесь: Создание динамических методов с деревьями выражений в Visual Studio 2010 . Он объясняет, как вы можете использовать ET вместо генерации MSIL для создания динамических методов. Фактически, есть некоторые варианты использования деревьев выражений вне LINQ даже в .NET 3.5, но эти посты еще не написаны.

1 голос
/ 28 октября 2009

У меня есть несколько примеров здесь

(извините за неправильное форматирование кода)

1 голос
/ 07 октября 2009

Вы можете использовать дерево выражений в качестве компоновщика кода с более высоким уровнем абстракции, чем при генерации сборки, и быстрее, чем 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();
    }
}
1 голос
/ 07 октября 2009

см. Этот пост: http://codebetter.com/blogs/gregyoung/archive/2009/10/03/delegate-mapper.aspx Это отличный пример использования.

1 голос
/ 07 октября 2009

У меня был хороший опыт преобразования этих AST для языка моего домена в деревья выражений. С помощью адаптера дерева ANTLR также довольно просто создавать дерево выражений непосредственно из грамматики.

...