Чтение онлайн

на главную

Жанры

Полное руководство. С# 4.0
Шрифт:

За исключением метода Join, остальные методы запроса принимают един ственный аргумент, который представляет собой объект некоторой разновидности обобщенного типа Func. Это тип встроенного делегата, объявляемый следующим образом: delegate TResult Func<in Т, out TResult>(T arg)

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

эти методы в цепочку.

Метод Join принимает четыре аргумента. Первый аргумент (inner) представляет собой ссылку на вторую объединяемую последовательность, а первой является последо вательность, для которой вызывается метод Join. Селектор ключа для первой последо вательности передается в качестве аргумента outerKeySelector, а селектор ключа для второй последовательности — в качестве аргумента LnnerKeySelector. Результат объе динения обозначается как аргумент resultSelector. Аргумент outerKeySelector имеет тип Func, аргумент innerKeySelector — тип Func, тогда как аргумент resultSelector — тип Func, где TOuter — тип элемента из вызывающей последовательности; Tinner — тип эле мента из передаваемой последовательности; TResult — тип элемента из объеди няемой в итоге последовательности, возвращаемой в виде перечислимого объекта.

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

Используя методы запроса одновременно с лямбда-выражениями, можно форми ровать запросы, вообще не пользуясь синтаксисом, предусмотренным в C# для запро сов. Вместо этого достаточно вызвать соответствующие методы запроса. Обратимся сначала к простому примеру. Он представляет собой вариант первого примера про граммы из этой главы, переделанный с целью продемонстрировать применение мето дов запроса Where и Select вместо соответствующих операторов. // Использовать методы запроса для формирования простого запроса. // Это переделанный вариант первого примера программы из настоящей главы. using System; using System.Linq; class SimpQuery { static void Main { int[] nums = { 1, -2, 3, 0, -4, 5 }; // Использовать методы Where и Select для // формирования простого запроса. var posNums = nums.Where(n => n > 0).Select(r => r); Console.Write("Положительные значения из массива nums: "); // Выполнить запрос и вывести его результаты. foreachfint i in posNums) Console.Write(i + " "); Console.WriteLine; } }

Эта версия программы дает такой же результат, как и исходная. Положительные значения из массива nums: 1 3 5

Обратите особое внимание в данной программе на следующую строку кода. var posNums = nums.Where(n => n > 0).Select(r => r);

В этой строке кода формируется запрос, сохраняемый в переменной posNums. По этому запросу, в свою очередь, формируется последовательность положительных зна чений, извлекаемых из массива nums. Для этой цели служит метод Where, отбираю щий запрашиваемые значения, а также метод Select, избирательно формирующий из этих значений окончательный результат. Метод Where может быть вызван для массива nums, поскольку во всех массивах реализуется интерфейс IEnumerable, поддерживающий методы расширения запроса.

Формально метод Select в рассматриваемом здесь примере не нужен, посколь ку это простой запрос. Ведь последовательность, возвращаемая методом Where, уже содержит конечный результат. Но окончательный выбор можно сделать и по более сложному критерию, как это было показано ранее на примерах использования син таксиса запросов. Так, по приведенному ниже запросу из массива nums возвращаются положительные значения, увеличенные на порядок величины. var posNums = nums.Where(n => n > 0).Select(r => r * 10);

Как и следовало ожидать, в цепочку можно объединять и другие операции над дан ными, получаемыми по запросу. Например, по следующему запросу выбираются по ложительные значения, которые затем сортируются по убывающей и возвращаются в виде результирующей последовательности: var posNums = nums.Where(n => n > 0).OrderByDescending(j => j);

где выражение j => j обозначает, что упорядочение зависит от входного параметра, который является элементом данных из последовательности, получаемой из метода Where.

