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

Диапазон значени й byte - от О до 255, или OxFF, т.е. двух шестнадцатерич­ ных цифр для вывода одного байта достаточно. Вот как выглядят первые 20 строк при выводе содержимого файла output . txt.

OOU B OO­ B OOОгB O O а B OOг B OOк B OOл , OOн B OOоm1, OUO B O U Uц O U ­ ( O U ОгB OU а ( O U г B O U к B O U л т OU н B O U о mV1 O ­ O .

 

 

 

 

т

 

 

 

 

,

 

 

 

 

 

 

 

 

гОг arnл а a rтnк

ек кг arnк Uarnк

arn­ O a r n­ н a rлn

O a rлn

­ a r n

к arnл а a rкгn

arnкОглarnа a rкгn

arnкаarn­ о m 1Oa r narnПtл6

­ Oarn­ O a r nа к a rкn

о m 1кa r n arnкгarnгОгarnл а a rлn

­ a r nк г a r n

к Ua rкn

 

arn­ н a rлn

 

 

 

ко

m1arnк arnклarn

­

arn

 

О г aлrаna rлn ­ a r n

 

 

­ Oarnак arnкоm1arnк arnкг arnа

arnк

 

 

arnкаarnкгarn­

arn

 

 

ак

arnкоm1arnarnкгarnа U a rкОгn

arnкОгarnкгarnлОгarn

­ Oarn

 

лОгarn­ о m 1Oa r n

arnРtт6 ­ Oarn­Oarnа

 

 

arnкгarnк

arnк arn

 

 

 

 

гОгarn

т

 

 

 

 

 

 

arn­ н a r­nо m 1 a r n

л ­ a r nл о m 1 a r n

л а a r nк ек кгarnк U a rкn

Ого arnO

 

arnРtп6 ­ O a r n­ Oarnа

arnкг arnлаarnлн a rnк

arn

н ­ arnкоarnгОгarnл а a rлn ­ a r nкгarnк U a rкn

arnO arn

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рtп6

­

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a r n

 

O a r n­ Oarnа ­ a r нn г a r nк к a rккn arnкг arnл ­ a r nг Ог л а a r n

 

 

кг

arnк Uarкn

arn­ Oarn­

arn­ Oarnк­ arnлг a rnк к a rn

л ­ a r n

кк arnкгarnл ­ a r nл

О

г ar­Oarnn кUarnк

 

 

a­rnOarnкгarnл н a r n

 

 

л

 

 

 

 

 

 

arnклarn­ OarnлОг arnл а a rлn ­ a r n

ко m1arnОг aлаr na rnко m1arnк

кг

arnк Uarnк

 

arn

 

arnк­arnк

 

 

arnкг arnкОглarnа a r n

 

 

 

­ O a r nк

 

 

O

arnРtп6 O

 

arnРtп6 а ­ a r nкоm1arnк

aкr nU a rлn­ a r лn

о m 1 a r n

г­ arnкгarnнаос каarnкгarnл ­ a r n­ Oarn­

arn­ Sarnл ­ a r n

кг arnк Uarnкаarn­ Oarnкоm1arnк arn­ Oarnл к a rнn и е сл ­ a r n

ко m1arnк arnлг a rnл

О

г a­ Or na r nл а a rлn

о m 1лaOarnr n кг arnлОг ar n

­ O a r n­ н a r аn О г aкнr narnк Uarлn­ arn­

 

 

arn­ O a r nао m 1кa rarnn

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

­ O

 

 

 

 

Можно восстановить файл в виде строк из вывода в шестнадцате­

 

ричном формате. Охб l - числовой эквивалент символа ,c Буквы

wsgAы­ъюs,

расположены в алфавитном порядке, так что Ох65 должно быть сим-

подР0Бноm1

волом s' Ох2 0 - проn,ел. Приведенная здесь первая строка выглядит

 

при обычной записи в виде строк как "stream ( pr". И нтригующе,

 

не правда ли? Полностью коды букв вы можете найти, выполнив в

 

Google поиск

, Сs

Эти коды корректны и при использовании набора символов Unicode, кото­ рый применяется С# по умолчанию (больше о Unicode вы можете узнать, про­ гугr1явшись в поисках термина 1oшгкодo.е,еoFко, 'пlд

Обход коллекций: итераторы

Воставшейся части главы будут проанализированы три разных подхода

кобщей задаче -usч ч, N,,-в коллекции. В этом разделе будет продолжено

обсуждение наиболее традиционного (как мин имум для программистов на С#) подхода с использованием итераторов, которые реализуют и нтерфейс

IEnumerator.

iм,

х ля#. , дчеозч оиобипттвиозпевo

еп фa

 

Термины 2el4)eл4 (iterator) и зl4l­ 2_ 2el:, (enumerator) являются

 

синонимами. Терми н 2el 4)eл 4 более распространен, несмотря на

СОВЕТ

имя реализуемого им интерфейса. От обоих терминов можно про­

извести глагольную форму - вы можете итерировать контейнер, а

 

 

можете перечислять. Другими подходами к решению этой же задачи

 

являются индексаторы и новые блоки итераторов.

Доступ к коллекции: общая задача

Различные типы коллекций могут иметь разные схемы доступа. Не все виды

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

наподобие приведенного далее:

цц

г пt,шх", 3р, нтрrrn,) :сй щпс rrn й :им :й,, g

с:,

шпсt x z Xим,, К б

Vцц

ц"

Т Т "

цц

, , ,

Коллекции каждого типа могут сами определять свои методы доступа (и де­ лают это). Например, связанный список может предоставить метод GetNext ( ) для выборки следующего элемента из цепочки объектов; стек может предло­ жить методы Push ( ) и Рор ( ) для добавления и удаления объектов и т.д.

Более общий подход состоит в предоставлении для каждого класса коллек­ ции отдельного так называемого r: )))) 2el4)eл4)р который знает, как рабо­ тать с конкретной коллекцией. Каждая коллекция х определяет собственный класс I teratorx. В отличие от Х, IteratorX представляет общий интерфейс IEnurnerator, золотой стандарт итерирования. Этот метод использует второй объект, именуемый 2el4)eл 4лР ув качестве указателя внутрь коллекции. Ите­ ратор (перечислитель) обладает следующими преимуществами.

