Разница между Expression> и Func [дубликат]
этот вопрос уже есть ответ здесь:
в качестве примера, почему большинство операторов LINQ признать Expression<Func<TSource>>
и его эквивалент Func<TSource>
?
В чем преимущество/причина использования generic Expression
класс вместо прямо вверх лямбда-синтаксис?
4 ответа:
С помощью
Expression<T>
вы явно создаете выражение дерево - это означает, что вы можете работать с кодом, который составляет запрос, как если бы это были данные.причина этого заключается в том, что поставщики LINQ (например, LINQ to SQL) проверяют сам запрос, чтобы определить лучший способ перевода выражений C# в запрос T-SQL. Поскольку дерево выражений позволяет рассматривать код как данные, поставщик может это сделать.
таким образом, основные различия между ними следующие:
Expression<Func<...>>
это выражение дерево который представляет исходный исходный код (он хранится в древовидной структуре данных, которая очень близка к исходному коду C#). В этой форме вы можете анализировать исходный код, а такие инструменты, как LINQ to SQL, могут переводить дерево выражений (исходный код) на другие языки (например, SQL в случае LINQ to SQL, но вы также можете цель, например, JavaScript).
Func<...>
обычный делегат, который вы можете выполнить. В этом случае компилятор компилирует тело функции на промежуточный язык (IL) так же, как при компиляции стандартного метода.стоит отметить, что
Expression<..>
естьCompile
метод, который компилирует выражение во время выполнения и генерируетFunc<...>
, Так что есть преобразование из первого во второй (с некоторыми стоимость исполнения). Однако нет преобразования из второго в первый, потому что как только вы получаете IL, очень сложно (невозможно) восстановить исходный исходный код.
Func<T>
создает исполняемую функцию.
Expression<Func<T>>
создает дерево выражения, которое позволяет работать с кодом в функции как данные.деревья выражений позволяют делать такие вещи, как LINQ to SQL и LINQ to XML, создавая базовые вызовы из вашего кода .NET.
An
Expression<Func<>>
- Это представление функции, которая еще не превратилась в код. АFunc<>
- это фактическая исполняемая функция. Использование первого позволяет превратить выражение в соответствующую функцию во время его вызова. Например, с LINQ to SQL это переведет его в эквивалентный код для выполнения инструкции SQL и возврата указанного содержимого. С помощью LINQ to objects он будет выполнять код на клиенте с помощью среды CLR. АFunc<>
всегда выполняется в среде CLR-это исполняемый код.