Что такое деревья выражений
Разберитесь, как код представляется в виде структуры данных.
«Что такое деревья выражений» — бесплатный урок C# Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Код как данные
Дерево выражений представляет код как структуру данных, которую можно проверить во время выполнения, в отличие от скомпилированных инструкций, которые можно только выполнить. В C# для этого используется Expression<TDelegate>.
Лямбда для делегата и для дерева
Если присвоить лямбду Func<...>, Вы получите исполняемый код. Если присвоить ту же лямбду Expression<Func<...>>, компилятор построит дерево, описывающее эту лямбду.
using System;
using System.Linq.Expressions;
Func<int, int> runnable = x => x + 1; // compiled delegate
Expression<Func<int, int>> tree = x => x + 1; // data structure
Console.WriteLine(runnable(5)); // 6
Console.WriteLine(tree); // x => (x + 1)Проверка дерева
Поскольку дерево выражений является данными, Вы можете прочитать его части: параметры, body и тип узла.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 1;
Console.WriteLine(tree.Parameters[0].Name); // x
Console.WriteLine(tree.Body.NodeType); // Add
Console.WriteLine(tree.ReturnType); // System.Int32Иерархия выражений
Каждый узел является производным от System.Linq.Expressions.Expression. К распространённым типам относятся BinaryExpression, ParameterExpression, ConstantExpression и MethodCallExpression.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 1;
var body = (BinaryExpression)tree.Body;
Console.WriteLine(body.Left); // x
Console.WriteLine(body.Right); // 1Допустимы только лямбды-выражения
В дерево можно преобразовать только лямбду с одним выражением. Лямбды с телом-оператором (в фигурных скобках) нельзя преобразовать в деревья выражений.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> ok = x => x * 2; // fine
// Expression<Func<int,int>> bad = x => { return x*2; }; // compile error
Console.WriteLine(ok); // x => (x * 2)Почему это важно
Деревья выражений позволяют библиотекам понимать Ваш код, а не просто выполнять его. Провайдеры LINQ преобразуют их в SQL, динамические запросы или другие целевые языки.
NodeType сообщает об операции
Свойство NodeType содержит значение перечисления ExpressionType, определяющее операцию в данном узле.
using System;
using System.Linq.Expressions;
Expression<Func<int, bool>> tree = x => x > 10;
Console.WriteLine(tree.Body.NodeType); // GreaterThanКонстанты и параметры
ParameterExpression представляет input, а ConstantExpression хранит литеральное значение, встроенное в код.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 5;
var body = (BinaryExpression)tree.Body;
Console.WriteLine(body.Left.GetType().Name); // ParameterExpression (or TypedParameterExpression)
Console.WriteLine(((ConstantExpression)body.Right).Value); // 5Вызовы методов в деревьях
Лямбда, вызывающая метод, становится объектом MethodCallExpression, который предоставляет доступ к методу и его аргументам.
using System;
using System.Linq.Expressions;
Expression<Func<string, int>> tree = s => s.Length;
// member access here; a call example:
Expression<Func<string, string>> call = s => s.ToUpper();
var mc = (MethodCallExpression)call.Body;
Console.WriteLine(mc.Method.Name); // ToUpperДеревья неизменяемы
Деревья выражений неизменяемы. Чтобы «изменить» дерево, Вы создаёте новое дерево из его частей — именно так работают обходчики и преобразователи.
Объединение всех элементов
Здесь мы рассмотрим небольшое дерево предиката от начала до конца: параметр, оператор и константа.
using System;
using System.Linq.Expressions;
Expression<Func<int, bool>> isAdult = age => age >= 18;
var body = (BinaryExpression)isAdult.Body;
Console.WriteLine(isAdult.Parameters[0].Name); // age
Console.WriteLine(body.NodeType); // GreaterThanOrEqual
Console.WriteLine(((ConstantExpression)body.Right).Value); // 18Быстрая проверка
Убедитесь, что понимаете, чем дерево выражений отличается от обычного кода.
Повторение
Вы узнали, что такое деревья выражений.
Expression<TDelegate>представляет код в виде данных, доступных для проверки.- Узлы включают параметры, константы, двоичные операции и вызовы методов.
- Подходят только лямбды с одним выражением.
- Деревья неизменяемы; при переписывании создаются новые деревья.
Часто задаваемые вопросы
Урок «Что такое деревья выражений» бесплатный?
Да — полный текст урока «Что такое деревья выражений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Что такое деревья выражений»?
Разберитесь, как код представляется в виде структуры данных. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Что такое деревья выражений»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Что такое деревья выражений
- Построение выражений вручную
- Компиляция и выполнение выражений
- Деревья выражений в поставщиках LINQ