Г. Шилдт - С#4.0 Полное руководство (1160795), страница 130
Текст из файла (страница 130)
Аргумент метода запроса представляет собой метод, совместимый с указываемой формой делегата риис, но он не обязательно должен быть явно объявляемым методом. На самом деле вместо него чаще всего используется лямбда-выражение. Как пояснялось в главе 15, лямбда-выражение обеспечивает более простой, но эффективный способ определения того, что, по существу, является анонимным методом, а компилятор Ся автоматически преобразует лямбда-выражение в форму, которая может быть передана в качестве параметра делегату риис. Благодаря тому что лямбда-выражения обеспечивают более простой и рациональный способ программированил, они используются во всех примерах, представленных далее в этом разделе.
Формирование запросов с помощью методов запроса Используя методы запроса одновременно с лямбда-выражениями, можно формировать запросы, вообще не пользуясь синтаксисом, предусмотренным в С() для запросов. Вместо этого достаточно вызвать соответствующие методы запроса. Обратимся сначала к простому примеру. Он представляет о>бой вариант первого примера программы из этой главы, переделанный с целью продемонстрировать применение методов запроса НЬеге () и Зе1есп () вместо соответствующих операторов.
// Использовать методы запроса для формирования простого запроса. О Это переделанный вариант первого примера программы из настоящей главы. ивгпд Зувоеви ивьпд зувсем. Ьгпоп с1ава Зивроиегу ( вгасгс го1О Ма1п() ( Глава 19. Пй(( 671 1па() пшпя = ( 1, -2, 3, О, 4, 5 )1 О использовать методы Влете() и Яе1еас() для О формирования прсатага запроса. чаг рояишпя = илпя.влете (п => п > О) .Бе1еаг(г => г); Сспяс1е.нггсе("Положительные значения из массива пшпя: УУ Выполнить запрос и вывести его результаты. Гагеясл(1пг 1 гп раяНшпя) Сопяс1е.нгтге(г + " ")( Сопяо1е.нггаеь1пе()," Эта версия программы дает такой же результат, как и исходная.
Положительные значения из масаива пшпя: 1 З 5 Обратите особое внимание в данной программе на следующую строку кода. чяг раянцшя = папа.нлеге (п => п > О) .Бе1еса (г => г); В этой строке кода формируется запрос, сохраняемый в переменной роянцшя. По этому запросу, в свою очередь, формируется последовательность положительных значений, извлекаемых из массива пцтя. Для этой цели служит метод И)песе (), отбирающий запрашиваемые значения, а также метод Бе1еа с ( ), избирательно формирующий из этих значений окончательный результат.
Метод И)песе () может быть вызван для массива иная, поскольку во всех массивах реализуется интерфейс 1ЕпцшегаЬ1е<Т>, поддерживающий методы расширения запроса. Формально метод Бе1еса () в рассматриваемом здесь примере не нужен, поскольку это простой запрос. Ведь последовательность, возвращаемая методом И)1еге (), уже содержит конечный результат. Но окончательный выбор можно сделать и по более сложному критерию, как это было показано ранее на примерах использования синтаксиса запросов.
Так, по приведенному ниже запросу из массива пцшя возвращаются положительные значения, увеличенные на порядок величины. чаг рсяншпя = пция.влете (п => и > О) .Бе1еап (г => г * 10) и Как и следовало ожидать, в цепочку можно объединять и другие операции над данными, получаемыми по запросу. Например, по следующему запросу выбираются положительные значения, которые затем сортируются по убывающей и возвращаются в виде результирующей последовательности: чаг раяншпя = пция.Влете (и => п > О) .Огбегвуоеясепб1пч(1 => З) 1 где выражение 5 => и обозначает, что упорядочение зависит от входного параметра, который является элементом данных из последовательности, получаемой из метода ИЛеге () .
В приведенном ниже примере демонстрируется применение метода запроса СгоцрВу ( ) . Это измененный вариант представленного ранее примера. О Прадеманатриравать применение метода запроса Пгацрву(). /! Эта переработанный вариант примера, представленного ранее У/ для демонстрации синтаксиса запросов. ця1пч Буясе1п; ця1пч Яуяпеи.ьгид," 672 Часть (.
Язык С№ с1аяя ЯгопрВуоешо ( ягаг1с чоьй Маьп() ( ясггпст() неоя1гея = ( "ЬяншпеА.сои", "ЬянашеВ.пес", "Ьянашес.пес", ' "Ьяназео.соз", бЬянаиеЕ.огя", "Ьяназег.ого", ''Ьянашеп.кч", "Ьянатен.пег", "Ьяназе1.сч" ): // Использовать методы запроса для группирования // веб-пайтон по имени домена самого верхнего уровня. чаг меЬАс(с(гя = неЬя1сея.ХЬеге(и => н.ъаяс1поехот('.') != 1). Ягопрэу(х => х.зпоясг1по(х.ъаяс1поехог(".", х.ъепоГЬ))) !/ Выполнить запрос и вывести его результаты. гогеасЬ(чаг яьсея хп иеЬАс(с(гя) ( Сопяо1е.нгьгеъьпе("Веб-сайты, сгруппированные "по имени домена " -,'- аггея.кеу); гогеаоп(чаг яьпе ьп я1пея) Сопяо1е.иг1сеъ1пе(" " + яьсе); Сопяо1е. ХггсеъьпЕ () ) ) Эта версия программы дает такой же результат, как и предыдущая.
Единственное отличие между ними заключается в том, как формируется запрос. В данной версии для этой цели используются методы запроса. Рассмотрим другой пример. Но сначала приведем еще раз запрос из представленного ранее примера применения оператора и о1п. чаг гпзсосХЬьяс = гхоз 1сеш ьп ксеня по1п епггу гп ясагпяъьвс оп 1сез.1сееншпЬег ес)иа1я епсгу.тсезнпзЬег яе1есс пен теир(1гез.нате, еппгу.1пЯГоск) ) По этому запросу формируется последовательность, состоящая из обьектов, инкапсулирующих наименование товара и состояние его запасов на складе. Вся эта информация получается путем объединения двух источников данных: 1гешя и ягагпяЬ1зг. Ниже приведен переделанный вариант данного запроса, в котором вместо синтаксиса, предусмотренного в С)) для запросов, используется метод запроса Яо№п ( ) . Использовать метод запроса Зоьп() для составления списка /с' наименований товаров и состояния их запасов на складе.
чаг 1пзгоскъвяс = сгезя.ло1п(ясагпяъ1яс, )с1 => )с1.1сеспншпЬег, Х2 => Х2.1сеинпзоег, (Х1, )с2) => пеи Тешр(Х1.нате, )с2.1пзсос)с) В данном варианте именованный класс тешр используется для хранения результирующего объекта, но вместо него можно воспользоваться анонимным типом. Такой вариант запроса приведен ниже. чаг гпзсоскъгяс = 1сеия.со1п(вгаспяъгяг, Х1 => )с1.1сезншпЬег, Глава 19. МНО 673 «2 => «2.1«ехичпЬег, («1, «2) => и ( «).иа е, «2.)лагос«) ); Синтаксис запросов и методы запроса Как пояснялось в предыдущем разделе, запросы в С(г можно формировать двумя способами, используя синтаксис запросов или методы запроса.
Любопытно, что оба способа связаны друг с другом более тесно, чем кажется, глядя на исходный код программы. Дело в том, что синтаксис запросов компилируется в вызовы методов запроса. Поэтому код хкеге х < 10 будет преобразован компилятором в следующий вызов. Н)1еге (х => х < 10) Дополнительные методы расширения, связанные с запросами Помимо методов, соответствующих операторам запроса, поддерживаемым в С(Г, имеется ряд друптх методов расширения, связанных с запросами и зачастую оказывающих помощь в формировании запросов. Эти методы предоставляются в среде.)х)ЕТ Ргатпеттог)< и определены для интерфейса 1ЕпшлегаЬ1е<Т> в классе ЕппвгегаЬ1е.
Ниже приведены наиболее часто используемые методы расширения, связанные с запросами. Многие из них могут перегружаться, поэтому они представлены лишь в самой общей форме. Метод Описание А11(ргеП1саге) Возвращает логическое значение сгое, если все элементы в после- довательности удовлетворяют условию, задаваемому параметром рте с)уса Се Возвращает логическое значение с«ее, если любой элемент в по- следовательности удовлетворяет условию, задаваемому параметром ртеЖсасе Возвращает среднее всех значений в числовой последовательности Возвращает логическое значение ггое, если в последовательности содержится указанный объект Возвращает длину последовательности, т.е. количество составляющих ее элементов Возвращает первый элемент в последовательности Возвращает последний элемент в последовательности Возвращает максимальное значение в последовательности Возвращает минимальное значение в последовательности Возвращает сумму значений в числовой последовательности Апу (ртес)уса Се) Ачегагте () Сопга1пз (т~а1ие) Соопг() Етгзс () 1.аз« () Мах () М1п () Еогп () Таким образом, оба способа формирования запросов в конечном итоге сходятся на одном и том же.
Но если оба способа оказываются в конечном счете равноценными, то какой из них лучше для программирования на СФ? В целом, рекомендуется чаще пользоваться синтаксисом запросов, поскольку он полностью интегрирован в язык СФ, поддерживается соответствующими ключевыми словами и синтаксическим конструкциями. 674 Часть!. Язык С() Метод Соппс () уже демонстрировался ранее в этой главе. А в следующей программе демонстрируются остальные методы расширения, связанные с запросами. Использовать ряд методов расширения, определенных в классе ЕпсвегаЬ1е.
чя1пч Яуягев; пв1пч яуясев.ь1пй; с1аяя ЕхГМеслобя ( ягас1с чогб Маго() ( ьпг() ппвя = ( 3, 1, 2, 5, 4 )у Сопяо1е.йггсеЬьпе("Минимальное значение равно " т пива.М1п()); Сопяо1е.йгьсеЬгпе("Максимальное значение равно " + ппвя.Мах()); Сопяо1е.йггсеЬгпе("Первое значение равно " т ппвя.у1гяс()); сопяо1е.хг1геььпе("последнее значение равно " + ппвя.ьаяс()) Сопяо1е.йг1сеььпе("Суммарное значение равно " е пшпв.Яив())," Сопзо1е.иг1севьпе("Среднее значение равно " Е пчвя.лчегаче())1 11(пшпя.А11(п => и > О)) Сопяо1е.Хггсевьпе("Все значения больше нуля."); 11(ппвя.впу(п => (и $ 2) == О)) Сопяо1е.йггсеЬьпе("По крайней мере одно значение является четным.") гт(псвя.Сопсаьпя(3)) Сопяо1е.Хггсевьпе("Массив содержит значение 3."); Вот к какому результату приводит выполнение этой программы. Минимальное значение равно 1 Максимальное значение равно 5 Первое значение равно 3 Последнее значение равно 4 Суммарное значение равно 15 Среднее значение равно 3 Все значения больше нуля.