Вот код.Что делает компилятор C# выводить дерево выражений вместо кода?
int[] data = new int[] { 1, 2, 3, 4, 5 };
var q1 = data.Select(x => 10 * x);
var q2 = data.AsQueryable().Select(x => 10 * x);
Expression<Func<int,int>> qe = (x) => 10 * x;
В первом случае компилятор генерирует код для оценки выражения. На выходе нет дерева выражений.
Во втором он генерирует дерево выражений (видимое при отладке), которое во время выполнения компилируется и выполняется для выполнения запроса (и делает то же самое).
В третьем случае такая же лямбда как (2) создается непосредственно как дерево выражений (а не как код).
Что заставляет компилятор генерировать дерево выражений вместо кода в этих двух случаях, и есть ли другие интересные случаи?
Причина: я хочу «выделить» верхний уровень дерева выражений во время выполнения, а затем скомпилировать и выполнить нижние уровни. У меня возникли проблемы с тем, чтобы заставить компилятор делать все по-моему!
Это случай «так написано компилятором». Это нужно сделать так, чтобы заставить выражения работать. Это похоже на методы, возвращающие 'IEnumerable' может использовать 'yield return'. Специальные операции компилятора для поддержки языковых функций. –
Enigmativity
Этот список можно продолжить. Компилятор обрабатывает 'Nullable' типы по-разному. Он может использовать утиную печать для циклов foreach. Запросы LINQ - это просто переупорядоченные методы (обычно это метод расширения, но не обязательно). 'using' заявления работают только с расходными материалами и т. д. –
Enigmativity
Ваше первое утверждение не является выражением; это вызов конструктора *. Два оператора Select - это выражения Linq, которые выражают как часть их нормальной работы. Четвертый оператор генерирует выражение, потому что вы указали выражение как результирующий тип. –