За сценой цикл 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 i n 1 1 c ) |
/ / f o r e a c h в ы п о л н я е т |
{ |
/ / п р и в е д е н и е т и п о в |
C o n s o l e . W r i t e L i n e ( s ) ; |
|
} |
|
Обобщенная версия связанного списка из этой главы с блоком итератора ис пользована в демонстрационной программе 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 , |
н о с а м и т е р а т о р р е а л и з у е т с я с и с п о л ь з о в а н и е м |
/ / |
б л о к а и т е р а т о р а |
|
|
u s i n g |
S y s t e m ; |
|
|
|
u s i n g |
S y s t e m . C o l l e c t i o n s ; |
|
|
n a m e s p a c e |
I t e r a t o r B l o c k l t e r a t o r |
|
{ |
|
|
|
|
|
|
|
c l a s s |
P r o g r a m |
|
|
|
{ |
|
|
|
|
|
|
/ / С о з д а н и е к о л л е к ц и и и и с п о л ь з о в а н и е д в у х о б ъ е к т о в |
|
/ / и т е р а т о р а д л я н е з а в и с и м о г о и т е р и р о в а н и я |
( к а ж д ы й |
|
/ / |
и с п о л ь з у е т б л о к и т е р а т о р а ) |
|
|
s t a t i c |
v o i d |
M a i n ( s t r i n g [ ] |
a r g s ) |
|
|
{ |
|
|
|
|
|
|
s t r i n g [ ] |
s t r s = n e w s t r i n g [ ] |
|
482 |
Часть VII. Дополнительные главы |
{ " J o e " , " B o b " , " T o n y " , " F r e d " } ; M y C o l l e c t i o n m c = n e w M y C o l l e c t i o n ( s t r s ) ;
/ / С о з д а н и е п е р в о г о и т е р а т о р а и н а ч а л о и т е р а ц и й M y C o l l e c t i o n l t e r a t o r m c i l = m c . G e t E n u m e r a t o r ( ) ;
f o r e a c h ( s t r i n g s i i n m c i l ) / / П е р в ы й и т е р а т о р
/ / К а к а я - т о р а б о т а с о с т р о к а м и C o n s o l e . W r i t e L i n e ( s i ) ;
/ / Ищем б о с с а Т о н и i f ( s i = = " T o n y " )
{
/ / В с р е д и н е э т о й и т е р а ц и и н а ч и н а е м н о в у ю с / / и с п о л ь з о в а н и е м в т о р о г о и т е р а т о р а
M y C o l l e c t i o n l t e r a t o r m c i 2 = m c . G e t E n u m e r a t o r ( ) ;
f o r e a c h ( s t r i n g s 2 i n m c i 2 ) |
/ / В т о р о й и т е р а т о р |
|
/ / Р а б о т а с о с т р о к а м и |
|
|
|
i f ( s 2 = = " B o b " ) |
|
|
|
{ |
|
|
|
C o n s o l e . W r i t e L i n e ( " \ t { 0 } |
- б о с с { l } " , |
s 2 , |
s i ) ; |
}}
}
}
/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я
C o n s o l e . W r i t e L i n e ( " Н а ж м и т е < E n t e r > д л я " +
" з а в е р ш е н и я п р о г р а м м ы . . . " ) ;
C o n s o l e . R e a d ( ) ;
}}
/ / П р о с т а я к о л л е к ц и я с т р о к p u b l i c c l a s s M y C o l l e c t i o n
{
/ / Р е а л и з а ц и я к о л л е к ц и и с и с п о л ь з о в а н и е м / / 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 = n e w A r r a y L i s t ( ) ; p u b l i c M y C o l l e c t i o n ( s t r i n g [ ] s t r s )
A r r a y L i s t м о г у т
f o r e a c h ( s t r i n g s i n s t r s )
{
l i s t . A d d ( s ) ;
}
}
/ / G e t E n u m e r a t o r - к а к и в L i n k e d L i s t , в о з в р а щ а е т о д и н / / и з о б ъ е к т о в и т е р а т о р о в
p u b l i c M y C o l l e c t i o n l t e r a t o r G e t E n u m e r a t o r ( )
{
r e t u r n n e w M y C o l l e c t i o n l t e r a t o r ( t h i s ) ;
}
}
/ / M y C o l l e c t i o n l t e r a t o r - к л а с с и т е р а т о р а д л я M y C o l l e c t i o n p u b l i c c l a s s M y C o l l e c t i o n l t e r a t o r
Глава 20. Работа с коллекциями |
483 |
|
/ / Х р а н и м с с ы л к у н а к о л л е к ц и ю |
|
|
p r i v a t e |
M y C o l l e c t i o n m c ; |
|
|
p u b l i c |
M y C o l l e c t i o n l t e r a t o r ( M y C o l l e c t i o n |
mc) |
|
{ |
|
|
|
|
|
t h i s . m c |
= mc,- |
|
|
|
} |
|
|
|
|
|
/ / G e t E n u m e r a t o r - б л о к и т е р а т о р а , к о т о р ы й в ы п о л н я е т |
|
/ / р е а л ь н ы е и т е р а ц и и д л я о б ъ е к т а и т е р а т о р а |
|
p u b l i c |
S y s t e m . C o l l e c t i o n s . I E n u m e r a t o r G e t E n u m e r a t o r ( ) |
|
{ |
|
|
|
|
|
/ / И т е р и р у е м с п и с о к с в я з а н н о й к о л л е к ц и и , к о т о р ы й |
|
/ / д о с т у п е н , п о т о м у ч т о о б ъ я в л е н к а к i n t e r n a l |
|
f o r e a c h |
( s t r i n g s |
i n m c . l i s t ) |
|
|
{ |
|
|
|
|
|
y i e l d r e t u r n s ; |
/ / С е р д ц е б л о к а и т е р а т о р а |
} |
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
Коллекция |
в |
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 .
/ / G e t E n u m e r a t o r - к а к и в L i n k e d L i s t , в о з в р а щ а е т о д и н / / и з о б ъ е к т о в и т е р а т о р о в
p u b l i c M y C o l l e c t i o n l t e r a t o r G e t E n u m e r a t o r ( )
{
r e t u r n n e w M y C o l l e c t i o n l t e r a t o r ( t h i s ) ;
}
Однако внутри самого класса итератора все гораздо интереснее. Он также содержит метод 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 - б л о к и т е р а т о р а , к о т о р ы й в ы п о л н я е т / / р е а л ь н ы е и т е р а ц и и д л я о б ъ е к т а и т е р а т о р а
p u b l i c S y s t e m . C o l l e c t i o n s . I E n u m e r a t o r G e t E n u m e r a t o r ( )
{
/ / |
И т е р и р у е м с п и с о к с в я з а н н о й к о л л е к ц и и , к о т о р ы й |
/ / |
д о с т у п е н , п о т о м у ч т о о б ъ я в л е н к а к i n t e r n a l |
f o r e a c h |
( s t r i n g s |
i n m c . l i s t ) |
{ |
|
|
y i e l d r e t u r n s ; |
/ / С е р д ц е б л о к а и т е р а т о р а |
} |
|
|
}
Данный метод имеет доступ к 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
для первого, что позволяет получить вывод программы наподобие приведенного: J o e
B o b T o n y
484 |
Часть VII. Дополнительные главы |
B o b - б о с с Tony-
F r e d / / • - •
Строка с отступом выводится вложенной итерацией.
Вот как выглядят эти вложенные циклы в функции M a i n ( ) : M y C o l l e c t i o n l t e r a t o r m c i l = m c . G e t E n u m e r a t o r ( ) ;
f o r e a c h ( s t r i n g s i i n m c i l ) / / П е р в ы й и т е р а т о р
/ / К а к а я - т о р а б о т а с о с т р о к а м и C o n s o l e . W r i t e L i n e ( s i ) ;
/ / Ищем б о с с а Т о н и i f ( s i = = " T o n y " )
{
/ / В с р е д и н е э т о й и т е р а ц и и н а ч и н а е м |
н о в у ю с |
/ / и с п о л ь з о в а н и е м в т о р о г о и т е р а т о р а |
|
M y C o l l e c t i o n l t e r a t o r m c i 2 = m c . G e t E n u m e r a t o r ( ) ; |
f o r e a c h ( s t r i n g s 2 i n m c i 2 ) |
/ / В т о р о й и т е р а т о р |
/ / Р а б о т а с о с т р о к а м и |
|
i f ( s 2 = = " B o b " ) |
|
{ |
|
C o n s o l e . W r i t e L i n e ( " \ t { o } |
- б о с с { l } " , s 2 , s i ) ; |
}
}
}
Впрочем, исходный итератор, с M o v e N e x t () и C u r r e n t , все равно остается более
гибким и простым...
Глава 20. Работа с коллекциями |
485 |
Г л а в а 2 1
Использование интерфейса Visual Studio
>Использование инструментария Visual Studio
>Настройка рабочего места
>Отладка программ
стественно, для работы необходимо знание языка. Программист на С#, не знающий С# — нонсенс. Однако важно также знать и используемый инструментарий — в ча стности, пользовательский интерфейс пакета Visual Studio, который вы, вероятно,
применяете в работе. В этой главе речь пойдет о том, как работать с Visual Studio. Материал настоящей главы применим ко всем редакциям Visual Studio 2005, включая
Visual С# Express. Большая часть времени при работе над консольными приложениями из этой книги была потрачена на работу со следующими четырьмя окнами Visual Studio:
Solution Explorer и Class View;
Editor;
Help;
Debugger.
Эти окна перечислены в "хронологическом" порядке, а не в порядке важности. Когда вы пишете большую программу, вы работаете с окном Solution Explorer, а затем вводите исходный текст С# в окне редактора, все время пользуясь окном справки, а также окнами Solution Explorer или Class View. После того как вы ввели программу, вы ищете ошиб ки в ней в окне отладчика. Пару раз в месяц вы обращаетесь еще к одному окну, за кото рым сидит кассир, но это окно не относится к Visual Studio.
Перед тем как приступить к работе, обычно настраивается расположение окон так, чтобы это было удобно программисту.
Разработка графических приложений Windows включает ряд дополнительных
окон: Form Designer, Toolbox и Properties. Вкратце о них было рассказано
в главе 1, "Создание вашей первой Windows-программы на С#".
Visual Studio организует свои различные инструменты в окна для лучшего использо вания наиболее ограниченного компьютерного ресурса — экрана монитора.
Состояния окон
Окно может находиться в одном из четырех состояний.
Закрытое (Closed) Свободное (Floating) Закрепленное (Docked) Свернутое (Tabbed)
Эти состояния описаны в следующих разделах.
Закрытое окно
Закрытое окно — это окно, убранное с экрана. Единственный способ увидеть его в н о в ь — воспользоваться подменю View, как показано на рис. 21.1. Наиболее часто ис пользуемые окна перечислены в середине меню View; менее распространенные - в подменю V i e w ^ O t h e r Windows . Некоторые отладочные окна доступны только из ме ню Debug в режиме отладки.
Свободные окна
Свободное окно выглядит парящим над рабочим столом 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 закреплено в верхнем правом углу, а окно Error List — в нижней части окна. Перемещая границу между двумя окнами, вы автоматически изменяете размеры каждого из окон.
Свернутое окно
Скрытые закрепленные окна, или, говоря более точно, минимизированные, выглядят как тонкие закладки, закрепленные на внешних границах окна Visual Studio. На рис. 21,3 показаны окна Solution Explorer и Class View, свернутые в закладки у правой границы окна Visual Studio.
Разместите курсор мыши над такой закладкой, чтобы развернуть окно. Чтобы оно ос талось в таком состоянии, воспользуйтесь кнопкой в правой верхней части окна с изо бражением канцелярской кнопки или оставьте его в автоматически скрываемом состоя нии, что бывает удобным, но, правда, далеко не всегда.
488 |
Часть VII. Дополнительные глав |
Рис. 21.1. Подменю View позволяет открыть все необходимые окна
Puc. 21.2. Свободное окно выглядит независящим от Visual Studio
Шва 21. Использование интерфейса Visual Studio |
489 |
Рис. 27.5. Основные окна Visual Studio
Щелчок правой кнопкой мыши на заголовке открытого окна позволяет изме нить его состояние— сделать его свободным, закрепленным, свернутым или скрытым.
Скрытие окна
Независимо от установок, большинство открытых окон имеют маленькую кнопку с изображением канцелярской кнопки (чтобы не говорить "кнопка" дважды, далее речь пойдет просто о канцелярской кнопке) рядом с кнопкой закрытия окна в его полосе заго ловка. Такую канцелярскую кнопку вы можете увидеть у окна Output на рис. 21.3, где показаны несколько основных окон Visual Studio. Щелкните на этой канцелярской кноп ке, и окно будет скрываться с ваших глаз, когда будет становиться ненужным. Это свой ство называется автоскрытием (auto-hide).
Поднятое состояние канцелярской кнопки означает закрепленное и заблокированное окно. Опущенная канцелярская кнопка указывает, что окно не заблокировано и будет ав томатически скрываться, когда вы покидаете его.
Скрытое окно остается открытым (и его можно видеть в виде закладки ). Все на стройки, которые действовали, пока окно находилось в открытом состоянии, продолжа ют действовать и в скрытом состоянии.
Перестановка окон
Вы можете разместить окна так, как вам кажется более удобным. Возьмите окно за полосу заголовка и переместите в другое место. При перетаскивании появится се рое изображение окна, указывающее, где окно будет закреплено, если вы перенесете его в это место. На рис. 21.4 показано то же окно Visual Studio, что и на рис. 21.3, после того как окно Output было перемещено для закрепления в верхней части окна Visual Studio.
490 |
Часть VII. Дополнительные главы |
При перемещении окна можно использовать "направляющий ромб" в центре с че тырьмя стрелками, направленными в разные стороны от центра.
Рис. 21.4. Закрепленное окно можно перезакрепить в новом месте
Для того чтобы перетащить окно, его нужно взять за полосу заголовка, перенести к рамке, за которую вы хотите его закрепить, переместить указатель мыши на направ ляющую стрелку для этой стороны и отпустить его. Окно будет закреплено в данной по зиции, если вы отпустите кнопку мыши над направляющей стрелкой (одной из централь ного ромба или ее дубля у края о к н а — на рис. 21.4 указатель мыши находится как раз над таким дублем).
Расстановка окон — увлекательное занятие, чем-то похожее на игру (можно при этом вспомнить знаменитый кубик Рубика). Вам может потребоваться подправить несколько окон, чтобы достичь желаемого эффекта. Например, начав с конфигурации, показанной на рис. 21.3, вы можете перенести окно Output к левой границе, а окно Error List сместить в нижний правый угол, как показано на рис. 21.5. Чтобы окно Error List было закреплено у всей нижней границы окна Visual Studio, закрепите его за нижнюю рамку (на рис. 21.6 показана данная конфигурация). Экспериментируйте, пока не полу чите устраивающий вас результат.
Наложение окон
Перетаскивание и отпускание окна на центральном квадрате направляющего ромба позволяет складывать окна в "стопку" (центральная пиктограмма играет роль своеобраз ного клея). Каждое окно в такой стопке доступно при щелчке на вкладке, которая может быть вверху или внизу окна. На рис. 21.7 показана стопка окон редактирования, состоя щая и з трех о к о н — для файлов U n i v e r s i t y . c s , S t u d e n t , c s и P r o g r a m , c s . Двойной щелчок на имени файла в Solution Explorer (о нем чуть позже) откроет окно с этим файлом так, что оно окажется верхним в стопке.
Глава 21. Использование интерфейса Visual Studio |
491 |
Рис. 21.5. Чтобы получить данную конфигурацию окон из конфигурации на рис. 21.3, требуется два шага. Еще один шаг— и вы получите конфигурацию, показанную на рис. 21.6
Рис. 21.6. Последовательное закрепление окон позволяет достичь желаемой конфигурации
492 |
Часть VII. Дополнительные главы |