Расширение Linq mix и синтаксис запроса - PullRequest
8 голосов
/ 01 марта 2011

Я предпочитаю использовать методы расширения для основных операций LINQ: Where(), Select, но для сложных операторов Select(), SelectMany() и особенно OrderBy().ThenBy() я считаю синтаксис запроса более читабельными естественно.

Сегодня я обнаружил, что задаю следующий запрос:

from c in _myObject.ObjectsParent.ParentsEnumerable
                    .Where(c =>
                        c == anotherObject || c.Parent == anotherObject)
from q in c.MyObjectsEnumerable
orderby c.SortKey, q.Description
select new { Item = q, Text = c.Description + " -> " + q.Description };

Опасно ли смешивать синтаксис запросов и расширений (из-за читабельности, удобства обслуживания или по любой другой причине)?*

Это может быть очень субъективным, если это так, извините, если оно не соответствует требованиям для хорошего субъективного вопроса.Дайте мне знать, если я смогу улучшить это!

Ответы [ 6 ]

6 голосов
/ 01 марта 2011

Опасно ли (из-за читабельности, удобства обслуживания или по любой другой причине) смешивать синтаксис запросов и расширений?

Самая большая опасность, которую я вижу, - это потенциальное добавление "удивления""в вашем коде, особенно при просмотре другими разработчиками.

С точки зрения компиляции синтаксис запроса транслируется непосредственно в вызовы метода расширения, поэтому здесь не обязательно возникнет техническая проблема.Однако это может привести к добавлению дополнительных вызовов методов, которые, на первый взгляд, не ожидаются многими разработчиками.Это может привести к потенциальной проблеме сопровождения.

При этом, если делать это экономно и по уважительной причине, я не чувствую реальной проблемы со смешиванием синтаксиса.На самом деле это довольно распространенное явление - например, если вы хотите писать в синтаксисе запроса, но должны полностью его оценить, оно часто заключено в скобки с добавлением .ToList () - или если вы хотите использовать PLINQ с синтаксисом запроса, это часто from x in collection.AsParallel(), который также технически смешивает синтаксис ...

3 голосов
/ 01 марта 2011

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

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

Однако есть случаи, которые не могут быть элегантно выражены в синтаксисе запроса. В случаях, когда просто невозможно смешать синтаксисы, запросы (опять же IMO) будут более читабельными, если вы разделите цепочку методов на ее собственную переменную, а затем просто ссылаетесь на эту переменную в выражении синтаксиса запроса. Используя ваш в качестве модели:

//The method chain can be pulled out as its own variable...
var filteredParents = _myObject.ObjectsParent.ParentsEnumerable
                    .Where(c => c == anotherObject || c.Parent == anotherObject);

//...which you can then substitute in a now purely query-syntax statement
from c in filteredParents
from q in c.MyObjectsEnumerable
orderby c.SortKey, q.Description
select new { Item = q, Text = c.Description + " -> " + q.Description };
3 голосов
/ 01 марта 2011

Вы можете сделать что-то вроде этого, чтобы немного упростить процесс.

var firstQuery =  _myObject.ObjectsParent.ParentsEnumerable
                 .Where(c => c == anotherObject || c.Parent == anotherObject);

var secondQuery = from q in firstQuery.MyObjectsEnumerable
                  orderby firstQuery.SortKey, q.Description
                  select new { Item = q, 
                               Text = firstQuery.Description + " -> " + q.Description };

Теперь ваши запросы не смешаны

2 голосов
/ 01 марта 2011

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

   _myObject.ObjectsParent
            .ParentsEnumerable
            .Where(c => c == anotherObject || c.Parent == anotherObject)
            .SelectMany(c => c.MyObjectsEnumerable, (c, q) => new {c, q})
            .OrderBy(t => t.c.SortKey)
            .ThenBy(t => t.q.Description)
            .Select(t => new {Item = t.q, Text = t.c.Description + " -> " + t.q.Description});
1 голос
/ 01 марта 2011

Сделав это сам (хотя и не для .Where, но для .Cast), я бы сказал, что очень многое зависит от того, какие методы расширения вы вызываете.

например, я чувствовал себя совершенно вправе использовать .Castпотому что он не был доступен в синтаксическом сахаре (AFAIK), но, вероятно, избежал .Where, потому что он имеет представление в синтаксисе запроса.

Сказав это, я бы, вероятно, использовал .Select для изменения данныхв запросе тоже ... Но я немного садист.

1 голос
/ 01 марта 2011

Я использую методы расширения, мой коллега использует синтаксис запроса.Нет никакой разницы.

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

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