Пытаясь понять, что такое дерево выражений - PullRequest
4 голосов
/ 18 октября 2011

Оба фрагмента ниже продукта одинакового выхода.Я понимаю, как Func инкапсулирует метод с одним параметром и возвращает значение bool.И вы можете назначить ему метод, анонимный метод или лямбда-выражение.

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));

Ответы [ 4 ]

5 голосов
/ 18 октября 2011

По сути, дерево выражений - это тело лямбда-выражения, которое позволяет вам

  • анализирует выражение (см. что в нем так сказать)
  • манипулировать выражением (упрощать, расширять (например, добавлять новые функции или изменять для работы с различными элементами).

Как только вы Compile() выражение, это просто еще один делегат , который вы можете только вызвать , не проверять или изменять.

Всякий раз, когда вы хотите

  • динамически создавать выражения (я имею в виду: конструировать, а не выделять)
  • работает с выражениями динамически

типов Function<> недостаточно.

1 голос
/ 18 октября 2011

В первом примере вы просто «жестко закодировали» тело функции и присвоили его делегату.

Во втором примере назначение создает дерево выражений, которое представляет собой объектную модель, представляющую ваш кодв структуре данных в памяти.

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

Например, LINQ2SQL использует эту технику для перевода ваших выражений в другой язык, называемый SQL.

1 голос
/ 18 октября 2011

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

Например, Linq2SQL компилирует деревья выражений в код SQL. Вы не могли бы сделать это с простой функцией .net.

0 голосов
/ 18 октября 2011

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

С другой стороны, скомпилированная функция представляет собой не что иное, как последовательность кода CIL.Вы все еще можете проверить его программно, но вы проверяете не определение, а вывод его компилятора.

...