>>Каждый класс коллекции может определить собственный класс итератора. Поскольку итератор реализует стандартный интерфейс IEnumerator, с ним обычно легко работать.

»Прикладной код не должен знать о внутреннем устройстве коллек­ ций. Пока программист работает с итератором, тот берет на себя все заботы о деталях. Это - хорошая инкапсуляция.

»Прикладной код может создать много независимых объектов-ите­ раторов для одной и той же коллекции. Поскольку итератор содер­ жит информацию о собственном состоянии (знает, где он находится

еoздз, З, "­ьеж ­, е, хеВВкхКс отс,

179

в процессе итерирования), каждый итератор может независимо проходить по коллекции. Вы можете одновременно выполнять не­ сколько итераций, причем в один и тот же момент все они могут на­ ходиться в разных позициях.

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

»Reset ( ) - устанавливает итератор таким образом, чтобы он ука­ зывал на начало коллекции. Примечание: обобщенная версия

IEnumerator, IEnumerator<T>, не предоставляет метод Reset ( ) .

В случае обобщенного LinkedList из .NЕТ (находится в System . Co l l e c t ions . Gene r i c) просто начинайте работу с вызова

MoveNext ( ) .

)) MoveNext ( ) - перемещает итератор от текущего объекта в контей­ нере к следующему.

)), Current - свойство (не метод), которое дает объект данных, храня­ щийся в текущей позиции итератора.

Описанный принцип продемонстрирован приведенным ниже методом. Про­ граммист класса MyCollection (не показанного здесь) создает соответствую­ щий класс итератора - скажем, IteratorMyCollection (применяя соглашение об именах Iteratorx, упоминавшееся ранее). Прикладной программист ранее сохранил ряд объектов ContainedDataObj ects в коллекции MyCollect ion.

Приведенный н иже фрагмент исходного текста использует три стандартных метода IEnumerator для чтения этих объектов:

F F

 

 

 

FF

s

r

 

 

 

F F

:

 

.

F F

 

 

 

F F

 

 

 

FF

 

 

 

 

 

s

r

F F

 

т

т

