Г. Шилдт - С#4.0 Полное руководство (1160795), страница 129
Текст из файла (страница 129)
яе1есс пеы ( Маве = 1сев.наве, 1пягосх = епсгу. 1пясосх )г Он возвращает объект анонимного типа с двумя доступными только для чтения свойствами: Мате и 1пэгосй. Этим свойствам присваиваются наименование товара и состояние его наличия на складе. Благодаря применению анонимного типа необходимость в упоминавшемся выше классе Тевр отпадает. Обратите также внимание на цикл Яогеас)Ь в котором выполняется запрос. Теперь переменная шага этого цикла объявляется с помощью ключевого слова уаг. Это необходимо потому, что у типа объекта, хранящегося в переменной ЯпБгосх11яс, нет имени.
Данная ситуация послужила одной из причин, по которым в С)) были внедрены неявно типизированные переменные, поскольку они нужны для поддержки анонимных типов. Прежде чем продолжить изложение, следует отметить еще один заслуживающий внимания аспект анонимных типов. В некоторых случаях, включая и рассмотренный выше, синтаксис анонимного типа упрощается благодаря применению ииициахизапгора проекции. В данном случае просто указывается имя самого инициализатора. Это имя автоматически становится именем свойства. В качестве примера ниже приведен другой вариант оператора яе1есг из предыдущей программы.
яе1есс пен ( ьсев.маве, епг су.1пясосх ); В данном примере имена свойств остаются такими же, как и прежде, а компилятор автоматически "проецирует" идентификаторы Маве и 1пэгос)с, превращая их в свойства анонимного типа. Этим свойствам присваиваются прежние значения, обозначаемые 1гев. Маве и епггу. 1пЯСоск соответственно. Создание группового объединения Как пояснялось ранее, оператор Япго можно использовать вместе с оператором я' о(.п для создания группового объединения, образующего последовательность, в которой каждый результат состоит из элементов данных из первой последовательности и группы всех совпадающих элементов из второй последовательности. Примеры группового объединения не приводились выше потому, что в этом объединении нередко применяется анонимный тип. Но теперь, когда представлены анонимные типы, можно обратиться к простому примеру группового объединения. В приведенном ниже примере программы групповое объединение используется для составления списка, в котором различные транспортные средства (автомашины, суда и самолеты) организованы по общим для них категориям транспорта: назем- Глава 19.
ЫМО 667 ного, морского, воздушного и речного. В этой программе сначала создается класс Тгапярогг, связывающий вид транспорта с его классификацией. Затем в методе Матп () формируются две входные последовательности. Первая из них представляет собой массив символьных строк, содержащих названия общих категорий транспорта: наземного, морского, воздушного и речного, а вторая — массив объектов типа ттапярогс, инкапсулирующих различные транспортные средства.
Полученное в итоге групповое объединение используется для составления списка транспортных средств, организованных по соответствующим категориям. // Продемонстрировать применение простого группового объединения. оятпэ Буягеьц оягпд Зуягеш.ьгпчг О Этот класс связывает наименование вида транспорта, // например поезда, с общей классификацией транспорта: // наземного, морского, воздушного или речного. стаяв Ттапяротт ( роытс яггьпч наше ( чегг яег; роЫьс яггьпч Нон ( Неги яегэ ) рпЫгс Тгапярогт(ятгтпч и, ягтгпс Ы Наше = и; Нон = Ы стаяв Стоорзолпоешо ( втатгс чогб Маго() ( // Массив классификации видов транспорта.
ятггпд[) Ггачегтурея = ( "Воздушный", "Морской", "Наземный", "Речной", О Массив видов транспорта. ттапярогг[) Сгапяротгя = ( пен Ттапярогт("велосипед", "Наземный" ), пен Тгапярогт("аэростат", "Воздушный" ), пен Тгапярогт("лодка", "Речной" ), пем тгапярогг("самолет", "Воздушный" ), пен Ттапярогт("каноэ", "Речной" ), пен Тгапяротт("биплан", "Воздушный" ), пен Тгапярогг("автомашина", "Наземный" ), пем Тгапяротт("судно", "Морской" ), пен Тгапярогт("поезд", "Назеыный") // Сфорыировать запрос, в котором групповое О объединение используется для составления списка 668 Часть ). Язык С№ // видов транспорта по соответствушшим категориям. чаг ЬуНон = Тгов Ьон гп Гтаче1Турев Зо1п тгапв 1п тгапврогтв оп Ьон ейпа1а стаяв.нон гпго 1вт ве1ест пен ( Нои = Ьон, Т11вт = 1вт ); // Выполнить запрос и вывести его результаты.
Гогеасб(чаг Г 1п ЬуНон) ( Сопво1е.шг1теьзпе("К категории <(0) транспорт> относится:", Ь.Нои); Гагеась(чаг в гп Г.Т11вт) Сопво1е.нгттеььпе(" " + в.Наше)~ Сопво1е.иггтеъ1пе(); ) Ниже приведен результат выполнения этой программы. К категории <Воздушньй транспорт> относится: аэростат самолет биплан К категории <Морской транспорт> относится: судно К категории <Наземный транспорт> относится: велосипед автомашина поезд К категории <Речной транспорт> относится: лодка каноэ Главной частью данной программы, безусловно, является следующий запрос. чат ЬуНои = Ггов Ьон тп Гтаче1Туреа 1огп гтапв тп ггапвроггв оп Ьон ейаа1в Ггапв.Нон 1пто 1вт.
ве1ест пен ( Нон = Ьон, Т1гвт = 1вт ); Этот запрос формируется следующим образом. В операторе Тгов используется переменная диапазона Ьоы для охвата всего массива Ьгаче1Турез. Напомним, что массив сгаче1турев содержит названия общих категорий транспорта; воздушного, наземного, морского и речного. Каждый вид транспорта объединяется в операторе 1огп со своей категорией.
Например, велосипед, автомашина и поезд объединяются с наземным транспортом. Но благодаря оператору 1псо для каждой категории транспорта в операторе з о та составляется список видов транспорта, относящихся к данной категории. Этот список сохраняется в переменной 1зс. И наконец, оператор зе1есс возвращает объект анонимного типа, инкапсулирующий каждое значение перемен- Глава 19. (1Н(1 669 Ь>геасп(чаг Г гп Ьув>н) Сопзо1е.игТСе(лпе("К категории <(О) транспорт> относится:", Г.вон); Гогеасп(наг и 1п Г.Т1гзс) Сопзп1е.нггсеъгпе(" " л и.капе); Сопзо1е.иг1<еъгпе О ) Во внешнем цикле получается объект, содержащий наименование общей категории транспорта, и список видов транспорта, относящихся к этой категории. А во внутреннем цикле выводятся отдельные виды транспорта.
Методы запроса Синтаксис запроса, описанный в предыдущих разделах, применяется при формировании большинства запросов в С(). Он удобен, эффективен и компактен, хотя и не является единственным способом формирования запросов. Другой способ состоит в использовании меягодав запроса, которые могут вызываться для любого перечислимого объекта, например массива. Основные методы запроса Методы запроса определяются в классе Яуасеы.
Е1пг(. ЕпппегаЬ1е и реализуются в виде лггнгодов ряс(и ирения функций обобщенной формы интерфейса ТЕпппге гаЬ1е<Т>. (Методы запроса определяются также в классе Буз Сепг. Елпц. С аегуаЬ1е, расширяющем функции обобщенной формы интерфейса 1опегуаЬ1е<Т>, но этот интерфейс в настоящей главе не рассматривается.) Метод расширения дополняет функции другого класса, но без наследования. Поддержка методов расширения была внедрена в версию СФ 3.0 и более подробно рассматривается далее в этой главе.
А до тех пор достаточно сказать, что методы запроса могут вызываться только для тех объектов, которые реализуют интерфейс 1ЕппвегаЬ1е<Т>. В классе ЕппнегаЬ1е предоставляется немало методов запроса, но основными считаются те методы, которые соответствуют описанным ранее операторам запроса. Эти методы перечислены ниже вместе с соответствующими операторами запроса. Следует, однако, иметь в виду, что эти методы имеют также перегружаемые формы, а здесь они представлены лишь в самой простой своей форме. Но именно эта их форма используется чаще всего. Оператор запроса Эквивалентный метод запроса ве1есс ипеге огс(егЬу Яе1есс(ае1ессог) Ыпеге(ргег(1саге) Огс)егВу()геуЯе1есгог) или Огг)егВупеасепг)109()геуЯе1есгог) 101п(1ппег, оигегкеуБе1есеог, ТппегКеузе1есгог, гегш10>е1есгог) Огопрну()геуЯе1есгог) Толп пгопр ной Ьои (категории транспорта) вмесге со списком видов транспорта.
Именно поэтому для вывода результатов запроса требуются два цикла Гогеасп. 670 часть (. язык С() За исключением метода Оо1п ( ), остальные методы запроса принимают единственный аргумент, который представляет собой объект некоторой разновидности обобщенного типа рипс<т, ткези1г>. Это тип встроенного делегата, объявляемый следующим образом: Ое1еэасе Тневи1Г Гипс<го Т, оиг Таеви1Г>(Т агэ) где Тйези1С обозначает тип результата, который дает делегат, а Т вЂ” тип элемента.
В методах запроса аргументы зе1ес с ос, ргес(уса Ге или )геуКе1ес Гог определяют действие, которое предпринимает метод запроса. Например, в методе ы)тесе () аргумент ргес(1 саге определяет порядок отбора данных в запросе. Каждый метод запроса возвращает перечислимый объект. Поэтому результат выполнения одного метода запроса можно использовать для вызова другого, соединяя эти методы в цепочку. Метод Ооз.п ( ) принимает четыре аргумента. Первый аргумент (Тппег) представляет собой ссылку на вторую объединяемую последовательность, а первой является последовательность, для которой вызывается метод .тоъп () . Селектор ключа для первой последовательности передается в качестве аргумента оисегКеуБе1ессог, а селектор ключа для второй последовательности — в качестве аргумента 1ппегКеуяе1ес Гол.
Результат объединения обозначается как аргумент гези1 гке1ессог. Аргумент оигегкеуке1есгог имеет тип Еипс<ТОисег, ТКеу>, аргумент уппегКеуяе1ессог — тип Гипс<Т1ппег, ТКеу>, тогда как аргумент гези1СКе1ессог — тип Гипс<ТОисег, ТТппег, Тйези1Г>, где ТОипе г — тип элемента из вызываЮщей последовательности; Т1ппег — тип элемента из передаваемой последовательности; Ткези1à — тип элемента из объединяемой в итоге последовательности, возвращаемой в виде перечислимого объекта.