Разница между Expression> и Func [дубликат]


этот вопрос уже есть ответ здесь:

в качестве примера, почему большинство операторов LINQ признать Expression<Func<TSource>> и его эквивалент Func<TSource>?

В чем преимущество/причина использования generic Expression класс вместо прямо вверх лямбда-синтаксис?

4 72

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-это исполняемый код.