В приведенном ниже примере демонстрируется применение метода запроса GroupBy. Это измененный вариант представленного ранее примера. // Продемонстрировать применение метода запроса GroupBy. // Это переработанный вариант примера, представленного ранее // для демонстрации синтаксиса запросов. using System; using System.Linq; class GroupByDemo { static void Main { string[] websites = { "hsNameA.com", "hsNameB.net", "hsNameC.net", "hsNameD.com", "hsNameE.org", "hsNameF.org", "hsNameG.tv", "hsNameH.net", "hsNameI.tv" }; // Использовать методы запроса для группирования // веб-сайтов по имени домена самого верхнего уровня. var webAddrs = websites.Where(w => w.LastIndexOf('.') != 1). GroupBy(x => x.Substring(x.LastIndexOf(".", x.Length))); // Выполнить запрос и вывести его результаты. foreach(var sites in webAddrs) { Console.WriteLine("Веб-сайты, сгруппированные " + "по имени домена " + sites.Key); foreach(var site in sites) Console.WriteLine(" " + site); Console.WriteLine; } } }

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

Рассмотрим другой пример. Но сначала приведем еще раз запрос из представлен ного ранее примера применения оператора join. var inStockList = from item in items join entry in statusList on item.ItemNumber equals entry.ItemNumber select new Temp(item.Name, entry.InStock);

По этому запросу формируется последовательность, состоящая из объектов, инкап сулирующих наименование товара и состояние его запасов на складе. Вся эта инфор мация получается путем объединения двух источников данных: items и statusList. Ниже приведен переделанный вариант данного запроса, в котором вместо синтаксиса, предусмотренного в C# для запросов, используется метод запроса Join. // Использовать метод запроса Join для составления списка // наименований товаров и состояния их запасов на складе. var inStockList = items.Join(statusList, k1 => k1.ItemNumber, k2 => k2.ItemNumber, (k1, k2) => new Temp(k1.Name, k2.InStock) );

В данном варианте именованный класс Temp используется для хранения результи рующего объекта, но вместо него можно воспользоваться анонимным типом. Такой вариант запроса приведен ниже. var inStockList = items.Join(statusList, k1 => k1.ItemNumber, k2 => k2.ItemNumber, (k1, k2) => new { k1.Name, k2.InStock} ); Синтаксис запросов и методы запроса

Как пояснялось в предыдущем разделе, запросы в C# можно формировать двумя способами, используя синтаксис запросов или методы запроса. Любопытно, что оба способа связаны друг с другом более тесно, чем кажется, глядя на исходный код про граммы. Дело в том, что синтаксис запросов компилируется в вызовы методов запроса. Поэтому код where х < 10

Поделиться:
Популярные книги

Александр Агренев. Трилогия

Кулаков Алексей Иванович
Александр Агренев
Фантастика:
альтернативная история
9.17
рейтинг книги
Александр Агренев. Трилогия

Последняя Арена 11

Греков Сергей
11. Последняя Арена
Фантастика:
фэнтези
боевая фантастика
рпг
5.00
рейтинг книги
Последняя Арена 11

Ты всё ещё моя

Тодорова Елена
4. Под запретом
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Ты всё ещё моя

Лейб-хирург

Дроздов Анатолий Федорович
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Лейб-хирург

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Хочу тебя любить

Тодорова Елена
Любовные романы:
современные любовные романы
5.67
рейтинг книги
Хочу тебя любить

Физрук 2: назад в СССР

Гуров Валерий Александрович
2. Физрук
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Физрук 2: назад в СССР

Шипучка для Сухого

Зайцева Мария
Любовные романы:
современные любовные романы
8.29
рейтинг книги
Шипучка для Сухого

Система Возвышения. (цикл 1-8) - Николай Раздоров

Раздоров Николай
Система Возвышения
Фантастика:
боевая фантастика
4.65
рейтинг книги
Система Возвышения. (цикл 1-8) - Николай Раздоров

Жандарм 4

Семин Никита
4. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 4

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

Кодекс Крови. Книга VIII

Борзых М.
8. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VIII

Слово дракона, или Поймать невесту

Гаврилова Анна Сергеевна
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Слово дракона, или Поймать невесту

Неверный. Свободный роман

Лакс Айрин
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Неверный. Свободный роман