Подтвердить что ты не робот

LINQ - Синтаксис запроса против цепей методов и лямбда

Кто-нибудь придерживается каких-либо правил (или вы вынуждены придерживаться каких-либо правил вашим работодателем?) при выборе использования синтаксиса запроса LINQ или выражения Lambda внутри одного из методов расширения LINQ? Это относится к любым объектам, SQL, объектам и т.д.

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

var names = collection.Select(item => item.Name);

var names = from item in collection
            select item.Name;

Возможно, при добавлении условия, Lambda, который я нахожу, немного запутан, где

var names = collection.Where(item => item.Name == "Fred")
                      .Select(item => item.Name);

var names = from item in collection
            where item.Name == "Fred"
            select item.Name;

Просто из интереса: как компилятор относится к этому? Кто-нибудь знает, как этот запрос LINQ будет компилироваться в лямбда? Будет ли вызываться свойство Name для каждого элемента? Можем ли мы сделать это вместо этого и потенциально улучшить производительность? Будет ли это означать, что лямбда немного более контролируема с точки зрения производительности?

var names = collection.Select(item => item.Name)
                      .Where(name => name == "Fred");

Конечно, когда мы начинаем использовать все больше и больше выражений, лямбда становится беспорядочной, и я бы начал использовать синтаксис запроса здесь.

var names = collection.Where(item => item.Name == "Fred")
                      .OrderBy(item => item.Age)
                      .Select(item => item.Name);

var names = from item in collection
            where item.Name == "Fred"
            order by item.Age
            select item.Name;

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

var names = collection.Count(item => item.Name == "Fred");

var names = (from item in collection
            where item.Name == "Fred"
            select item).Count()

Даже для некоторых простых лямбда-цепей ReSharper предлагает преобразовать их в запросы LINQ.

Может ли кто-нибудь еще добавить к этому? У кого-нибудь есть свои собственные правила или их компания предлагает/принудительно использует один?

4b9b3361

Ответ 1

Чтобы ответить на вопрос о переводе, выражение запроса всегда будет переведено на основе правил 7.16 спецификации С# 4 (или эквивалента в спецификации С# 3). В примере, когда вы задаете вопрос о свойстве Name, это не вопрос перевода выражения запроса - это то, что методы Select и Where выполняют с делегатами или деревьями выражений, которые они принимают в качестве параметров. Иногда имеет смысл делать проекцию перед фильтрованием, иногда нет.

Что касается небольших правил, у меня есть только один: используйте любой способ, наиболее читаемый для рассматриваемого вопроса. Поэтому, если запрос изменяется и "какая форма более читаема" изменяется одновременно, измените используемый синтаксис.

Если вы собираетесь использовать LINQ, вы должны быть довольны синтаксисом, по крайней мере, для чтения.

Я обычно обнаруживаю, что запросы с несколькими переменными диапазона (например, через SelectMany или Join или предложение let) становятся более читабельными с использованием выражений запроса, но это далеко от жесткого и быстрого правила.