1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 95
Текст из файла (страница 95)
Работа с коллекциями481За сценой цикл f o r e a c h выполняет за вас необходимые приведения. Так что есливы храните в списке строки s t r i n g , ваш цикл f o r e a c h ищет именно их:f o r e a c h ( s t r i n g s in 11c){Console.WriteLine(s);////foreach выполняетприведение типов}Обобщенная версия связанного списка из этой главы с блоком итератора использована в демонстрационной программе G e n e r i c L i n k e d L i s t C o n t a i n e r на прилагаемом компакт-диске. В этой демонстрационной программе инстанцируется обобщенный класс L i n k e d L i s t для объектов типаs t r i n g , а затем — типа i n t . Чтобы лучше понять, как все это работая,стоит пошагово пройти цикл f o r e a c h в отладчике. Для сравнения вы можете познакомиться с новым встроенным классом L i n k e d L i s t < T > в пространстве имен S y s t e m .
C o l l e c t i o n s . G e n e r i c .Советую вам при работе полностью забыть о мире необобщенных коллекций — за исключением старого доброго массива, который может оказатьсяполезен и при этом безопасен с точки зрения типов. Воспользуйтесь лучшеобобщенными коллекциями. Правда, лично я собираюсь не следовать этому^совету уже в следующем разделе...Осталось еще немного...Реализация исходного итератора в L i n k e d L i s t реализует итератор как отдельныйкласс, спроектированный для работы с классом L i n k e d L i s t . У такого решения естьодна привлекательная возможность, которая отсутствует у решения с использованиемблока итератора.
Вы можете легко создать несколько экземпляров итераторов и применять каждый из них независимо от других. Так что i t e r a t o r l может пройти полпути,когда i t e r a t o r 2 только начинает обход.Последняя демонстрационная программа решает этот вопрос (хотя и для болеелее простой коллекции, не L i n k e d L i s t ) . I t e r a t o r B l o c k l t e r a t o r использует объект итератора с доступом к внутреннему устройству коллекции,но сам этот объект реализован с применением блока итератора.// I t e r a t o r B l o c k l t e r a t o r - реализует отдельный объект// и т е р а т о р а для работы с классом коллекции, типа// L i n k e d L i s t , но сам и т е р а т о р р е а л и з у е т с я с использованием// блока итератораusing System;usingSystem.Collections;namespaceIteratorBlocklterator{classProgram{//////sta{s482Создание коллекции и использование двухитератора для независимого итерированияиспользует блок итератора)t i c void Main(string[]args)t r i n g []strs=newобъектов(каждыйs t r i n g []Часть VII.
Дополнительные главы{"Joe","Bob","Tony","Fred"};M y C o l l e c t i o n mc = new M y C o l l e c t i o n ( s t r s ) ;// Создание первого итератора и начало итерацийMyCollectionlterator mcil = mc.GetEnumerator();foreach(string si in mcil)/ / Первый и т е р а т о р// Какая-то работа соConsole.WriteLine(si);/ / Ищем б о с с а Т о н иi f ( s i == "Tony")строками{/ / В средине э т о й и т е р а ц и и начинаем новую с// использованием второго итератораM y C o l l e c t i o n l t e r a t o r mci2 = m c . G e t E n u m e r a t o r ( ) ;foreach(string s2in mci2)// Второй итератор//Работаif(s2==состроками"Bob"){Console.WriteLine("\t{0}}}-босс{l}",s2,s i ) ;}}/ / Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для " +"завершения программы..
. " ) ;Console.Read();}}//ПростаяpublicколлекцияclassстрокMyCollection{// Реализация коллекции с использованием A r r a y L i s t// i n t e r n a l- так что объекты итераторов могут// о б р а щ а т ь с я к с т р о к а мi n t e r n a l A r r a y L i s t l i s t = new A r r a y L i s t ( ) ;publicMyCollection(string[]strs)foreach(stringsinstrs){list.Add(s);}}////GetEnumerator - как и виз объектов итераторовpublicMyCollectionlteratorLinkedList,возвращаетодинGetEnumerator(){returnnewMyCollectionlterator(this);}}// M y C o l l e c t i o n l t e r a t o r - класс итератораpublicclassMyCollectionlteratorГлава 20. Работа с коллекциямидляMyCollection483// Храним ссылку на коллекциюp r i v a t e M y C o l l e c t i o n mc;publicMyCollectionlterator(MyCollectionmc){this.mc=mc,-}// G e t E n u m e r a t o r - блок итератора,который выполняет// реальные итерации для объекта итератораpublicSystem.Collections.IEnumerator GetEnumerator(){//Итерируемсписоксвязанной//доступен,потомучтоforeach(stringsinколлекции,объявленкаккоторыйinternalmc.list){yield}returns;//Сердцеблокаитератора}} }Коллекция вI t e r a t o r B l o c k l t e r a t o r представляет собой простой класс-оболочку вокруг класса A r r a y L i s t .
Его метод G e t E n u m e r a t o r ( ) просто возвращаетновый экземпляр сопутствующего класса итератора, такого же, как для L i n k e d L i s t .////GetEnumerator - как и виз объектов итераторовpublicLinkedList,MyCollectionlteratorвозвращаетодинGetEnumerator(){returnnewMyCollectionlterator(this);}Однако внутри самого класса итератора все гораздо интереснее. Он также содержитметод G e t E n u m e r a t o r ( ) . Реализованный с применением блока итератора, он выполняет всю работу по итерированию. Вот этот метод:// G e t E n u m e r a t o r - блок итератора,который выполняет// реальные итерации для объекта итератораpublicSystem.Collections.IEnumerator GetEnumerator(){//Итерируемсписоксвязанной//доступен,потомучтоforeach(stringsinколлекции,объявленкаккоторыйinternalmc.list){yieldreturns;//Сердцеблокаитератора}}Данный метод имеет доступ к A r r a y L i s t из сопутствующей'коллекции, так что егоинструкция y i e l d r e t u r n может поочередно возвращать хранимые в коллекции строкиВыигрыш от этих сложностей концентрируется в функции M a i n ( ) , где создаются двекопии объекта итератора.
Цикл f o r e a c h для второго итератора вложен в цикл f o r e a c hдля первого, что позволяет получить вывод программы наподобие приведенного:JoeBobTony484Часть VII. Дополнительные главыBob-боссTony-Fred//• - •Строка с отступом выводится вложенной итерацией.Вот как выглядят эти вложенные циклы в функции M a i n ( ) :MyCollectionlteratorforeach(stringsiinmcil=mcil)// Какая-то работа соConsole.WriteLine(si);/ / Ищем б о с с а Т о н иi f ( s i == "Tony")mc.GetEnumerator();//Первыйитераторстроками{/ / В средине э т о й и т е р а ц и и начинаем новую с// использованием второго итератораM y C o l l e c t i o n l t e r a t o r mci2 = m c .
G e t E n u m e r a t o r ( ) ;foreach( s t r i n g s2 in mci2)// Второй итератор// Работа со строкамиi f ( s 2 == "Bob"){Console.WriteLine("\t{o}}-босс{l}",s2,s i ) ;}}Впрочем, исходный итератор, с M o v e N e x t () и C u r r e n t , все равно остается болеегибким и простым...Глава 20. Работа с коллекциями485Глава 21Использование интерфейса Visual Studio>Использование инструментария Visual Studio>Настройка рабочего места>Отладка программстественно, для работы необходимо знание языка.
Программист на С#, не знающийС# — нонсенс. Однако важно также знать и используемый инструментарий — в частности, пользовательский интерфейс пакета Visual Studio, который вы, вероятно,применяете в работе. В этой главе речь пойдет о том, как работать с Visual Studio.Материал настоящей главы применим ко всем редакциям Visual Studio 2005, включаяVisual С# Express. Большая часть времени при работе над консольными приложениямииз этой книги была потрачена на работу со следующими четырьмя окнами Visual Studio:Solution Explorer и Class V i e w ;Editor;Help;Debugger.Эти окна перечислены в "хронологическом" порядке, а не в порядке важности. Когдавы пишете большую программу, вы работаете с окном Solution Explorer, а затем вводитеисходный текст С# в окне редактора, все время пользуясь окном справки, а также окнамиSolution E x p l o r e r или C l a s s V i e w .
После того как вы ввели программу, вы ищете ошибки в ней в окне отладчика. Пару раз в месяц вы обращаетесь еще к одному окну, за которым сидит кассир, но это окно не относится к Visual Studio.Перед тем как приступить к работе, обычно настраивается расположение окон так,чтобы это было удобно программисту.Разработка графических приложений Windows включает ряд дополнительныхокон: F o r m Designer, T o o l b o x и Properties. Вкратце о них было рассказанов главе 1, "Создание вашей первой Windows-программы на С # " .Visual Studio организует свои различные инструменты в окна для лучшего использования наиболее ограниченного компьютерного ресурса — экрана монитора.Состояния оконОкно может находиться в одном из четырех состояний.Закрытое (Closed)Свободное (Floating)Закрепленное (Docked)Свернутое (Tabbed)Эти состояния описаны в следующих разделах.Закрытое окноЗакрытое окно — это окно, убранное с экрана.
Единственный способ увидеть егов н о в ь — воспользоваться подменю V i e w , как показано на рис. 21.1. Наиболее часто используемые окна перечислены в середине меню V i e w ; менее распространенные в подменю V i e w ^ O t h e r W i n d o w s . Некоторые отладочные окна доступны только из меню D e b u g в режиме отладки.Свободные окнаСвободное окно выглядит парящим над рабочим столом Visual Studio, как показанона рис. 21.2. Свободное окно не является совершенно независимым. Например, его нельзя минимизировать или разместить за главным окном, но зато можно поместить "за пределами" окна Visual Studio, эффективно расширяя рабочий стол последнего.Каждый режим Visual Studio имеет собственные настройки.
У вас может бытьодно расположение окон в режиме разработки программы, когда вы редактируете ее исходный текст и компилируете ее, и другое в режиме отладки, как будет описано позже в этой главе.Закрепленное окноВы можете закрепить практически любое окно, выбрав его и воспользовавшись командой W i n d o w ^ D o c k a b l e . Закрепленное окно "хватается" за другое окно или рамкуглавного окна Visual Studio. Это состояние сохраняется и при изменении размеров окнаVisual Studio — закрепленные окна цепко держатся за границы основного окна и изменяют свои размеры вместе с ним.На рис. 21.3, например, окно Output закреплено в верхнем правом углу, а окно ErrorList — в нижней части окна.
Перемещая границу между двумя окнами, вы автоматическиизменяете размеры каждого из окон.Свернутое окноСкрытые закрепленные окна, или, говоря более точно, минимизированные, выглядяткак тонкие закладки, закрепленные на внешних границах окна Visual Studio. На рис. 21,3показаны окна Solution E x p l o r e r и C l a s s V i e w , свернутые в закладки у правой границыокна Visual Studio.Разместите курсор мыши над такой закладкой, чтобы развернуть окно.
Чтобы оно осталось в таком состоянии, воспользуйтесь кнопкой в правой верхней части окна с изображением канцелярской кнопки или оставьте его в автоматически скрываемом состоянии, что бывает удобным, но, правда, далеко не всегда.488Часть VII. Дополнительные главРис. 21.1. Подменю View позволяет открыть все необходимые окнаPuc. 21.2. Свободное окно выглядит независящим от Visual StudioШва 21.