Какие преимущества приносят деревья выражений в таблицу?
Деревья выражений позволяют программе упрощенно манипулировать частью собственной реализации во время выполнения. Они позволяют выражениям передаваться как представление их структуры, а не просто как делегат, который может быть вызван.
Что именно означает это утверждение: «Деревья выражений - это данные, скомпилированные в виде кода»?
Языки до 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 , вероятно, является лучшим выбором на данный момент.