Какие преимущества приносят деревья выражений?
Деревья выражений позволяют программе упрощенно манипулировать частью своей реализации во время выполнения. Они позволяют передавать выражения как представление их структуры, а не просто делегат, который можно вызывать.
Что именно означает это утверждение: «Деревья выражений — это данные, скомпилированные в виде кода»?
Языки до C#/.NET поддерживали такого рода манипуляции... лучшим примером является LISP. Способность представлять структуру программы в структуре данных внутри программы называется гомоиконичностью. . C# поддерживает ограниченную гомоиконичность в виде деревьев выражений. Язык C# позволяет прозрачно создавать деревья выражений из (подмножества) выражений в вашем коде. Например:
int x = 3;
Expression<Func<bool>> IsXLessThan4Expr = () => x < 4;
Func<bool> IsXLessThan4 = () => x < 4;
Переменная IsXLessThan4Expr
берется из лямбда-выражения в виде дерева выражений. Теперь мы можем просмотреть представление этого выражения, если хотим понять, какова его структура, и манипулировать им, если захотим. Делегат IsXLessThan4
, напротив, не может быть проинспектирован... его можно только вызывать. Конечно, вы всегда можете получить необработанный IL для любого метода (при условии, что у вас есть необходимые разрешения), но гораздо сложнее изменить логическую структуру программы из IL, чем из дерева выражений.
Какие общие проблемы решают деревья выражений и функциональное программирование в контексте .net?
Лучшим примером использования деревьев выражений для решения нетривиальной задачи является LINQ-to-SQL, где реализация IQueryable
способна преобразовывать деревья выражений запросов, написанные на C#, в эквивалентные запросы SQL, которые могут выполняться базой данных. .
Деревья выражений также позволяют генерировать код C# на лету, поскольку деревья выражений могут быть скомпилированы в лямбда-выражения. Вот пример этого:
var paramNotification =
Expression.Parameter(typeof (NotificationEntry), "noti");
Func<NotificationEntry, bool> predicate =
m_PredicateExpr = Expression.Lambda<Func<NotificationEntry, bool>>(
Expression.LessThan(
Expression.Property(paramNotification, "Value"),
Expression.Constant(100)),
new[] {paramNotification})
.Compile();
Приведенный выше фрагмент создает выражение, которое сравнивает поле Value
объекта NotificationEntry
с некоторой предоставленной константой (100) и компилирует его в лямбду, которую мы можем вызвать.
Какие есть хорошие онлайн-ресурсы, чтобы набрать скорость по этому вопросу?
MSDN, вероятно, лучший выбор на данный момент.
person
LBushkin
schedule
10.11.2010