Они оказываются пригодными в тех случаях, когда запрос выполняется вне програм мы, например средствами SQL в базе данных. Если запрос представлен в виде данных, то его можно преобразовать в формат, понятный для базы данных. Этот процесс вы полняется, например, средствами LINQ to SQL в интегрированной среде разработки Visual Studio. Таким образом, деревья выражений способствуют поддержке в C# раз личных баз данных.
Для получения исполняемой формы дерева выражений достаточно вызвать метод Compile, определенный в классе Expression. Этот метод возвращает ссылку, ко торая может быть присвоена делегату для последующего выполнения. А тип делегата может быть объявлен собственным или же одним из предопределенных типов деле гата Func в пространстве имен System. Две формы делегата Func уже упоминались ранее при рассмотрении методов запроса, но существует и другие его формы. Деревьям выражений присуще следующее существенное ограничение: они могут представлять только одиночные лямбда-выражения. С их помощью нельзя предста вить блочные лямбда-выражения.
Ниже приведен пример программы, демонстрирующий конкретное применение
дерева выражений. В этой программе сначала создается дерево выражений, данные
которого представляют метод, определяющий, является ли одно целое число множи
телем другого. Затем это дерево выражений компилируется в исполняемый код. И на
конец, в этой программе демонстрируется выполнение скомпилированного кода.
// Пример простого дерева выражений.
using System;
using System.Linq;
using System.Linq.Expressions;
class SimpleExpTree {
static void Main {
// Представить лямбда-выражение в виде данных.
Expression
Вот к какому результату приводит выполнение этой программы. Число 5 является множителем 10. Число 7 не является множителем 10.
Данный пример программы наглядно показывает два основных этапа применения
дерева выражений. Сначала в ней создается дерево выражений с помощью следующе
го оператора.
Expression
В этом операторе конструируется представление лямбда-выражения в оперативной
памяти. Как пояснялось выше, это представление доступно по ссылке, присваиваемой
делегату IsFactorExp. А в следующем операторе данные выражения преобразуются
в исполняемый код.
Func
После выполнения этого оператора делегат IsFactorExp может быть вызван, что бы определить, является ли одно целое число множителем другого.
Обратите также внимание на то, что
Как упоминалось выше, методы расширения предоставляют средства для расшире ния функций класса, не прибегая к обычному механизму наследования. Методы рас ширения создаются нечасто, поскольку механизм наследования, как правило, пред лагает лучшее решение. Тем не менее знать, как они действуют, никогда не помешает. Ведь они имеют существенное значение для LINQ.