Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 180
Текст из файла (страница 180)
Для того чтобы сохранить объекты определяемых пользователем классов в типизированной коллекции, придется воспользоваться классами обобщенных коллекций. В качестве примера ниже приведен переделанный вариант программы из предыдущего примера. В этом варианте используется класс обобщенной коллекции П1зг<Т>, а результат получается таким же, как и прежде. Глава 24.
Коллекции, леречнслигелн л итера)ори 893 пягпч Буясеи) иягпс Буягеи.со11есггопя.пепегтс) с1аяя 1пчепсогу ( ясггпч пате; бопвте сояг; гпс оппапби риЬ1>с Хпнепсогу(ясг100 и, бэпп|я с, гпс Ь) ( паве = и( сояг = с( оппяпб = (и ) рпЬ110 онеггтбе ясгтпч Тозсггпс() ( гесигп Бсггпс.Гоппас ("(О, -10 )Стоимостгы ( 1, б:С) Наличие: (2) ", пяте, пояс, оппяпс)л с1аяя Турезатегпнепсогуътяс ( ясасгс того Магп() ( ьтяг<хптепгогу> Хпт = пен ътяг<хптепгогу>() // добавить элементы в список. Хпч.лбб(пен Хптепсогу("Кусачки", 5.95, 3)); Хпн.АНЯпен Хптепсогу("Отвертки", 8.
29, 2) ) ) Хпн.лбб(пен Хптепсогу("Молотки", 3.50, 4))) Хпу.лсИ(пен Хптепсогу("дрели", 19.88, 8))' Сопяо1е.нгтсеьгпе("Перечень товарных запасов:"); Гогеясп((пуепсогу г гп Хпу) ( Сопяо1е.нгтсеь1пе(" " + 1); ) ) Данный пример отличается от предыдущего лишь передачей типа Хпуепсогу в качестве аргумента типа конструктору класса ьазг<Т>. А в остальном оба примера рассматриваемой здесь программы практически одинаковы.
Это, по существу, означает, что для применения обобщенной коллекции ие требуется никаких особых усилий, но при сохранении в такой коллекции объекта конкретного типа строго соблюдается типовая безопасность. Тем не менее для обоих примеров рассматриваемой здесь программы характерна еще одна особенность: они довольно кратки. Если учесть, что для организации динамического массива, где можно хранить, извлекать и обрабатывать данные товарных запасов, потребуется ие менее 40 строк кода, то преимущества коллекций сразу же становятся очевидными. Нетрудно догадаться, что рассматриваемая здесь программа получится длиннее в несколько раз, если попытаться закодировать все эти функции коллекции вручную. Коллекции предлагают готовые решения самых разных задач программирования, и поэтому их следует использовать при всяком удобном случае. 994 Часть!1. Библиотека С№ У рассматриваемой здесь программы имеется все же один не совсем очевидный недостаток: коллекция не подлежит сортировке.
Дело в том, что в классах йггауьфзс и ефзг<т> отсутствуют средства для сравнения двух объектов типа 1пчепгогу. но из этого положения имеются два выхода. Во-первых, в классе 1пчепгогу можно реализовать интерфейс 1соврагаЫе, в котором определяется метод сравнения объектов данного класса. И во-вторых, для целей сравнения можно указать объект типа 1Соврагег. Оба подхода рассматриваются далее по очереди.
Реализация интерфейса хсоврагаЬ1е Если требуется отсортировать коллекцию, состоящую из объектов определяемого пользователем класса, при условии, что они не сохраняются в коллекции класса яоггек(Ызг, где элементы располагаются в отсортированном порядке, то в такой коллекции должен быть известен метод сортировки содержащихся в ней объектов. С этой целью можно, в частности, реализовать интерфейс 1СоврагаЫе для объектов сохраняемого типа.
Интерфейс 1соврагаЬ1е доступен в двух формах: обобщенной и необобщенной. Несмотря на, сходство применения обеих форм данного интерфейса, между ними имеются некоторые, хотя и небольшие, отличия, рассматриваемые ниже. Реализация интерфейса 1СошраюаЬ1е для необобщенных коллекций Если требуется отсортировать объекты, хранящиеся в необобщенной коллекции, то для этой цели придется реализовать необобщенный вариант интерфейса 1СоврагаЫе.
В этом варианте данного интерфейса определяется только один метод, Соврагето (), который определяет порядок выполнения самого сравнения. Ниже приведена общая форма метода СоврагеТо () . ьпк СоврагеТо(оЬ№еск опу) В методе СоврагеТо () вызывающий объект сравнивается с объектом оЬой Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное— если значение вызывающего объекта больше, чем у объекта оЬя'; и отрицательное — если значение вызывающего объекта меньше, чем у объекта оЬЯЧ А для сортировки по убывающей можно обратить результат сравнения объектов.
Если же тип объекта оЬя' не подходит для сравнения с вызывающим объектом, то в методе СоврагеТо () может быть сгенерировано исключение йгдпвепгЕхсерс1оп. В приведенном ниже примере программы демонстрируется конкретная реализация интерфейса 1СоврагаЫе. В этой программе интерфейс 1СоврагаЫе вводится в класс 1пчепгогу, разработанный в двух последних примерах из предыдущего раздела. В классе 1пчепсогу реализуется метод СоврагеТо () для сравнения полей паве объектов данного класса, что дает возможность отсортировать товарные запасы по наименованию. Как показано в данном примере программы, коллекция объектов класса 1пчепгогу подлежит сортировке благодаря реализации интерфейса 1СоврагаЫе в этом классе. // Реализовать интерфейс 1СоврагаЬ1е.
плыло Яузсевк озала Яузсев.со11есс1опа; // Реализовать необобщенный вариант интерфейса 1СоирагаЫе. с1аяя 1пчепкогу: 1СоирагаЬ1е ( ясгапо паве; бопЫе совка гпк оппапбт рпЬ1гс 1пчепкогу(якг1по и, бопЬ1е с, гпк Ь) ( паве п) сояг = с) оппапб = Ьт ) рпЫ1с онегг1бе якгапо Тоакг1п9() ( гекигп Якг1пО.Гопвас("(0,-10)Стоимосты (1,5:С) Наличие: (2)", папе, сояк, оппапб)) ) // Реализовать интерфейс 1СоырагаЫе. рпЫгс Тпс СоэрагеТо(оЬ)есс оЬО) ( 1пчепкогу Ьт Ь (1пчепкогу) оЬОт гекигп паве.СоэрагеТо(Ь.папе)) ) с1аяя 1СоэрагаЬ1ебешо ( якак1с чо1б Маап() ( Аггауыавк апч = пен Аггау11як()т // Добавить элементы в список.
ГПЧ.Або(ПЕЫ 1ПЧЕПГОГу(еиуСаЧКИ", 5.95, 3))т 1пч.лоб(пен 1пчепкогу("Отвертки", 8.29, 2))) гпн.лоб(пеы тпнепсогу("Молотки", 3.50, 4))т 1пч.АсЫ(пеы 1пчепкогу("Дрели", 19.88, 8))' Сопяо1е.ыггкеаапе("Перечень Тогеасп(1пчепкогу 1 гл глч) Сопяо1е.иг1ке11пе(" ) Сопво1е.игаке11пе()т // Отсортировать список. Рпн.Яогг()т Сопяо1е.ыг1ке11пе("Перечень Тогеасп(1пчепкогу 1 гп гпч) Сопяо1е.игаке1гпе(" ) Рлаеа 24. Коллекции, леречислители и итераторы 895 товарных запасов ло сортировки:") ( 1) ) товарных запасов/после сортировки:"); ( 1) ) 896 Часть Н, Библиотека СЗ Ниже приведен результат выполнения данной программы.
Обратите внимание на то, что после вызова метода яогг () товарные запасы оказываются отсортированными по наименованию. Перечень товарных'запасов до сортировки: Стоимость: $5.95 Стоимость: $8.29 Стоимость: $3.50 Стоимость: $19.88 наличие: 3 Наличие: 2 Наличие: 4 Наличие: 8 Кусачки Отвертки Молотки Дрели Перечень Дрели Кусачки Молотки Отвертки товарных запасов после сортировки: Стоимость: $19.88 Наличие: 8 Стоимость: $5.95 Наличие: 3 Стоимость: $3.50 Наличие: 4 Стоимость: $8.29 Наличие: 2 Реализация интерфейса ХСотрахаЪ1е для обобщенных коллекций Если требуется отсортировать объекты, хранящиеся в обобщенной коллекции, то для этой цели придется реализовать обобщенный вариант интерфейса 1СощрагаЬ1е<Т>.
В этом варианте интерфейса 1сощрагаЬ1е определяется приведенная ниже обобщенная форма метода СощрагеТо () . ьпс СощрагеТо(Т оЬ3] // Реализовать интерфейс 1сощрагапте<Т>. пя1пч зуясещт ояьпч зуясещ.Со11есгьопя.Пепегьст // Реализовать обобщенный вариант интерфейса 1сощрагаЬ1е<Т>. с1аяя 1пчепсогу: 1сощрагаЬ1е<1пчепсогу> ( яггьпч паве; боппге сояст Тпс оппапбт риЬ11с 1пчепсогу(ясгьпч и, боиЬ1е с, ьпк и) паве = пт В методе Сощрагето () вызывающий объект сравнивается с объектом оЬу. Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное— если значение вызывающего объекта больше, чем у объекта оь3; и отрицательное — если значение вызывающего объекта меньше, чем у объекта ОЬ~. А для сортировки по убывающей можно обратить результат сравнения объектов.
При реализации обобщенного интерфейса 1СощрагаЬ1е<Т> имя типа реализующего класса обычно передается в качестве аргумента типа. Приведенный ниже пример программы является вариантом предыдущего примера, переделанным с целью реализовать и использовать обобщенный интерфейс 1СощрагаЬ1е<Т>. Обратите внимание на применение класса обобщенной коллекции Бтзс<т> вместо класса необобщенной коллекции йггаун1яг. Глава 24 Коллекции, перечислители и итераторы 897 созт = с) опЬапб = Ь; ) роЫгс очеттьбе зтг1пч Тоатгкпд() ( гетптп зтгкпо. Роппат (" ( О, -10 ]Стоиыосты ( 1, б: С) Наличие: ( 2 ) ", паве, созт, оппапб)( ) // Реализовать интерфейс 1СоырагаЫе<Т>. роЫгс Тпт СоырагеТо(1пчептогу оЬ3) ( гетпгп паве.СоырагеТо(оЬ).паве)) ) ) с1азз Оепег1с1СозрагаЬ1епезо ( зтатгс ноге Магп() ( ьгзт<1пчептоту> гпч = пем 1 Тзт<1пчептоту>() // Добавить элементы в список. гпч.або(пеы тпчептогу("Кусачки", 5.95, 3])( гпч.АсЫ(пеи 1п.нептогу("Отвертки", 8.29, 2))) гпн.ас(с((пеы Хпнептогу("Молотки", 3.50, 4))) гпн.ас(с((печ 1пнептоту("Дрели", 19.88, 8))) Сопзо1е.нгктеъфпе("Перечень товарных запасов ло сортировки:"); тогеасЬ(1пчептогу 1 Тп гпч) ( сопяо1е.игггеьхпе(" " т г) ) ) Сопзо1е.Игьтеъфпе (); // Отсортировать список.
гпч.зогт()( Сопзо1е.нгктеъ1пе("Перечень товарных запасов после сортировки:"); тогеасп(1пчептогу 1 1п гпч) ( Сопзо1е.игьтещпе (" " + г) ) ) ) ) Эта версия программы дает такой же результат, как и предыдущая, необоощенная версия. Применение интерфейса 1Сотрахет Для сортировки объектов определяемых пользователем классов зачастую проще всего реализовать в этих классах интерфейс 1СоырагаЫе. Тем не менее данную задачу можно решить и с помощью интерфейса 1Соырагет. Для этой цели необходимо сначала создать класс, реализующий интерфейс 1Соырагег, а затем указать объект этого класса, когда потребуется сравнение.