Преобразование лямбда-выражения в дерево выражений - PullRequest
8 голосов
/ 07 декабря 2011

Из глубины C #:

Не все лямбда-выражения можно преобразовать в деревья выражений.Вы не можете преобразовать лямбду с блоком операторов (даже с одним оператором возврата) в дерево выражений -> оно должно быть в форме, которая просто оценивает одно выражение.

Так какОператоры Linq-to-Object не преобразуются в объекты дерева выражений, лямбда-выражения, используемые с операторами Linq-to-Object, могут содержать блок операторов

        string[] count = { "one ", "two ", "three ", "four ", "five ", "six " };
        IEnumerable<int> result = count.Select(item =>
                               {
                                   Console.WriteLine(item);
                                   return item.Length;
                               });
        foreach (int i in result);

OUTPUT:

one two three four five six

Я еще не начал изучать Linq-To-Sql или Linq-To-Entities, но я предполагаю, что лямбда-выражения, используемые в операторах LINQ, которые работают с IQueryable<T>, могут содержать только одно выражение из-за переопределения, которое толькоодно выражение может быть преобразовано в дерево выражений?

Спасибо

Ответы [ 2 ]

15 голосов
/ 07 декабря 2011

Мало того, что они могут содержать только одно выражение - это не может быть оператор лямбда вообще.Даже такой блок:

var result = query.Select(item => { return item.Length; });

будет недопустимым для LINQ to SQL.Это должно было бы быть выражено как:

var result = query.Select(item => item.Length);

(я только что заметил, что это часть книги, которую вы цитировали. Ну да ладно - это показывает, что я последовательна)Обратите внимание, что в .NET 4 сами деревья выражений do имеют возможность содержать блоки, но компилятор C # не может переводить лямбда-выражения операторов в такое дерево выражений.Есть и другие ограничения, но они редко вызывают проблемы.

Это указано в разделе 4.6 спецификации C # 4:

Не все анонимные функции могут быть представлены в виде деревьев выражений.Например, анонимные функции с телами операторов и анонимные функции, содержащие выражения присваивания, не могут быть представлены.В этих случаях преобразование все еще существует, но завершится неудачей во время компиляции.

1 голос
/ 07 декабря 2011

Вы правы, они могут содержать только одно выражение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...