2010-06-26 3 views

ответ

13

Expression treesданные представления логики - что означает, что они могут быть проверены во время выполнения такими вещами, как поставщики LINQ. Они могут решить, что означает код, и, возможно, преобразовать его в другую форму, такую ​​как SQL.

Семейство типов Func, однако, является просто делегатом. Они заканчиваются как нормальные ИЛ, которые могут быть выполнены непосредственно, но не (легко) исследованы. Обратите внимание, что вы можете скомпилировать деревья выражений (ну, Expression<T> и LambdaExpression) в делегаты и выполнить их в управляемом коде, если вам нужно.

Вы можете создать деревья выражений вручную, используя фабричные методы в классе Expression, но как правило, вы просто использовать тот факт, что C# можно преобразовать лямбда-выражения в обоих деревьев выражений и обычных делегатов:

Expression<Func<int, int>> square = x => x * x; 
Func<int, int> square = x => x * x; 

Обратите внимание, что существуют ограничения, по которым лямбда-выражения могут быть преобразованы в деревья выражений. Самое главное, что только лямбды, состоящие из одного выражения (а не тел оператора) может быть превращены:

// Compile-time error 
Expression<Func<int, int>> square = x => { return x * x; }; 
// Works fine 
Func<int, int> square = x => { return x * x; }; 
3

Выражение может быть создано во время выполнения, функция не (если вы не используете отражение). После того, как вы построите дерево выражений, вы можете скомпилировать его и превратить в указатель функции, который можно вызвать. Func - это указатель на некоторую уже существующую функцию, которая больше не может быть изменена, а Expression представляет код некоторой функции, которая не существует до ее компиляции.

0

Вы обычно используете выражение, если вы хотите сохранить семантики кода, так что вы можете перевести его. То есть, выражения позволяют обрабатывать код как данные. Если код не нужно рассматривать как данные (т. Е. Вы не планируете его хранить или переводить), то использование Func является подходящим.

7

Это не правда, что «они делают то же самое». Expression описывает ваш намерение таким образом, который может быть интерпретирован во время выполнения - это, если хотите, рецепт. Функция - непрозрачный делегат, что не может быть проверен - его можно использовать как черный ящик. По сравнению с рецептом, это какой-то авто-шеф-повар, который не позволяет вам увидеть, что он делает: дайте ему немного хлеба и курица, закройте глаза, и это даст вам сэндвич, но вы никогда не узнаете .

Я обсуждаю это здесь: Explaining Expression, но рецепт является ключевым для LINQ, RPC и т. Д. И, конечно, если у вас есть рецепт, вы можете сделать своего шеф-повара, используя Expression.Compile().

Смежные вопросы