Добавил:
2200 7008 9480 6099 TKFF БЛАГОДАРНОСТЬ МОЖНО ТУТ ОСТАВИТЬ Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ДИПЛОМ 2025 / 4 курса_МТУСИ / 1 КУРС / Информатика / С# для чайников - Мюллер.pdf
Скачиваний:
0
Добавлен:
04.06.2025
Размер:
53.3 Mб
Скачать

Что же такое коллекция

Остановимся на минутку и сравним эту небольшую коллекцию с коллекци­ ей "аапен,х теinрассмотренной выше в главе. В то время как -Сапен-Стрnимеет сложную структуру узлов, связанных посредством указателей, приведенная простейшая коллекция месяцев основана на простом массиве с фиксирован­ ным содержимым. Но понятие коллекции оказывается существенно шире.

Ваш класс коллекции не обязан иметь фиксированное содержимое - боль­ шинство коллекций разработаны для хранения объектов путем добавления их в коллекции, например, с помощью метода гннnи иилиn чего-то в этом роде. Класс ьефенгл лофinк примеру, использует для добавления элементов в коллекцию ин­ дексатор. Ваша коллекция также должна обеспечивать метод гннnа и какi n и блок итератора, чтобы вы могли работать с ней с помощью цикла цдлеоучьn

Цель коллекции в наиболее общем смысле заключается в хранении мно­ жества объектов и обеспечении возможности их последовательного обхода по одному, хотя иногда может использоваться и произвольная выборка, как в де­ монстрационной программе .ане-елр(nКонечно, массив и так в состоянии спра­ виться с этим, без дополнительных "наворотов" наподобие класса лдаечмофтcn но итераторы вполне могут применяться и за пределами примера лда рччофтmяn

Говоря более обобщенно, независимо от того, что именно происходит за сценой, итерируемая коллекция генерирует "поток" значений, который мож­ но получить с помощью сдлеодчыЧтобыn лучше понимать данную концепцию, ознакомьтесь с еще одним примером простого класса из демонстрационной программы д щелощдлйгдуптекотn орый иллюстрирует чистую идею коллекции:

ц ц6

Uыхим1п3 имm­

:

цц

6 х\1имп3 имm

 

(rщ

 

(

 

 

("hё

и""x

;(={ (""и="Tи

("hё

и""x

hT

;

("hё

и""x

(;=

"=hh {

("hё

и""x

" ="

=иё

("hё

и""x

 

 

Коллекция зен аа:eчоа Атркакn ни странно, ничего не юiNт2e в обычном смысле этого слова. В ней нет даже массива. Так где же здесь коллекция? Она - в последовательности вызовов фlеконаерn :аВтnиспользующих специаль­ ный новый синтаксис для возврата элементов один за другим, пока все они не будут возвращены вызывающему методу. Эта коллекция "содержит" пять

ГЛАВА 7 Работа с коллекция ми 191

объектов, каждый из которых представляет собой простую строку, как и в рас­ смотренном только что примере MonthDays. Извне класса, в методе Main ( ) , вы можете итерировать эти объекты посредством простого цикла foreach, поскольку конструкция yield return возвращает по одной строке за раз. Вот часть метода Main ( ) , в которой выполняется итерирование "коллекции" StringChunks:

, ,

о

, wП

 

, ,

r

>

, ,

 

 

y

, ы

­ ы ,П

,

 

w

Г

,

Пу

Синтаксис итератора

В С# 2 .0 были введены два новых варианта синтаксиса итераторов. Кон­ струкция y i e l d r e t u rn больше всего напом и нает старую комб инацию MoveNext ( ) и Current для получения очередного элемента коллекции. Кон­ струкция yield break похожа на оператор break, который позволяет прекра­ тить работу цикла или конструкци и switch.

иtt­m Тtгж

Синтаксис yield return работает следующим образом.

д с Пре и первом вызове он возвращает первое значение коллекции. тежПри следующем вызове возвращается второе значение.

3. И так далее. . .

Это очень похоже на старый метод итератора MoveNext ( ) , использовавший­ ся в коде LinkedList. Каждый вызов MoveNext ( ) предоставляет новый элемент коллекции. Однако в данном случае вызов MoveNext ( ) не требуется.

Что же подразумевается под "следующим вызовом"? Давайте еще раз по­ смотрим на цикл foreach, использующийся для итерирования коллекции

StringChunks:

,

 

w

г

,

Т w

Каждый раз, когда цикл получает новый элемент посредством итератора, последний сохраняет достигнутую им позицию в коллекции. При очередной итерации цикла foreach итератор возвращает следующий элемент коллекции.

192 ЧАСТЬ 1 Основы программирования на С#

Следует упомянуть е ще об одном с интаксисе. Можно остановить ра­ боту итератора в определен ный момент, использовав в нем конструкцию yield break. Например, достигнут некоторый порог при тестировании опре­ деленного условия в блоке итератора класса коллекции и вы хотите на этом прекратить итерации. Вот краткий пример блока итератора, использующего yield break именно таким образом:

FF

,

 

 

FF

 

 

 

FF

i ­ a О г aгrcn л a r Un U a rUnП a rUnл c U п a r­nО г

FF

 

 

 

FF

,

,

) г

 

 

ь

 

 

ь

U О гааокжг

чмо.

аз FF

В рассмотрен ном случае блок итератора содержит оператор i f, который проверяет все простые числа, возвращаемые итератором (кстати, с примене­ нием еще одного цикла foreach внутри итератора). Если простое число пре­ вышает ] 3, в блоке выполняется инструкция yield break, которая прекращает возврат простых чисел итератором. В противном случае работа итератора про­ должалась бы и каждая инструкция yield return давала бы очередное простое число, пока коллекция полностью не исчерпалась бы.

СОВЕТ

СОВЕТ

Помимо использования в классах формальных коллекций для ре­ ализации перечисл ителей, любой из блоков итераторов в этой гла­ ве может быть написан как, например, статический метод в классе Program. Во м ногих случаях коллекция находится внутри метода. Такие коллекции специального назначен ия могут иметь много при­ менений и обычно создаются очень быстро и просто.

Можно также написать i u,Я чЕfту-ч ,-(врассматривается в час­ ти 2, "Объектно-ориентированное программирование на С#") для некоторого класса (или иного типа), который ведет себя, как блок итератора. Класс, который в определенном смысле может рассматри­ ваться как коллекция, может оказаться очень полезным.

оe юа юСдС Работа с коллекциями 193

Блоки итераторов произвольного вида и размера

и,

l.,.,

.,."

..- ..,..

..".-

.,...

...".

. ...."..,

..".

.....

,..-. ,.р

 

 

 

 

 

 

 

 

 

Р

 

 

 

..

 

 

 

 

 

 

 

 

 

 

 

 

6..-.

,

,..

.,. .. .....

.-.1 .

....."

1,..

. п

 

 

 

 

 

 

 

.3.....

...й

.n.... .... .

 

 

 

 

 

 

 

 

7..y7n. ...77..К

 

 

 

 

 

 

" ....

. ... . .. . .. . .. . ...

 

 

 

 

 

 

 

..".

.,

.,.,

..

,.. . . .-.1 ..

, .

..".-.,.- . . .

." ."

.,.-

. ..".".

и..

"., ...

. .

.,..,

.-...- .1

именоваю1ый итератор e

ронатртмакмвес

гетгичт

 

иыновaочст едсйr хeи­.йи сниедduее­ый тацй

мроснатu ее­ый мaвьо,

танавочтыотаеукеытиронtтирутaовее ­ыо оавио ч у.ра зонотыекменtонаттrанtт щещй.цир ч у,х еан.тыедвировттдвасначтронатттанавочтразонтисдакtкаменtсут ткутиновивамеыиутцоныrтц исоктантыотанаванаткыецоыиутмтдавуттотубывания

татыоталаванаттаыоцыанаткыецоыиубтм

тектеДтироыыатмтдавуттотяе о меыиуvткут

иновелавамтянатсягиотдяснутиNт

 

,,

 

з

 

_

,,

 

 

 

 

,,

 

 

 

 

оо , ,

 

)

ы

о o

,,

 

 

 

Г

,,,

,

б ы

 

 

екtекг

aнилог щ анииокленси tСесзолтtог

 

 

 

нои косWсИевоси

чеслглне ьгеслг илнетг

,,

 

 

,,

б

л O

 

, ,

- П

 

 

, ,

м

:

 

мо

м

ки

 

 

, ,

 

 

,,

 

с о г

,,

_

П OL

ы

П

o

.LТ O ы

П

194

21

41

444

641

4426 244

ЗАПОМНИ!

СОВЕТ

З!!

! !ЕТ";З="=!= В

ВВ!В А""!Н;!А! В!З!=! ;!З ;"В"В!

;"НЗН! ! В!ВВ!В

"";"З!ЕТ!П­!

 

="!НН="З="А"А =";!!!НН

"ВНН"

 

 

"=!З"=З" !

З! ЗВ"!ВВ!В "Н

 

 

 

;"

З!З=" А!

А="

"!= ;"

!;";!Н

!НЗВ! "В!ЕТ"=!А";

"НВН

ЗНН! =!=!;!!П !ЕТ"=!НЗ"

З!!

! !ЕТ";НЗ!Н!ПЗ!В

В!ВВ!В

"П! В!ВВ!В ""

=! !З!З!В

"З В!=!;ЗВ!ВВ!В

­"

!ЗВ

ЕТ"

!ЕТ;"!З="=!= П"

ЕТ";;

"В"!З А!П

Н!=А­Н;"

В!;!

А

З!=З="=!=!ЕТ!=!;НЗ=­!ЗНН=

З!А =!

!З!"З!="=!А"З

З"ВВ"ВА"= "ПВ"

!="НН ;"ЕТЗ="=!=ЗНН Н

" != ";! Н! НЗ";

ЕТ"=З; !ЕТ=";";

=

 

 

 

 

 

 

 

 

 

З!="З!=;! !ПН

";П

ЗВ!;!

;

=

"НН=!З="=НВ!ЕТ

"З"!="

З!= В!З!=

З=" "З=!НА! ЕТ"!З;!А!!

 

"НВ!

 

 

 

 

З! З! Н З"П!НВ!;! ; "В

=!

!З!

" !З!З!=!ЕТ"З ;"

 

!;"! В!З!=!! ЕТ!В

;!НЗ";!А­З"З!="

""

!ЗЗ="=!=З! ! В"В

 

=! ;! А А"З

 

!

 

А "ВВ!

А=!З!ЕТ!

ВНИМАНИВ

А!А З="А!ЕТ;!!; А

 

 

 

 

А З!В;Н!ЗНН";"В!

 

" ;! ЕТ!Н "!ЕТ;!З!В"

";!

З!З=!"

! ЕТ!НВ"А З!=!ЕТ"ЕТ­З!

 

АВ" !НЗА! =";" ; ;!

!З;

!

;" !;"Н !

! !ЕТ;! З="=!;!;"!

 

!З!="З!="

 

 

 

 

 

 

 

 

С

 

Н

 

 

 

И

 

 

 

 

 

М

 

 

 

 

 

 

 

!=

!"

=

=М ="!П

 

 

; ! ; ! = Н=

Этот вызов дает список четных ч исел от I О до 4. Обратите также внима­ ние на то, как используется цикл ниьпчл туВы должны инстанцировать объект Вбпаt щпьм(класс коллекции). Затем в инструкции ниьпчл т вызывается метод именованного итератора:

 

 

. r

 

 

.

,

.

.

r ( , -

 

 

. r

 

 

.

,

.

.

Кц ( ( -

Если бы ТпмлпзрозтВбпзм x kбыл статическим методом, можно было обойтись без экземпляра класса. В этом случае его можно было бы

вызвать с использованием имени класса, как обычно:

СОВЕТ

.

(

.

.

К , ) )

Поток идей для потоков обьектов

Теперь, когда вы можете сгенерировать "поток" четных чисел таким обра­ зом, подумайте о массе других полезных вещей, потоки которых вы можете по­ лучить с помощью аналогичных "коллекций" специального назначения: пото­ ки степеней двойки, членов арифметических или геометрических прогрессий, простых чисел или ч исел Фибоначчи - да что угодно. Как вам идея потока случайных чисел (чем, собственно, и занимается класс sчар ид, или сгенериро­ ванных случайным образом объектов?

Итерируемые свойства

 

Можно также реализовать блок итератора в в иде fN

fuNnкласса, кон­

кретнее - в методе доступа тпв x kсвойства. Вот простой класс со свойством Тикщлпgкитt Метод доступа тпа б дэтого класса работает как блок итератора, возвращающий поток значений типа рижчпc

F F

 

,

 

FF

 

 

 

ч

 

U ( P. ­ ( P . П ( г . а ( кл l

 

 

F F

<

я

д

 

,

,

 

 

.

 

К

iic

,ляs.

, дче оз ч ои обипт тви озпевo еп фa

Заголовок D o uЬ l e P r op пишется так же, как и заголовок метода DescendingEvens ( ) в примере именованного итератора. Он возвращает интер­ фейс IEnumeraЫe, но в виде свойства, не использует скобок после имени свой­ ства и имеет только метод доступа get ( ) , но не set ( ) . Метод доступа get ( ) реализован как цикл foreach, который итерирует коллекцию и применяет стан­ дартную инструкцию yield return для поочередного возврата элементов из коллекции чисел типа douЫe. Вот как это свойство можно использовать в ме­ тоде Main ( ) :

цц

u

 

я

,нхст ,х

 

\ хщ, сх

,хст, х

,хщтхстсх . им, ,хст,

х ­ щ,х

хсn тИ

цц

л,с

р

:им тхст к"с

{,, хст s

r,

-сх,щ(3

{,,

 

 

псимс{,

1eх:

,г:им,

n , as

 

 

 

 

Вы можете использовать тэтэb

д",хды ньд гыьт гх мыПодробнее они

 

рассмотрены в справочной системе, в разделе, посвященном приме­

СОВЕТ

нению итераторов.

 

 

 

ГЛАВА 7 Работа с коллекциями 197

О б о б ще н н о ст ь

В ЭТОЙ ГЛА В Е...

))

Обобщенны

й код - о

тлично

е решение

 

 

 

 

 

 

 

 

 

 

 

­

о

 

е ч2

))

 

 

 

гуух

Написание собственного обобщенного

класса

 

 

mn

 

з

 

 

 

)) Напис;:ан!llеобобщенных. методов

 

 

 

))

Использование обобщенных интерфейсов ·и делегатов

еероблема с коллекциями заключается в том, что вам нужно точно знать, что вы в них отправляете. Можете ли вы представить себе рецепт, ко­ торый допускает только точно перечисленные ингредиенты, и никакие другие? Никаких замен - ничто даже не может быть названо по-другому!

Именно так поступает большинство коллекций, но только не обобщенных. Как и в случае с рецептами в аптеке, вы можете сэкономить, выбрав уни­

версальную версию (дженерик)уикН­л­ llттлгeO вошла в язык в версии С# 2.0 и представляет собой классы, методы, интерфейсы и делегаты, являющиеся "форматированными бланками", которые заполняются затем действительными типами. Например, класс List<T> определяет обобщенный список, очень по­ хожий на старый необобщенный ArrayList, но гораздо лучше! Когда вы "вы­ таскиваете из раковины" List<T>, чтобы инстанцировать собственный список, например чисел типа int, то просто заменяете т на int:

г: :им( Sг г: з им, г: (:им н НS Wцц :им

укИгра слов: "generic" - "обобщенный класс"; еще один смысл слова "дженерик" - "лекарство-копия, которое совпадает с оригиналом по количеству действующего ве­ щества и влиянию на организм, обычно гораздо дешевле патентованных аналоmв". -

n( с цgтм) ц(я)

Соседние файлы в папке Информатика