F F

 

 

 

s

,

s мм

 

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

Метод икии вaир i е принимает в качестве аргумента коллекцию гдичсецч ир

оа в е шо l и л в у О н нач и нается

с создания итератора типа

vв и л е в и л и к

дифюилв цичу Метод начинает цикл с вызова иит иtи,в Д е Приу

первом вызове

иитиtи,в

Д рперемещает итератор к первому элементу коллекции. При каждом

последующем вызове иитиtи,в

) е перемещает указатель "на одну позицию".

Метод иитиtи,в Д рвозвращает СефыиКкогда коллекция исчерпана и итератор

больше нельзя передвинуть.

 

 

 

Свойство дтлличв

возвращает ссылку на объект данных

в текущей

позиц ии

итератора.

П рограмма преобразует возвращаем ы й

объект в

дичве цчир­ев ешоlилв перед тем, как присвоить его переменной личв ецчиру Вызов дтлличв некорректен, если предшествующий вызов метода иитиtи,в ) р не вернул влтиу

Использование foreach

Методы ­Вчтдилевил достаточно стандартны для того, чтобы С# исполь­ зовал их автоматически для реализации конструкции Силиелaу Цикл Силиелa может обращаться к любому классу, реализующему интерфейс v Вчтди леч и или КВчтдилеч иlгd( как показано в приведенном обобщенном методе, кото­ рый может работать с любым классом - от массивов и связанных списков до стеков и очередей:

 

s

 

г

s

 

м

 

,

/

е : м

Класс реал изует ­ В ч т д и л е

и Н г d

путем о пределения м етода

.ив Вчтди левил Д е котщ орый возвращает экземпляр ­ Вчтди левилНгdу Скры­ то от посторонних глаз Силиелa вызывает метод .ив Вчтд илевил i е для по­ лучения итератора. Цикл использует этот итератор для обхода контейнера. Каждый выбираемый им элемент приводится к соответствующему типу пе­ ред тем, как продолжить выполнение тела цикла. Обратите внимание на то, что ­ Вчтди лгц" и v Вч тд илЭ- , различные, но связанные интерфейсы . С#

,cлвл e цньо2н ю котт пк3 вoтв

181

предоставляет и необобщенную версию обоих интерфейсов, но для повыше­ ния безопасности типов следует предпочесть обобщенную версию.

IEnumeraЫe<T> имеет следующий вид: interface IEnumeraЬle<T>

ажIEnumerator<T> GetEnumerator ( ) ;

А IEnumerator<T> - такой: interface IEnumerator<T>

ажbool MoveNext ( ) ; Т Current { get ;

Необобщенный интерфейс IEnumerator добавляет метод Reset ( ) , который перемещает итератор в начало коллекции, а его свойство Current возвраща­ ет тип Obj ect. Обратите внимание на то, что IEnumerator<T> унаследован от IEnumerator, и вспомните, что наследование интерфейсов (рассматривается в главе 1 8, "Интерфейсы") отличается от обычного наследования объектов.

Массивы С# (воплощенные в классе Array) и все классы коллекций .NET ре­ ализуют оба интерфейса. Поэтому беспокоиться о реализации этих интерфей­

сов следует только при разработке собственных коллекций. Для встроенных коллекций вы можете просто их использовать (см. раздел ,; :шМбхж, FFМAжгош2:бъ

.МгоМжми2AlбМi lAМсправочной системы). Итак, цикл foreach можно записать таким образом:

foreach ( int nValue in myContainer)

ажсmсmш . ш ю

нтз яжыобыюиюьддыичбн дюияию июдя ййбуяд оюботыийяеь зкю

Обращение к элементам массива очень простое и понятное: команда container [ n ] обеспечивает обращение к п-му элементу массива container. Было бы хорошо, если бы так же просто с помощью индексов можно было обращаться и к другим типам коллекций.

Язык С# позволяет написать собственную реализацию операции индексиро­ вания. Вы можете предоставить возможность обращения через индекс коллек­ циям, которые таким свойством изначально не обладают. Кроме того, вы може­ те индексировать с использованием в качестве индексов не только типа int, но

.,o,

gз.lф, к, eеоеыn, ниеrирттс иеыросо, ор, мч,

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