Добавить в цитаты Настройки чтения

Страница 320 из 502

<b>foreach(var t in byHow) {</b>

<b>  Console.WriteLine(&quot;К категории &lt;{0} транспорт&gt; относится:&quot;, t.How);</b>

<b>  foreach(var m in t.Tlist)</b>

<b>    Console.WriteLine(&quot; &quot; + m.Name);</b>

<b>  Console.WriteLine();</b>

<b>}</b>

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

Методы запроса

Синтаксис запроса, описанный в предыдущих разделах, применяется при формировании большинства запросов в С#. Он удобен, эффективен и компактен, хотя и не является единственным способом формирования запросов. Другой способ состоит в использовании методов запроса, которые могут вызываться для любого перечислимого объекта, например массива.

Методы запроса определяются в классе System.Linq.Enumerable и реализуются в виде методов расширения функций обобщенной формы интерфейса IEnumerable&lt;T&gt;. (Методы запроса определяются также в классе System.Linq.Queryable, расширяющем функции обобщенной формы интерфейса IQueryable&lt;T&gt;, но этот интерфейс в настоящей главе не рассматривается.) Метод расширения дополняет функции другого класса, но без наследования. Поддержка методов расширения была внедрена в версию C# 3.0 и более подробно рассматривается далее в этой главе. А до тех пор достаточно сказать, что методы запроса могут вызываться только для тех объектов, которые реализуют интерфейс IEnumerable&lt;T&gt;.

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

<b>Оператор запроса  Эквивалентный метод запроса</b>

select            Select(<i>selector)</i>

where             Where(<i>predicate)</i>

orderby           OrderBy(<i>keySelector)</i> или

                  OrderByDescending(<i>keySelector)</i>

join              Join<i>(i

<i>                    i

group             GroupBy(<i>keySelector)</i>

За исключением метода Join(), остальные методы запроса принимают единственный аргумент, который представляет собой объект некоторой разновидности обобщенного типа Func&lt;T, TResult&gt;. Это тип встроенного делегата, объявляемый следующим образом:

<b>delegate TResult Func&lt;in Т, out TResult&gt;(Т arg)</b>

где TResult обозначает тип результата, который дает делегат, а Т — тип элемента. В методах запроса аргументы <i>selector</i>, <i>predicate</i> или <i>keySelector</i> определяют действие, которое предпринимает метод запроса. Например, в методе Where() аргумент <i>predicate</i> определяет порядок отбора данных в запросе. Каждый метод запроса возвращает перечислимый объект. Поэтому результат выполнения одного метода запроса можно использовать для вызова другого, соединяя эти методы в цепочку.

Метод Join() принимает четыре аргумента. Первый аргумент (<i>i

Аргумент метода запроса представляет собой метод, совместимый с указываемой формой делегата Funс, но он не обязательно должен быть явно объявляемым методом. На самом деле вместо него чаще всего используется лямбда-выражение. Как пояснялось в главе 15, лямбда-выражение обеспечивает более простой, но эффективный способ определения того, что, по существу, является анонимным методом, а компилятор C# автоматически преобразует лямбда-выражение в форму, которая может быть передана в качестве параметра делегату Funс. Благодаря тому что лямбда-выражения обеспечивают более простой и рациональный способ программирования, они используются во всех примерах, представленных далее в этом разделе.

Используя методы запроса одновременно с лямбда-выражениями, можно формировать запросы, вообще не пользуясь синтаксисом, предусмотренным в C# для запросов. Вместо этого достаточно вызвать соответствующие методы запроса. Обратимся сначала к простому примеру. Он представляет собой вариант первого примера программы из этой главы, переделанный с целью продемонстрировать применение методов запроса Where() и Select() вместо соответствующих операторов.