14.02.2017 Views

. Стиллмен, Дж. Грин - Изучаем C#, 2-е издание

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Изуча<strong>е</strong>м</strong><br />

Управляй<br />

данными<br />

с Ы №<br />

2-<strong>е</strong> издани<strong>е</strong><br />

Познай с<strong>е</strong>кр<strong>е</strong>ты<br />

абстрагирования<br />

и насл<strong>е</strong>дования /<br />

Изучай С#<br />

на забавных<br />

прим<strong>е</strong>рах<br />

^<br />

Узнай,<br />

как м<strong>е</strong>тоды<br />

расшир<strong>е</strong>ния<br />

обл<strong>е</strong>гчают жизнь<br />

программиста<br />

Научись<br />

эфф<strong>е</strong>ктивно<br />

использовать<br />

обобщ<strong>е</strong>нны<strong>е</strong><br />

колл<strong>е</strong>кции


<strong>Изуча<strong>е</strong>м</strong> С#<br />

2-<strong>е</strong> издани<strong>е</strong><br />

Э. <strong>Стиллм<strong>е</strong>н</strong><br />

<strong>Дж</strong>. <strong>Грин</strong><br />

С ^ П П Т Е Р '<br />

М осква ■С а н кт-П <strong>е</strong>т<strong>е</strong>р б у р г ■Н иж ний Новгород ■В орон<strong>е</strong>ж<br />

Р о сто в -н а-Д о н у • Екат<strong>е</strong>ринбург ■С ам ара - Новосибирск<br />

Ки<strong>е</strong>в • Харьков ■М и н ск<br />

2012


ББК 32.973.2-018.1<br />

УДК 004.43<br />

С80<br />

С80<br />

<strong>Стиллм<strong>е</strong>н</strong> Э., <strong>Грин</strong><strong>Дж</strong>.<br />

<strong>Изуча<strong>е</strong>м</strong> С#. 2-<strong>е</strong> изд. — СПб.: Пит<strong>е</strong>р, 2012. — 696 с.: ил.<br />

ISBN 978-5-459-00422-9<br />

В отличи<strong>е</strong> от большинства книг по программированию, постро<strong>е</strong>нных на основ<strong>е</strong> скучного излож<strong>е</strong>ния сп<strong>е</strong>цификаций<br />

и прим<strong>е</strong>ров, с этой книгой читат<strong>е</strong>ль смож<strong>е</strong>т сразу приступить к написанию собств<strong>е</strong>нного кода на<br />

язык<strong>е</strong> программирования <strong>C#</strong> с самого начала. Вы освоит<strong>е</strong> минимальный набор инструм<strong>е</strong>нтов, а дал<strong>е</strong><strong>е</strong> прим<strong>е</strong>т<strong>е</strong><br />

участи<strong>е</strong> в забавных и инт<strong>е</strong>р<strong>е</strong>сных программных про<strong>е</strong>ктах: от разработки карточной игры до создания с<strong>е</strong>рь<strong>е</strong>зного<br />

бизн<strong>е</strong>с-прилож<strong>е</strong>ния. Второ<strong>е</strong> издани<strong>е</strong> книги включа<strong>е</strong>т посл<strong>е</strong>дни<strong>е</strong> в<strong>е</strong>рсии <strong>C#</strong> .NET 4.0 и Visual Studio<br />

2010 и буд<strong>е</strong>т инт<strong>е</strong>р<strong>е</strong>сно вс<strong>е</strong>м изучающим язык программирования С#.<br />

Особ<strong>е</strong>нностью данного издания явля<strong>е</strong>тся уникальный способ подачи мат<strong>е</strong>риала, выд<strong>е</strong>ляющий с<strong>е</strong>рию «Head<br />

First» издат<strong>е</strong>льства O’Reilly в ряду множ<strong>е</strong>ства скучных книг, посвящ<strong>е</strong>нных программированию.<br />

ББК 32.973.2-018.1<br />

УДК 004.43<br />

Права на издани<strong>е</strong> получ<strong>е</strong>ны по соглаш<strong>е</strong>нию с O'Reilly. Вс<strong>е</strong> права защищ<strong>е</strong>ны. Никакая часть данной книги н<strong>е</strong> мож<strong>е</strong>т быть<br />

воспроизв<strong>е</strong>д<strong>е</strong>на в какой бы то ни было форм<strong>е</strong> б<strong>е</strong>з письм<strong>е</strong>нного разр<strong>е</strong>ш<strong>е</strong>ния влад<strong>е</strong>льц<strong>е</strong>в авторских прав.<br />

Информация, сод<strong>е</strong>ржащаяся в данной книг<strong>е</strong>, получ<strong>е</strong>на из источников, рассматрива<strong>е</strong>мых издат<strong>е</strong>льством как над<strong>е</strong>жны<strong>е</strong>.<br />

Т<strong>е</strong>м н<strong>е</strong> м<strong>е</strong>н<strong>е</strong><strong>е</strong>, им<strong>е</strong>я в виду возможны<strong>е</strong> ч<strong>е</strong>лов<strong>е</strong>ч<strong>е</strong>ски<strong>е</strong> или т<strong>е</strong>хнич<strong>е</strong>ски<strong>е</strong> ошибки, издат<strong>е</strong>льство н<strong>е</strong> мож<strong>е</strong>т гарантировать<br />

абсолютную точность и полноту приводимых св<strong>е</strong>д<strong>е</strong>ний и н<strong>е</strong> н<strong>е</strong>с<strong>е</strong>т отв<strong>е</strong>тств<strong>е</strong>нности за возможны<strong>е</strong> ошибки, связанны<strong>е</strong><br />

с использовани<strong>е</strong>м книги.<br />

ISBN 978-1-4493-8034-2 англ.<br />

© Authorized Russian translation of the English edition Head First <strong>C#</strong> © O'Reilly<br />

Media, Inc. This translation is published and sold by permission of O'Reilly Media,<br />

Inc., the owner of all rights to publish and sell the same<br />

ISBN 978-5-459-00422-9 © П<strong>е</strong>р<strong>е</strong>вод на русский язык ООО Издат<strong>е</strong>льство «Пит<strong>е</strong>р», 2012<br />

© Издани<strong>е</strong> на русском язык<strong>е</strong>, оформл<strong>е</strong>ни<strong>е</strong><br />

ООО Издат<strong>е</strong>льство «Пит<strong>е</strong>р», 2012


авторы<br />

Спасибо, что купили нашу книгу!<br />

Мы писали <strong>е</strong><strong>е</strong> с удовольстви<strong>е</strong>м<br />

и над<strong>е</strong><strong>е</strong>мся, что вы получит<strong>е</strong><br />

кайф от <strong>е</strong><strong>е</strong> Прочт<strong>е</strong>ния...<br />

Эндрю<br />

А в т о р эт ой ф от ограф ии (как<br />

и сним ка канала Гованус) ~<br />

Ниша Сондх<strong>е</strong><br />

Э ндрю С тиллм<strong>е</strong>н родился в Нью-Йорк<strong>е</strong>,<br />

дважды <strong>е</strong>му приходилось жить в Питтсбург<strong>е</strong>.<br />

Сначала он закончил там унив<strong>е</strong>рсит<strong>е</strong>т Карн<strong>е</strong>ги-М<strong>е</strong>ллон,<br />

зат<strong>е</strong>м им<strong>е</strong>нно вэтом город<strong>е</strong> они<br />

с <strong>Дж</strong><strong>е</strong>нни начали свой консультационный<br />

бизн<strong>е</strong>с и работу над п<strong>е</strong>рвой книгой для издат<strong>е</strong>льства<br />

O ’Reilly<br />

В<strong>е</strong>рнувшись посл<strong>е</strong> колл<strong>е</strong>джа в родной город,<br />

Эндрю устроился программистом в фирму<br />

EMI-Capitol Records, что было н<strong>е</strong> лиш<strong>е</strong>но<br />

смысла, в<strong>е</strong>дь в школьны<strong>е</strong> годы он научился<br />

играть на виолонч<strong>е</strong>ли и джазовой бас-гитар<strong>е</strong>.<br />

И в той ж<strong>е</strong> компании, гд<strong>е</strong> Эндрю руководил<br />

командой программистов, работала <strong>Дж</strong><strong>е</strong>нни.<br />

За прош<strong>е</strong>дши<strong>е</strong> годы Эндрю сотрудничал<br />

с в<strong>е</strong>сьма квалифицированными программистами<br />

и ув<strong>е</strong>р<strong>е</strong>н, что многому от них научился.<br />

В свободно<strong>е</strong> от написания книг вр<strong>е</strong>мя Эндрю<br />

созда<strong>е</strong>т б<strong>е</strong>спол<strong>е</strong>зны<strong>е</strong> (но забавны<strong>е</strong>) программы,<br />

пиш<strong>е</strong>т музыку (для вид<strong>е</strong>оигр и н<strong>е</strong> только),<br />

изуча<strong>е</strong>т тайцзи и айкидо, встр<strong>е</strong>ча<strong>е</strong>тся со<br />

сво<strong>е</strong>й д<strong>е</strong>вушкой Лизой и выраш;ива<strong>е</strong>т шпица.<br />

Д ж <strong>е</strong>н н и ф <strong>е</strong>р <strong>Грин</strong> изучала в колл<strong>е</strong>дж<strong>е</strong> философию<br />

и, как и многи<strong>е</strong> <strong>е</strong><strong>е</strong> однокурсники, н<strong>е</strong> смогла<br />

найти работу по сп<strong>е</strong>циальности. Но благодаря<br />

способностям к разработк<strong>е</strong> программного об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ния<br />

она начала работать в онлайновой служб<strong>е</strong>.<br />

В 1998 году <strong>Дж</strong><strong>е</strong>нни п<strong>е</strong>р<strong>е</strong><strong>е</strong>хала в Нью-Йорк и<br />

устроилась в фирму по разработк<strong>е</strong> финансового<br />

программного об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ния. Она управляла<br />

командой разработчиков, занимавшихся искусств<strong>е</strong>нным<br />

инт<strong>е</strong>лл<strong>е</strong>ктом и обработкой <strong>е</strong>ст<strong>е</strong>ств<strong>е</strong>нных<br />

языков.<br />

Зат<strong>е</strong>м она много пут<strong>е</strong>ш<strong>е</strong>ствовала по миру с различными<br />

командами разработчиков и р<strong>е</strong>ализовала<br />

ц<strong>е</strong>лый ряд зам<strong>е</strong>чат<strong>е</strong>льных про<strong>е</strong>ктов.<br />

<strong>Дж</strong><strong>е</strong>ниф<strong>е</strong>р обожа<strong>е</strong>т пут<strong>е</strong>ш<strong>е</strong>ствия, индийско<strong>е</strong><br />

кино, комиксы, компьют<strong>е</strong>рны<strong>е</strong> игры и свою гончую.<br />

с мом<strong>е</strong>нта сво<strong>е</strong>й встр<strong>е</strong>чи в г я я г - м <strong>Дж</strong><strong>е</strong>нни и Эндрю вм<strong>е</strong>ст<strong>е</strong> разрабатывают программно<strong>е</strong> об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ни<strong>е</strong><br />

и пишут о н<strong>е</strong>м. Их п<strong>е</strong>рвая книга Applied Software Project<br />

^<br />

ств<strong>е</strong> О'Р<strong>е</strong>йли в ZOOS году. A п<strong>е</strong>рвая книга в с<strong>е</strong>рии Head P int Head R rst РМР поябылясь б Z007-M .<br />

В Z 003 году р<strong>е</strong>бята основали фирму Stellman & Qreene Consultine ^о разработк<strong>е</strong> программного<br />

об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ния для уч<strong>е</strong>ных, иссл<strong>е</strong>дующих возд<strong>е</strong>йстви<strong>е</strong> г<strong>е</strong>рбицидов, прим<strong>е</strong>н<strong>е</strong>нных во вр<strong>е</strong>мя ^^ины во<br />

Вь<strong>е</strong>тнам<strong>е</strong> В свободно<strong>е</strong> от написания программ и книг вр<strong>е</strong>мя Эндрю и <strong>Дж</strong><strong>е</strong>ни участвуют в конф<strong>е</strong><br />

р<strong>е</strong>нтах разработчиков программного об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ния и руководит<strong>е</strong>л<strong>е</strong>й про<strong>е</strong>ктов.<br />

Их личный блог располож<strong>е</strong>н по адр<strong>е</strong>су: http://www.stellm an-greene.com


оглавл<strong>е</strong>ни<strong>е</strong><br />

Оо д <strong>е</strong> р ж а н и <strong>е</strong> ( с Б о д к а )<br />

Вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

1 Эфф<strong>е</strong>ктивность с с#. Визуальны<strong>е</strong> прилож<strong>е</strong>ния за 10 минут<br />

2 Это вс<strong>е</strong>го лишь код. Под покровом<br />

3 Объ<strong>е</strong>кты, по порядку стройся! При<strong>е</strong>мы программирования<br />

4 Типы и ссылки. 10:00утра. Куда под<strong>е</strong>вались наши данны<strong>е</strong>?<br />

5 Инкапсуляция. Пусть лично<strong>е</strong> оста<strong>е</strong>тся... личным<br />

6 Насл<strong>е</strong>довани<strong>е</strong>. Г<strong>е</strong>н<strong>е</strong>алогич<strong>е</strong>ско<strong>е</strong> др<strong>е</strong>во объ<strong>е</strong>ктов<br />

7 Инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы. Пусть классы д<strong>е</strong>ржат об<strong>е</strong>щания<br />

8 П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции. Больши<strong>е</strong> объ<strong>е</strong>мы данных<br />

9 Чт<strong>е</strong>ни<strong>е</strong> и запись файлов. Сохрани массив байтов и спаси мир<br />

10 Обработка исключ<strong>е</strong>ний. Борьба с огн<strong>е</strong>м надо<strong>е</strong>да<strong>е</strong>т<br />

11 События и д<strong>е</strong>л<strong>е</strong>гаты. Что д<strong>е</strong>ла<strong>е</strong>т ваш код, когда вы на н<strong>е</strong>го н<strong>е</strong> смотрит<strong>е</strong><br />

12 Обзор и пр<strong>е</strong>дварит<strong>е</strong>льны<strong>е</strong> р<strong>е</strong>зультаты. Знания, сила и постро<strong>е</strong>ни<strong>е</strong><br />

прилож<strong>е</strong>ний<br />

13 Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты. Наводим красоту<br />

14 Капитан В<strong>е</strong>ликол<strong>е</strong>пный. См<strong>е</strong>рть объ<strong>е</strong>кта<br />

15 ЫЫЦ. Управля<strong>е</strong>м данными<br />

23<br />

35<br />

73<br />

115<br />

153<br />

195<br />

231<br />

283<br />

339<br />

395<br />

449<br />

491<br />

525<br />

573<br />

631<br />

669<br />

(^ о д <strong>е</strong> |^ Ж а н и <strong>е</strong> (н асл іо й гЩ <strong>е</strong> <strong>е</strong> )<br />

Вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

Ваш мозг и С # .<br />

Вы учит<strong>е</strong>сь — готовит<strong>е</strong>сь к экзам<strong>е</strong>ну. Или<br />

пыта<strong>е</strong>т<strong>е</strong>сь освоить сложную т<strong>е</strong>хнич<strong>е</strong>скую т<strong>е</strong>му. Ваш мозг пыта<strong>е</strong>тся<br />

оказать вам услугу. Он стара<strong>е</strong>тся сд<strong>е</strong>лать так, чтобы на эту оч<strong>е</strong>видно<br />

н<strong>е</strong>сущ<strong>е</strong>ств<strong>е</strong>нную информацию н<strong>е</strong> тратились драгоц<strong>е</strong>нны<strong>е</strong><br />

р<strong>е</strong>сурсы. Их лучш<strong>е</strong> потратить на что-нибудь важно<strong>е</strong>. Так как ж<strong>е</strong> заставить<br />

<strong>е</strong>го изучить С # ?<br />

Для кого написана эта книга 24<br />

Мы зна<strong>е</strong>м, о ч<strong>е</strong>м вы дума<strong>е</strong>т<strong>е</strong> 25<br />

М<strong>е</strong>тапознани<strong>е</strong>: наука о мышл<strong>е</strong>нии 27<br />

Заставьт<strong>е</strong> свой мозг повиноваться 29<br />

Что вам потр<strong>е</strong>бу<strong>е</strong>тся 30<br />

Информация 31<br />

Т<strong>е</strong>хнич<strong>е</strong>ски<strong>е</strong> р<strong>е</strong>ц<strong>е</strong>нз<strong>е</strong>нты 32<br />

Благодарности 33<br />

7


оглавл<strong>е</strong>ни<strong>е</strong><br />

э ^ '^ <strong>е</strong> К т и Б н о с ш ь С<br />

Визуальны<strong>е</strong> прилож<strong>е</strong>ния за 10 минут<br />

Хотит<strong>е</strong> программировать д<strong>е</strong>йствит<strong>е</strong>льно быстро? с# —<br />

мощный язык программирования. Благодаря Visual Studio вам н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся<br />

писать н<strong>е</strong>понятный код, чтобы заставить кнопку работать. Вм<strong>е</strong>сто<br />

того чтобы запоминать парам<strong>е</strong>тры м<strong>е</strong>тода для им<strong>е</strong>ни и для ярлыка кнопки,<br />

вы смож<strong>е</strong>т<strong>е</strong> сфокусироваться на достиж<strong>е</strong>нии р<strong>е</strong>зультата. Звучит заманчиво?<br />

Тогда п<strong>е</strong>р<strong>е</strong>в<strong>е</strong>рнит<strong>е</strong> страницу и приступим к д<strong>е</strong>лу.<br />

это<br />

Зач<strong>е</strong>м вам изучать <strong>C#</strong> 36<br />

с#, ИСР Visual Studio много<strong>е</strong> упрощают 37<br />

Избавьт<strong>е</strong> дир<strong>е</strong>ктора от бумаг 38<br />

П<strong>е</strong>р<strong>е</strong>д началом работы выяснит<strong>е</strong>, что им<strong>е</strong>нно нужно пользоват<strong>е</strong>лю 39<br />

Что мы собира<strong>е</strong>мся сд<strong>е</strong>лать 40<br />

Это вы д<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> в Visual Studio 42<br />

А это Visual Studio д<strong>е</strong>ла<strong>е</strong>т за вас 42<br />

Созда<strong>е</strong>м пользоват<strong>е</strong>льский инт<strong>е</strong>рф<strong>е</strong>йс 46<br />

Visual Studio, за сц<strong>е</strong>ной 48<br />

Р<strong>е</strong>дактировани<strong>е</strong> кода 4 9<br />

П<strong>е</strong>рвый запуск прилож<strong>е</strong>ния 50<br />

Гд<strong>е</strong> ж<strong>е</strong> мои файлы? 5 0<br />

Вот что уж<strong>е</strong> сд<strong>е</strong>лано 5 1<br />

Для хран<strong>е</strong>ния информации нужна база данных 52<br />

База данных, созданная ИСР 53<br />

Язык SQL 5 3<br />

Создани<strong>е</strong> таблицы для списка контактов 54<br />

Поля в контактной карт<strong>е</strong> —это столбцы таблицы People 56<br />

.NET Framework<br />

solutione<br />

DOala access<br />

lerigelsimd<br />

Howeod? Ooood OtШяг Швая<br />

Vrfua ...... 7<br />

«П(«<br />

Зав<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> таблицы 5 9<br />

П<strong>е</strong>р<strong>е</strong>нос в базу данных с карточ<strong>е</strong>к 60<br />

Источник данных со<strong>е</strong>динит форму с базой 62<br />

Добавл<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов, связанных с базой данных 64<br />

Хороши<strong>е</strong> программы понятны интуитивно 66<br />

Т<strong>е</strong>стировани<strong>е</strong> 68<br />

Как пр<strong>е</strong>вратить ВАШЕ прилож<strong>е</strong>ни<strong>е</strong> в прилож<strong>е</strong>ни<strong>е</strong> для ВСЕХ 69<br />

П<strong>е</strong>р<strong>е</strong>да<strong>е</strong>м прилож<strong>е</strong>ни<strong>е</strong> пользоват<strong>е</strong>лям 70<br />

Работа НЕ оконч<strong>е</strong>на: пров<strong>е</strong>рим проц<strong>е</strong>сс установки 71<br />

Управляющ<strong>е</strong><strong>е</strong> данными прилож<strong>е</strong>ни<strong>е</strong> готово 72


оглавл<strong>е</strong>ни<strong>е</strong><br />

э щ о Бс<strong>е</strong>Го Л иШ ь КоД<br />

Под покровом<br />

Вы — программист, а н<strong>е</strong> просто пользоват<strong>е</strong>ль<br />

ИСР. И С Р мож<strong>е</strong>т сд<strong>е</strong>лать за вас много<strong>е</strong>, но н<strong>е</strong> всё. При написании<br />

прилож<strong>е</strong>ний часто приходится р<strong>е</strong>шать повторяющи<strong>е</strong>ся<br />

задачи. Пусть эту работу выполня<strong>е</strong>т ИСР. Вы ж<strong>е</strong> буд<strong>е</strong>т<strong>е</strong> в это<br />

вр<strong>е</strong>мя думать над бол<strong>е</strong><strong>е</strong> глобальными в<strong>е</strong>щами. Научившись<br />

писать код, вы получит<strong>е</strong> возможность р<strong>е</strong>шить любую задачу.<br />

♦<br />

Д°СЗЦр“Ц1Ц<strong>е</strong><br />

ишкую fo J ^<br />

Когда вы д<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> это...<br />

...ИСР д<strong>е</strong>ла<strong>е</strong>т это.<br />

Как рождаются программы<br />

Писать код помога<strong>е</strong>т ИСР<br />

Любы<strong>е</strong> д<strong>е</strong>йствия в<strong>е</strong>дут к изм<strong>е</strong>н<strong>е</strong>нию кода<br />

Структура программы<br />

Начало работы программы<br />

Р<strong>е</strong>дактировани<strong>е</strong> точки входа<br />

ЬСлассы могут принадл<strong>е</strong>жать одному пространству им<strong>е</strong>н<br />

Что тако<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

Знакомы<strong>е</strong> мат<strong>е</strong>матич<strong>е</strong>ски<strong>е</strong> символы<br />

Наблюд<strong>е</strong>ни<strong>е</strong> за п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными в проц<strong>е</strong>сс<strong>е</strong> отладки<br />

Циклы<br />

П<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>м к практик<strong>е</strong><br />

Оп<strong>е</strong>ратор выбора<br />

Пров<strong>е</strong>рка условий<br />

74<br />

75<br />

76<br />

78<br />

80<br />

82<br />

84<br />

86<br />

91<br />

92<br />

94<br />

95<br />

97<br />

98<br />

99<br />

100<br />

А л я т х д с й п р о г р а м м ы в к<br />

Р , « Ч Е Т<br />

(Сля£;с<br />

ф рагм <strong>е</strong> н т бйид<strong>е</strong>«<br />

(ом<strong>е</strong>н»<br />

АМХА&н<strong>е</strong>ки&л^ограммы ^<br />

могит COC^v\oi:^A\t:><br />

и з й <strong>е</strong> г о од но го кла сса;.<br />

им<strong>е</strong>н<br />

К л а с с вю \к/ч а<strong>е</strong>ул оЗми и ли н с с к о л о к о<br />

A^£Уv'.o^oв. M£^■vxoдo^ вс<strong>е</strong>гё^а<br />

какому-либо<br />

'Л из о м р а ьу^о р о в,


оглавл<strong>е</strong>ни<strong>е</strong><br />

о б ъ <strong>е</strong> к т ы , 310 цо|>ядку сшр>ойся<br />

При<strong>е</strong>мы программирования<br />

Каждая прогроАлма р<strong>е</strong>ша<strong>е</strong>т какую-либо пробл<strong>е</strong>му. П<strong>е</strong>р<strong>е</strong>д написани<strong>е</strong>м<br />

программы нужно ч<strong>е</strong>тко сформулировать, какую задачу она буд<strong>е</strong>т<br />

р<strong>е</strong>шать. Им<strong>е</strong>нно поэтому так пол<strong>е</strong>зны объ<strong>е</strong>кты. В<strong>е</strong>дь они позволяют структурировать<br />

код наибол<strong>е</strong><strong>е</strong> удобным образом. Вы ж<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> соср<strong>е</strong>доточиться<br />

на обдумывании пут<strong>е</strong>й р<strong>е</strong>ш<strong>е</strong>ния, так как вам н<strong>е</strong> нужно тратить вр<strong>е</strong>мя на<br />

написани<strong>е</strong> кода. Правильно<strong>е</strong> использовани<strong>е</strong> объ<strong>е</strong>ктов позволя<strong>е</strong>т получить<br />

интуитивно понятный код, который при н<strong>е</strong>обходимости можно л<strong>е</strong>гко отр<strong>е</strong>дактировать.<br />

Нау|да1ог<br />

8<strong>е</strong>10<strong>е</strong>811па1юп()<br />

ModifyRouteToAvoid()<br />

Мо(1^Рои1<strong>е</strong>То1п(:^ис1<strong>е</strong>()<br />

6<strong>е</strong>1Нои1<strong>е</strong>()<br />

в<strong>е</strong>1Пт<strong>е</strong>ТоО<strong>е</strong>811паИоп()<br />

То1а101з1апс<strong>е</strong>()<br />

Опр<strong>е</strong>д<strong>е</strong>ляй «лйсс, вы опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<strong>е</strong><br />

и <strong>е</strong>го мскУ\оды, точно такж<strong>е</strong> как<br />

ч<strong>е</strong>рт<strong>е</strong>ж 01лр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т вн<strong>е</strong>шний вид<br />

дома.<br />

Что дума<strong>е</strong>т Майк о своих пробл<strong>е</strong>мах 116<br />

Пробл<strong>е</strong>ма Майка с точки зр<strong>е</strong>ния навигационной сист<strong>е</strong>мы 117<br />

М<strong>е</strong>тоды прокладки и р<strong>е</strong>дактирования маршрутов 118<br />

Построим программу с использовани<strong>е</strong>м классов 119<br />

Ид<strong>е</strong>я Майка 121<br />

Объ<strong>е</strong>кты как способ р<strong>е</strong>ш<strong>е</strong>ния пробл<strong>е</strong>мы 122<br />

Возьмит<strong>е</strong> класс и постройт<strong>е</strong> объ<strong>е</strong>кт 123<br />

Экз<strong>е</strong>мпляры 124<br />

Просто<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>! 125<br />

Поля 130<br />

Созда<strong>е</strong>м экз<strong>е</strong>мпляры! 131<br />

Спасибо за память 132<br />

Что происходит в памяти программы 133<br />

Значимы<strong>е</strong> им<strong>е</strong>на 134<br />

Структура классов 136<br />

Выбор структуры класса при помощи диаграммы 138<br />

Помогит<strong>е</strong> парням 142<br />

Про<strong>е</strong>кт «Парни» 143<br />

Форма для взаимод<strong>е</strong>йствия с кодом 144<br />

Бол<strong>е</strong><strong>е</strong> просты<strong>е</strong> способы присво<strong>е</strong>ния начальных знач<strong>е</strong>ний 147<br />

10<br />

чН а основ<strong>е</strong> одного ч<strong>е</strong>рт<strong>е</strong>жа<br />

МОЖНО у^остроить сколько<br />

угодно домов, а из одного<br />

класса можно получить<br />

сколько угодно объ<strong>е</strong>ктов.


оглавл<strong>е</strong>ни<strong>е</strong><br />

гоипь! и ссылки<br />

L<br />

10:00 утра. Куда под<strong>е</strong>вались наши данны<strong>е</strong>?<br />

Б<strong>е</strong>з данных програллмы б<strong>е</strong>спол<strong>е</strong>зны. Взяв информацию от пользоват<strong>е</strong>л<strong>е</strong>й,<br />

вы производит<strong>е</strong> новую информацию, чтобы в<strong>е</strong>рнуть <strong>е</strong><strong>е</strong> им ж<strong>е</strong>.<br />

Практич<strong>е</strong>ски вс<strong>е</strong> в программировании связано с обработкой данных т<strong>е</strong>м<br />

или иным способом, в этой глав<strong>е</strong> вы познакомит<strong>е</strong>сь с использу<strong>е</strong>мыми в С #<br />

типами данных, узна<strong>е</strong>т<strong>е</strong> м<strong>е</strong>тоды работы с ними и даж<strong>е</strong> ужасный с<strong>е</strong>кр<strong>е</strong>т объ<strong>е</strong>ктов<br />

(только т-с-с-с... объ<strong>е</strong>кты — это тож<strong>е</strong> данны<strong>е</strong>).<br />

Dog fldo;<br />

Dog lucky new Dog();<br />

fido = new DogO ;<br />

Тип п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т, каки<strong>е</strong> данны<strong>е</strong> она мож<strong>е</strong>т сохранять 154<br />

Наглядно<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

10 литров в 5-литровой банк<strong>е</strong><br />

Прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> типов<br />

Автоматич<strong>е</strong>ская корр<strong>е</strong>кция слишком больших знач<strong>е</strong>ний<br />

Иногда прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> типов происходит автоматич<strong>е</strong>ски<br />

Аргум<strong>е</strong>нты м<strong>е</strong>тода должны быть совм<strong>е</strong>стимы<br />

с типами парам<strong>е</strong>тров<br />

Комбинация с оп<strong>е</strong>ратором =<br />

Объ<strong>е</strong>кты тож<strong>е</strong> используют п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> ссылочного типа<br />

Ссылки подобны марк<strong>е</strong>рам<br />

При отсутствии ссылок объ<strong>е</strong>кт пр<strong>е</strong>враща<strong>е</strong>тся в мусор<br />

Побочны<strong>е</strong> эфф<strong>е</strong>кты множ<strong>е</strong>ств<strong>е</strong>нных ссылок<br />

Дв<strong>е</strong> ссылки это ДВА способа р<strong>е</strong>дактировать данны<strong>е</strong> объ<strong>е</strong>кта<br />

Особый случай; массивы<br />

Массив<br />

Массив мож<strong>е</strong>т состоять из ссылочных п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

Добро пожаловать на распродажу сэндвич<strong>е</strong>й от <strong>Дж</strong>о!<br />

Ссылки позволяют объ<strong>е</strong>ктам обращаться друг к другу<br />

Сюда объ<strong>е</strong>кты <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> отправлялись<br />

Игра<strong>е</strong>м в п<strong>е</strong>чатную машинку<br />

156<br />

157<br />

158<br />

159<br />

160<br />

161<br />

166<br />

167<br />

168<br />

169<br />

170<br />

171<br />

176<br />

177<br />

177<br />

178<br />

179<br />

181<br />

182<br />

187<br />

lucky = null;<br />

poof!-~<br />

/ \ \<br />

11


оглавл<strong>е</strong>ни<strong>е</strong><br />

и н к а п с у л я ц и я<br />

Пусть лично<strong>е</strong> оста<strong>е</strong>тся... личным<br />

д<br />

Вы когда-нибудь м<strong>е</strong>чтали о том, чтобы вашу личную<br />

жизнь оставили в поко<strong>е</strong>? Иногда объ<strong>е</strong>кты чувствуют то ж<strong>е</strong> само<strong>е</strong>.<br />

Вы ж<strong>е</strong> н<strong>е</strong> хотит<strong>е</strong>, чтобы посторонни<strong>е</strong> люди читали ваши записки или рассматривали<br />

банковски<strong>е</strong> выписки. Вот и объ<strong>е</strong>кты н<strong>е</strong> хотят, чтобы други<strong>е</strong><br />

объ<strong>е</strong>кты им<strong>е</strong>ли доступ к их полям. В этой глав<strong>е</strong> мы поговорим об инкапсуляции.<br />

Вы научит<strong>е</strong>сь закрывать объ<strong>е</strong>кты и добавлять м<strong>е</strong>тоды защ ищ ающи<strong>е</strong><br />

данны<strong>е</strong> от доступа.<br />

Кэтлин проф<strong>е</strong>ссиональный массовик-зат<strong>е</strong>йник 196<br />

Как происходит оц<strong>е</strong>нка 1 9 7<br />

Кэтлин т<strong>е</strong>стиру<strong>е</strong>т программу 202<br />

Каждый вариант нужно было считать отд<strong>е</strong>льно 204<br />

Н<strong>е</strong>правильно<strong>е</strong> использовани<strong>е</strong> объ<strong>е</strong>ктов 206<br />

Форма 206<br />

Инкапсуляция как управл<strong>е</strong>ни<strong>е</strong> доступом к данным 207<br />

Доступ к м<strong>е</strong>тодам и полям класса 208<br />

НА САМОМ ЛИ ДЕЛЕ защищ<strong>е</strong>но пол<strong>е</strong> realName? 209<br />

Закрыты<strong>е</strong> поля и м<strong>е</strong>тоды доступны только изнутри класса 210<br />

Инкапсуляция сохраня<strong>е</strong>т данны<strong>е</strong> н<strong>е</strong>тронутыми 218<br />

Инкапсуляция при помощи свойств 219<br />

Прилож<strong>е</strong>ни<strong>е</strong> для пров<strong>е</strong>рки класса Farmer 220<br />

Автоматич<strong>е</strong>ски<strong>е</strong> свойства 221<br />

Р<strong>е</strong>дактиру<strong>е</strong>м множит<strong>е</strong>ль feed 222<br />

Конструктор 223<br />

WMbervf<br />

peo^e.<br />

i=oo4»2$|i<br />

АМЫ,<br />

(*20|ИГ<br />

liemid<br />

Pamv raney<br />

deeoratioH^<br />

FuKy<br />

№oratloHi<br />

І*і;рсггіпм<br />

•VOdutrathig<br />

ful<br />

NomuU<br />

Picontlnu<br />

№ЇОр(Г<br />

s s ssa is i<br />

12


оглавл<strong>е</strong>ни<strong>е</strong><br />

н а с л <strong>е</strong> д о в а н и <strong>е</strong><br />

Г<strong>е</strong>н<strong>е</strong>алогич<strong>е</strong>ско<strong>е</strong> др<strong>е</strong>во объ<strong>е</strong>ктов<br />

Иногда люди хотят быть похожим на своих родит<strong>е</strong>л<strong>е</strong>й.<br />

Вы встр<strong>е</strong>чали объ<strong>е</strong>кт, который д<strong>е</strong>йству<strong>е</strong>т почти так, как нужно? Думали ли вы<br />

о том, како<strong>е</strong> сов<strong>е</strong>рш<strong>е</strong>нство можно было бы получить, изм<strong>е</strong>нив вс<strong>е</strong>го н<strong>е</strong>сколько<br />

эл<strong>е</strong>м<strong>е</strong>нтов? Им<strong>е</strong>нно по этой причин<strong>е</strong> насл<strong>е</strong>довани<strong>е</strong> явля<strong>е</strong>тся одним из самых<br />

мощных инструм<strong>е</strong>нтов с#, в этой глав<strong>е</strong> вы узна<strong>е</strong>т<strong>е</strong>, как производный класс<br />

повторя<strong>е</strong>т пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> родит<strong>е</strong>льского, сохраняя при этом гибкость р<strong>е</strong>дактирования.<br />

Вы научит<strong>е</strong>сь изб<strong>е</strong>гать дублирования кода и обл<strong>е</strong>гчит<strong>е</strong> посл<strong>е</strong>дующ<strong>е</strong><strong>е</strong><br />

р<strong>е</strong>дактировани<strong>е</strong> своих программ.<br />

Организация дн<strong>е</strong>й рожд<strong>е</strong>ния —это тож<strong>е</strong> работа 1Сэтлин<br />

Нам нуж<strong>е</strong>н класс BirthdayParty<br />

Планировщик м<strong>е</strong>роприятий, в<strong>е</strong>рсия 2.0<br />

Дополнит<strong>е</strong>льный взнос за м<strong>е</strong>роприятия с большим<br />

колич<strong>е</strong>ством гост<strong>е</strong>й<br />

Насл<strong>е</strong>довани<strong>е</strong><br />

Мод<strong>е</strong>ль классов; от общ<strong>е</strong>го к частному<br />

Симулятор зоопарка<br />

И<strong>е</strong>рархия классов<br />

Производны<strong>е</strong> классы расширяют базовый<br />

Синтаксис насл<strong>е</strong>дования<br />

При насл<strong>е</strong>довании поля свойства и м<strong>е</strong>тоды базового класса<br />

добавляются к производному...<br />

П<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> м<strong>е</strong>тодов<br />

Вм<strong>е</strong>сто базового класса можно взять один из производных<br />

Производный класс ум<strong>е</strong><strong>е</strong>т скрывать м<strong>е</strong>тоды<br />

Ключ<strong>е</strong>вы<strong>е</strong> слова override и virtual<br />

Ключ<strong>е</strong>во<strong>е</strong> слово base<br />

Если в базовом класс<strong>е</strong> присутству<strong>е</strong>т конструктор, он долж<strong>е</strong>н<br />

и в производном класс<strong>е</strong><br />

Т<strong>е</strong>п<strong>е</strong>рь мы готовы зав<strong>е</strong>ршить программу для Кэтлин!<br />

Сист<strong>е</strong>ма управл<strong>е</strong>ния уль<strong>е</strong>м<br />

Постро<strong>е</strong>ни<strong>е</strong> основ<br />

Сов<strong>е</strong>рш<strong>е</strong>нству<strong>е</strong>м сист<strong>е</strong>му управл<strong>е</strong>ния уль<strong>е</strong>м<br />

при помощи насл<strong>е</strong>дования<br />

232<br />

233<br />

234<br />

241<br />

242<br />

243<br />

244<br />

248<br />

249<br />

250<br />

253<br />

254<br />

255<br />

262<br />

264<br />

266<br />

остаться<br />

267<br />

268<br />

273<br />

274<br />

282<br />

13


оглавл<strong>е</strong>ни<strong>е</strong><br />

инт<strong>е</strong>р^^<strong>е</strong>йсы и а^ аи р ак тн ы <strong>е</strong> классы<br />

Пусть классы д<strong>е</strong>ржат об<strong>е</strong>щания<br />

Д<strong>е</strong>йствия значат больш<strong>е</strong>, ч<strong>е</strong>м слова. Иногда возника<strong>е</strong>т н<strong>е</strong>обходимость<br />

сгруппировать объ<strong>е</strong>кты по выполня<strong>е</strong>мым функциям, а н<strong>е</strong> по классам,<br />

от которых они насл<strong>е</strong>дуют. Зд<strong>е</strong>сь вам на помощь приходят инт<strong>е</strong>рф<strong>е</strong>йсы,<br />

они позволяют работать с любым классом, отв<strong>е</strong>чающим вашим потр<strong>е</strong>бностям.<br />

Но ч<strong>е</strong>м больш<strong>е</strong> возможност<strong>е</strong>й, т<strong>е</strong>м выш<strong>е</strong> отв<strong>е</strong>тств<strong>е</strong>нность, и <strong>е</strong>сли<br />

классы, р<strong>е</strong>ализующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс, н<strong>е</strong> выполнят обязат<strong>е</strong>льств... программа<br />

компилироваться н<strong>е</strong> буд<strong>е</strong>т.<br />

Насл<strong>е</strong>довани<strong>е</strong><br />

^|нкаисуляЦия<br />

ДбсторакЦия<br />

Ф<br />

В<strong>е</strong>рн<strong>е</strong>мся к нашим пч<strong>е</strong>лам 284<br />

Классы для различных типов пч<strong>е</strong>л 285<br />

Инт<strong>е</strong>рф<strong>е</strong>йсы 286<br />

Классы, р<strong>е</strong>ализующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсы, должны включать ВСЕ<br />

м<strong>е</strong>тоды инт<strong>е</strong>рф<strong>е</strong>йсов 289<br />

Учимся работать с инт<strong>е</strong>рф<strong>е</strong>йсами 290<br />

Ссылки на инт<strong>е</strong>рф<strong>е</strong>йс 292<br />

IJoiuMop'fuaM<br />

Room<br />

Decoration<br />

Locsl&on<br />

Name<br />

Exfts<br />

Oescrip&mO<br />

O utside<br />

Hot<br />

Ссылка на инт<strong>е</strong>рф<strong>е</strong>йс аналогична ссылк<strong>е</strong> на объ<strong>е</strong>кт 293<br />

Инт<strong>е</strong>рф<strong>е</strong>йсы и насл<strong>е</strong>довани<strong>е</strong> 295<br />

КоЬоВ<strong>е</strong><strong>е</strong> 4000 функциониру<strong>е</strong>т б<strong>е</strong>з м<strong>е</strong>да 296<br />

Коф<strong>е</strong>варка относится к Приборам 298<br />

Восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> 299<br />

Нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> 300<br />

Нисходящ<strong>е</strong><strong>е</strong> и восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсов 301<br />

Модификаторы доступа 305<br />

Изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> видимости при помощи модификаторов доступа 306<br />

Классы, для которых н<strong>е</strong>допустимо создани<strong>е</strong> экз<strong>е</strong>мпляров 309<br />

Абстрактный класс. П<strong>е</strong>р<strong>е</strong>путь<strong>е</strong> м<strong>е</strong>жду классом и инт<strong>е</strong>рф<strong>е</strong>йсом 310<br />

Как уж<strong>е</strong> было сказано, н<strong>е</strong>допустимо создавать экз<strong>е</strong>мпляры<br />

н<strong>е</strong>которых классов 3 1 2<br />

Абстрактный м<strong>е</strong>тод н<strong>е</strong> им<strong>е</strong><strong>е</strong>т т<strong>е</strong>ла 313<br />

См<strong>е</strong>рт<strong>е</strong>льным ромбом! 3 1 8<br />

Различны<strong>е</strong> формы объ<strong>е</strong>кта 3 2 1<br />

14


оглавл<strong>е</strong>ни<strong>е</strong><br />

п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и я U К о л л <strong>е</strong> к ц и и<br />

Больши<strong>е</strong> объ<strong>е</strong>мы данных<br />

Пришла б<strong>е</strong>да — отворяй ворота, в р<strong>е</strong>альном мир<strong>е</strong> данны<strong>е</strong>, как правило,<br />

н<strong>е</strong> хранятся мал<strong>е</strong>нькими кусочками. Данны<strong>е</strong> приходят вагонами, штаб<strong>е</strong>лями<br />

и кучами. Для их сист<strong>е</strong>матизации нужны мощны<strong>е</strong> инструм<strong>е</strong>нты, и тут<br />

вам на помощь приходят колл<strong>е</strong>кции. Они позволяют хранить, сортировать<br />

и р<strong>е</strong>дактировать данны<strong>е</strong>, которы<strong>е</strong> обрабатыва<strong>е</strong>т программа. В р<strong>е</strong>зультат<strong>е</strong> вы<br />

мож<strong>е</strong>т<strong>е</strong> соср<strong>е</strong>доточиться на основной ид<strong>е</strong><strong>е</strong> программирования, оставив задачу<br />

отсл<strong>е</strong>живания данных колл<strong>е</strong>кциям.<br />

Кат<strong>е</strong>гории данных н<strong>е</strong> вс<strong>е</strong>гда можно сохранять<br />

в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных типа string 340<br />

П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния 341<br />

Присвоим числам им<strong>е</strong>на 342<br />

Создать колоду карт можно было при помощи массива... 345<br />

Пробл<strong>е</strong>мы работы с массивами 346<br />

Колл<strong>е</strong>кции 347<br />

Колл<strong>е</strong>кции List 348<br />

Динамич<strong>е</strong>ско<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> разм<strong>е</strong>ров 351<br />

Обобщ<strong>е</strong>нны<strong>е</strong> колл<strong>е</strong>кции 352<br />

Инициализаторы колл<strong>е</strong>кций 356<br />

Колл<strong>е</strong>кция уток 357<br />

Сортировка эл<strong>е</strong>м<strong>е</strong>нтов колл<strong>е</strong>кции 358<br />

Инт<strong>е</strong>рф<strong>е</strong>йс IComparable 359<br />

Способы сортировки 360<br />

Создадим экз<strong>е</strong>мпляр объ<strong>е</strong>кта-компаратора 361<br />

Сложны<strong>е</strong> сх<strong>е</strong>мы сравн<strong>е</strong>ния 362<br />

П<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> м<strong>е</strong>тода ToStringO 365<br />

Обновим цикл foreach 366<br />

\ \ ^ Инт<strong>е</strong>рф<strong>е</strong>йс1Епит<strong>е</strong>гаЫ<strong>е</strong> 367<br />

- ___ Восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> с помощью lEnumerable 368<br />

* Создани<strong>е</strong> п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нных м<strong>е</strong>тодов 369<br />

/ ^ Словари 375<br />

Дополнит<strong>е</strong>льны<strong>е</strong> типы колл<strong>е</strong>кций... 389<br />

Зв<strong>е</strong>нья сл<strong>е</strong>дуют в порядк<strong>е</strong> их поступл<strong>е</strong>ния 390<br />

Зв<strong>е</strong>нья сл<strong>е</strong>дуют в порядк<strong>е</strong>, обратном порядку их поступл<strong>е</strong>ния 391<br />

15


оглавл<strong>е</strong>ни<strong>е</strong><br />

Ч т <strong>е</strong> н и <strong>е</strong> U sa n u cb * ^ a u J I o B<br />

Сохрани массив байтов и спаси мир<br />

Иногда настойчивость окупа<strong>е</strong>тся.<br />

Пока что вс<strong>е</strong> ваши программы жили н<strong>е</strong>долго. Они запускались, н<strong>е</strong>которо<strong>е</strong> вр<strong>е</strong>мя<br />

работали и закрывались. Но этого н<strong>е</strong>достаточно, когда им<strong>е</strong><strong>е</strong>шь д<strong>е</strong>ло с важной<br />

информаци<strong>е</strong>й. Вы должны ум<strong>е</strong>ть сохранять свою работу В этой глав<strong>е</strong> мы<br />

поговорим о том, как записать данны<strong>е</strong> в файл, а зат<strong>е</strong>м о том, как прочитать эту<br />

информацию. Вы познакомит<strong>е</strong>сь с потоковыми классами .NET и узна<strong>е</strong>т<strong>е</strong> о тайнах<br />

ш<strong>е</strong>стнадцат<strong>е</strong>ричной и двоичной сист<strong>е</strong>м счисл<strong>е</strong>ния.<br />

Для чт<strong>е</strong>ния и записи данных в .NET используются потоки 396<br />

Различны<strong>е</strong> потоки для различных данных 397<br />

Объ<strong>е</strong>кт FileStream 3 9 3<br />

Тр<strong>е</strong>хшаговая проц<strong>е</strong>дура записи т<strong>е</strong>кста в файл 399<br />

Чт<strong>е</strong>ни<strong>е</strong> и запись при помощи двух объ<strong>е</strong>ктов 403<br />

Встро<strong>е</strong>нны<strong>е</strong> объ<strong>е</strong>кты для вызова стандартных окон диалога 407<br />

Встро<strong>е</strong>нны<strong>е</strong> классы File и Directory<br />

4 Ю<br />

Открыти<strong>е</strong> и сохран<strong>е</strong>ни<strong>е</strong> файлов при помощи окон диалога 413<br />

Инт<strong>е</strong>рф<strong>е</strong>йс IDisposable 4 1 5<br />

Оп<strong>е</strong>раторы using как ср<strong>е</strong>дство изб<strong>е</strong>жать сист<strong>е</strong>мных ошибок 416<br />

Запись файлов сопровожда<strong>е</strong>тся приняти<strong>е</strong>м р<strong>е</strong>ш<strong>е</strong>ний 422<br />

Оп<strong>е</strong>ратор switch 4 2 3<br />

Чт<strong>е</strong>ни<strong>е</strong> и запись информации о картах в файл 424<br />

Чт<strong>е</strong>ни<strong>е</strong> карт из файла 4 2 5<br />

С<strong>е</strong>риализации подв<strong>е</strong>рга<strong>е</strong>тся н<strong>е</strong> только сам объ<strong>е</strong>кт... 429<br />

E u r e k a !<br />

69 7^4<br />

69 117 114 101 107 97 33<br />

о \ г г ^ ч i<br />

10797'<br />

С<strong>е</strong>риализация позволя<strong>е</strong>т читать и записывать объ<strong>е</strong>кт ц<strong>е</strong>ликом 430<br />

С<strong>е</strong>риализу<strong>е</strong>м и д<strong>е</strong>с<strong>е</strong>риализу<strong>е</strong>м колоду карт 432<br />

.NET использу<strong>е</strong>т Unicode для хран<strong>е</strong>ния символов и т<strong>е</strong>кста 435<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> данных внутри массива байтов 436<br />

Класс BinaryWriter 4 3 7<br />

Чт<strong>е</strong>ни<strong>е</strong> и запись с<strong>е</strong>риализованных файлов вручную 439<br />

Найдит<strong>е</strong> отличия и отр<strong>е</strong>дактируйт<strong>е</strong> файлы 440<br />

Сложности работы с двоичными файлами 441<br />

Программа для создания дампа 4 4 2<br />

Достаточно StreamReader и Stream Writer 443<br />

Чт<strong>е</strong>ни<strong>е</strong> байтов из потока 4 4 4<br />

16


оглавл<strong>е</strong>ни<strong>е</strong><br />

обр>абощка искЛіоЧ<strong>е</strong>ний<br />

Борьба с огн<strong>е</strong>м надо<strong>е</strong>да<strong>е</strong>т<br />

Программисты н<strong>е</strong> должны уподобляться пожарным.<br />

Вы ус<strong>е</strong>рдно работали, штудировали т<strong>е</strong>хнич<strong>е</strong>ски<strong>е</strong> руководства и након<strong>е</strong>ц достигли<br />

в<strong>е</strong>ршины; т<strong>е</strong>п<strong>е</strong>рь вы главный программист. Но вам до сих пор продолжают<br />

звонить с работы по ночам, потому что программа упала или работа<strong>е</strong>т<br />

н<strong>е</strong>правильно. Ничто так н<strong>е</strong> выбива<strong>е</strong>т из кол<strong>е</strong>и, как н<strong>е</strong>обходимость устранять<br />

странны<strong>е</strong> ошибки... но благодаря обработк<strong>е</strong> искпюч<strong>е</strong>ний вы смож<strong>е</strong>т<strong>е</strong> написать<br />

код, который сам буд<strong>е</strong>т разбираться с возможными пробл<strong>е</strong>мами.<br />

Брайану нужны мобильны<strong>е</strong> оправдания<br />

Объ<strong>е</strong>кт Exception<br />

Код Брайана работа<strong>е</strong>т н<strong>е</strong> так, как пр<strong>е</strong>дполагалось<br />

Исключ<strong>е</strong>ния насл<strong>е</strong>дуют от объ<strong>е</strong>кта Exception<br />

Работа с отладчиком<br />

Поиск ошибки в прилож<strong>е</strong>нии Excuse Manager с помощью<br />

отладчика<br />

А код вс<strong>е</strong> равно н<strong>е</strong> работа<strong>е</strong>т...<br />

Ключ<strong>е</strong>вы<strong>е</strong> слова try и catch<br />

Вызов сомнит<strong>е</strong>льного м<strong>е</strong>тода<br />

Р<strong>е</strong>зультаты прим<strong>е</strong>н<strong>е</strong>ния ключ<strong>е</strong>вых слов try/catch<br />

Ключ<strong>е</strong>во<strong>е</strong> слово finally<br />

Получ<strong>е</strong>ния информации о пробл<strong>е</strong>м<strong>е</strong><br />

Обработка исключ<strong>е</strong>ний разных типов<br />

Один класс созда<strong>е</strong>т исключ<strong>е</strong>ни<strong>е</strong>, другой <strong>е</strong>го обрабатыва<strong>е</strong>т<br />

Исключ<strong>е</strong>ни<strong>е</strong> OutOffloney для пч<strong>е</strong>л<br />

Оп<strong>е</strong>ратор using как комбинация<br />

оп<strong>е</strong>раторов try и finally<br />

Изб<strong>е</strong>га<strong>е</strong>м исключ<strong>е</strong>ний при помощи инт<strong>е</strong>рф<strong>е</strong>йса IDisposable<br />

Наихудший вариант блока catch<br />

Вр<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ния<br />

Кратки<strong>е</strong> принципы обработки исключ<strong>е</strong>ний<br />

Након<strong>е</strong>ц Брайан получил свой отдых...<br />

450<br />

454<br />

456<br />

458<br />

459<br />

460<br />

463<br />

465<br />

466<br />

468<br />

470<br />

475<br />

476<br />

477<br />

478<br />

481<br />

482<br />

484<br />

485<br />

486<br />

489<br />

17


оглавл<strong>е</strong>ни<strong>е</strong><br />

собьдпия и Д<strong>е</strong>Л<strong>е</strong>Гашь!<br />

Что д<strong>е</strong>ла<strong>е</strong>т код, когда вы на н<strong>е</strong>го н<strong>е</strong> смотрит<strong>е</strong><br />

Н<strong>е</strong>возможно вс<strong>е</strong> вр<strong>е</strong>мя контролировать созданны<strong>е</strong> объ<strong>е</strong>кты.<br />

Иногда что-то... происходит И хот<strong>е</strong>лось бы, чтобы объ<strong>е</strong>кты ум<strong>е</strong>ли р<strong>е</strong>агировать<br />

на происходящ<strong>е</strong><strong>е</strong>. Зд<strong>е</strong>сь вам на помощь приходят события. Один объ<strong>е</strong>кт<br />

их публику<strong>е</strong>т, други<strong>е</strong> объ<strong>е</strong>кты на них подписываются, и сист<strong>е</strong>ма работа<strong>е</strong>т.<br />

А для контроля подписчиков вам пригодится м<strong>е</strong>тод обратного вызова.<br />

Хотит<strong>е</strong>, что объ<strong>е</strong>кты научились думать сами?<br />

Как объ<strong>е</strong>кты узнают, что произошло?<br />

События<br />

Один объ<strong>е</strong>кт иницииру<strong>е</strong>т событи<strong>е</strong>, другой р<strong>е</strong>агиру<strong>е</strong>т на н<strong>е</strong>го<br />

Обработка события<br />

Со<strong>е</strong>диним вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong><br />

Автоматич<strong>е</strong>ско<strong>е</strong> создани<strong>е</strong> обработчиков событий<br />

Обобщ<strong>е</strong>нный Еу<strong>е</strong>пСНап(11<strong>е</strong>г<br />

Вс<strong>е</strong> формы используют события<br />

Н<strong>е</strong>сколько обработчиков одного события<br />

Связь м<strong>е</strong>жду издат<strong>е</strong>лями и подписчиками<br />

Д<strong>е</strong>л<strong>е</strong>гат зам<strong>е</strong>ща<strong>е</strong>т м<strong>е</strong>тоды<br />

Д<strong>е</strong>л<strong>е</strong>гаты в д<strong>е</strong>йствии<br />

Объ<strong>е</strong>кт мож<strong>е</strong>т подписаться на событи<strong>е</strong>...<br />

Обратный вызов<br />

Обратный вызов как способ работы с д<strong>е</strong>л<strong>е</strong>гатами<br />

492<br />

492<br />

493<br />

494<br />

495<br />

496<br />

500<br />

506<br />

507<br />

508<br />

510<br />

511<br />

512<br />

515<br />

516<br />

518<br />

Р‘^сс^оянии 8 2<br />

^ I<br />

Ва11 .О пВ аШ пР1ау (70, 82)<br />

от базы.<br />

Лодаюм,ий Эолж<strong>е</strong>н<br />

бросит о э т о т<br />

МЯИ.<br />

^<br />

Подающий м ож <strong>е</strong>т<br />

угл о м и на<br />

т ако<strong>е</strong> расст ояни<strong>е</strong><br />

дольш <strong>е</strong>, ч<strong>е</strong>м 23 82.).<br />

Р 1 Ь с Ь в г . С а Ь с Ь В а 1 1 ( 7 0 , 9 0 )<br />

18


оглавл<strong>е</strong>ни<strong>е</strong><br />

и т1р<strong>е</strong>ДБа|=пщ1<strong>е</strong>ЛьНы<strong>е</strong> р’<strong>е</strong>зуЛьташ ы<br />

Знания, сила и постро<strong>е</strong>ни<strong>е</strong> прилож<strong>е</strong>ний<br />

Знания нужно прим<strong>е</strong>нять на практик<strong>е</strong>.<br />

Пока вы н<strong>е</strong> начн<strong>е</strong>т<strong>е</strong> писать работающий код, вряд ли можно быть ув<strong>е</strong>р<strong>е</strong>нным,<br />

что вы на самом д<strong>е</strong>л<strong>е</strong> усвоили сложны<strong>е</strong> понятия С#. С<strong>е</strong>йчас мы<br />

займ<strong>е</strong>мся прим<strong>е</strong>н<strong>е</strong>ни<strong>е</strong>м на практик<strong>е</strong> получ<strong>е</strong>нных ран<strong>е</strong><strong>е</strong> знаний. Кром<strong>е</strong><br />

того, вы найд<strong>е</strong>т<strong>е</strong> пр<strong>е</strong>дварит<strong>е</strong>льны<strong>е</strong> св<strong>е</strong>д<strong>е</strong>ния о понятиях, которы<strong>е</strong> будут<br />

рассматриваться в сл<strong>е</strong>дующих главах. Мы начн<strong>е</strong>м постро<strong>е</strong>ни<strong>е</strong> д<strong>е</strong>йствит<strong>е</strong>льно<br />

сложного прилож<strong>е</strong>ния, чтобы закр<strong>е</strong>пить ваши навыки.<br />

Жизнь U см<strong>е</strong>рть цв<strong>е</strong>тка<br />

Обь<strong>е</strong>^г^<br />

jage = ОIfe<br />

Вы прошли долгий путь<br />

Вы стали пч<strong>е</strong>ловодом<br />

Архит<strong>е</strong>ктура симулятора улья<br />

Постро<strong>е</strong>ни<strong>е</strong> симулятора улья<br />

Жизнь и см<strong>е</strong>рть цв<strong>е</strong>тка<br />

Класс В<strong>е</strong><strong>е</strong><br />

Программисты против б<strong>е</strong>здомных пч<strong>е</strong>л<br />

Для жизни улья нуж<strong>е</strong>н м<strong>е</strong>д<br />

Постро<strong>е</strong>ни<strong>е</strong> класса Hive<br />

М<strong>е</strong>тод Go О для улья<br />

Вс<strong>е</strong> готово для класса World<br />

Сист<strong>е</strong>ма, основанная на кадрах<br />

Код для класса World<br />

Пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>л<br />

Основная форма<br />

Получ<strong>е</strong>ни<strong>е</strong> статистики<br />

Тайм<strong>е</strong>ры<br />

Работа с группами пч<strong>е</strong>л<br />

Колл<strong>е</strong>кция колл<strong>е</strong>кциониру<strong>е</strong>т... ДАННЫЕ<br />

LINQynpom;aeT работу с колл<strong>е</strong>кциями и базами данных<br />

Т<strong>е</strong>стировани<strong>е</strong> (вторая попытка)<br />

Посл<strong>е</strong>дни<strong>е</strong> штрихи: Open и Save<br />

526<br />

527<br />

528<br />

529<br />

533<br />

534<br />

538<br />

538<br />

542<br />

543<br />

544<br />

545<br />

546<br />

552<br />

554<br />

555<br />

556<br />

564<br />

565<br />

567<br />

568<br />

569<br />

O&beV^<br />

19


оглавл<strong>е</strong>ни<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нты уп|>аБл<strong>е</strong>ния и Гра^^иЧ<strong>е</strong>ски<strong>е</strong> “^ а Ш <strong>е</strong> н т ы<br />

Наводим красоту<br />

Иногда управл<strong>е</strong>ни<strong>е</strong> графикой приходится брать в свои руки.<br />

До этого мом<strong>е</strong>нта визуальный асп<strong>е</strong>кт наших прилож<strong>е</strong>ний был отдан на откуп<br />

эл<strong>е</strong>м<strong>е</strong>нтам управл<strong>е</strong>ния. Но иногда этого н<strong>е</strong>достаточно, наприм<strong>е</strong>р, <strong>е</strong>сли вы<br />

хотит<strong>е</strong> анимировать изображ<strong>е</strong>ни<strong>е</strong>. Вам пр<strong>е</strong>дстоит научиться создавать свои<br />

эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния для .NET, прим<strong>е</strong>нять двойную буф<strong>е</strong>ризацию и даж<strong>е</strong><br />

рисовать н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно на формах.<br />

Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния как ср<strong>е</strong>дство взаимод<strong>е</strong>йствия<br />

с программой<br />

Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния - это тож<strong>е</strong> объ<strong>е</strong>кты<br />

Анимиру<strong>е</strong>м симулятор улья<br />

Визуализатор<br />

Формы для визуализации<br />

П<strong>е</strong>рвый анимированный эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

Базовый класс PictureBox<br />

Кнопка добавл<strong>е</strong>ния эл<strong>е</strong>м<strong>е</strong>нта BeeControl<br />

Удал<strong>е</strong>ни<strong>е</strong> доч<strong>е</strong>рних эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

Класс UserControl<br />

Пом<strong>е</strong>стим на форму анимированных пч<strong>е</strong>л<br />

Формы Hive и Field<br />

Постро<strong>е</strong>ни<strong>е</strong> визуализатора<br />

Со<strong>е</strong>диним основную форму с формами HiveForm и FieldForm<br />

Пробл<strong>е</strong>мы с производит<strong>е</strong>льностью<br />

Объ<strong>е</strong>кт Graphics<br />

Объ<strong>е</strong>кт Bitmap<br />

Пространство им<strong>е</strong>н System.Drawing<br />

Знакомство с GDI+<br />

Рису<strong>е</strong>м на форм<strong>е</strong><br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> пробл<strong>е</strong>мы с прозрачностью<br />

Событи<strong>е</strong> Paint<br />

П<strong>е</strong>р<strong>е</strong>рисовка форм и эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

Двойная буф<strong>е</strong>ризация<br />

Вывод на п<strong>е</strong>чать<br />

Окно пр<strong>е</strong>дварит<strong>е</strong>льного просмотра и окно диалога Print<br />

574<br />

575<br />

576<br />

578<br />

579<br />

583<br />

584<br />

586<br />

587<br />

588<br />

590<br />

592<br />

593<br />

596<br />

600<br />

602<br />

603<br />

604<br />

605<br />

606<br />

611<br />

612<br />

615<br />

618<br />

624<br />

625<br />

20


оглавл<strong>е</strong>ни<strong>е</strong><br />

М<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта<br />

Когда запуска<strong>е</strong>т м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта<br />

Явно<strong>е</strong> и н<strong>е</strong>явно<strong>е</strong> высвобожд<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>сурсов<br />

Возможны<strong>е</strong> пробл<strong>е</strong>мы<br />

С<strong>е</strong>риализу<strong>е</strong>м объ<strong>е</strong>кт в м<strong>е</strong>тод<strong>е</strong> Dispose ()<br />

Структура напомина<strong>е</strong>т объ<strong>е</strong>кт...<br />

...но объ<strong>е</strong>ктом н<strong>е</strong> явля<strong>е</strong>тся<br />

Знач<strong>е</strong>ния копируются, а ссылки присваиваются<br />

Структуры - это значимы<strong>е</strong>, а объ<strong>е</strong>кты - ссылочны<strong>е</strong> типы<br />

Сравн<strong>е</strong>ни<strong>е</strong> ст<strong>е</strong>ка и кучи<br />

Н<strong>е</strong>обязат<strong>е</strong>льны<strong>е</strong> парам<strong>е</strong>тры<br />

Типы, допускающи<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> null<br />

Типы, допускающи<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> null, ув<strong>е</strong>личивают робастность<br />

программы<br />

Что осталось от В<strong>е</strong>ликол<strong>е</strong>пного<br />

Сравн<strong>е</strong>ни<strong>е</strong><br />

М<strong>е</strong>тоды расшир<strong>е</strong>ния<br />

Расширя<strong>е</strong>м фундам<strong>е</strong>нтальный тип; string<br />

638<br />

639<br />

640<br />

642<br />

643<br />

647<br />

647<br />

648<br />

649<br />

651<br />

656<br />

657<br />

658<br />

661<br />

661<br />

662<br />

664<br />

21


оглавл<strong>е</strong>ни<strong>е</strong><br />

LINQ<br />

Управля<strong>е</strong>м данными<br />

Этот мир управля<strong>е</strong>тся данными... вам лучш<strong>е</strong> знать, как в н<strong>е</strong>м жить.<br />

Вр<strong>е</strong>м<strong>е</strong>на, когда можно было программировать днями и даж<strong>е</strong> н<strong>е</strong>д<strong>е</strong>лями, н<strong>е</strong><br />

касаясь множ<strong>е</strong>ства данных, давно позади. В наши дни с данными связано<br />

вс<strong>е</strong>. Часто приходится работать с данными из разных источников и даж<strong>е</strong> разных<br />

форматов. Базы данных, XM L, колл<strong>е</strong>кции из других программ... вс<strong>е</strong> это<br />

давно стало частью работы программиста на С#. В этом <strong>е</strong>му помога<strong>е</strong>т LINQ.<br />

Эта функция н<strong>е</strong> только упроща<strong>е</strong>т запросы, но и ум<strong>е</strong><strong>е</strong>т разбивать данны<strong>е</strong> на<br />

группы и, наоборот, со<strong>е</strong>динять данны<strong>е</strong> из различных источников.<br />

Простой про<strong>е</strong>кт... 670<br />

...но сначала нужно собрать данны<strong>е</strong> 671<br />

List 671<br />

Сбор данных из разных источников 672<br />

Колл<strong>е</strong>кции .NET уж<strong>е</strong> настро<strong>е</strong>ны под LINQ 673<br />

Простой способ сд<strong>е</strong>лать запрос 674<br />

Сложны<strong>е</strong> запросы 675<br />

Унив<strong>е</strong>рсальность LINQ 678<br />

Группировка р<strong>е</strong>зультатов запроса 683<br />

Сгруппиру<strong>е</strong>м р<strong>е</strong>зультаты <strong>Дж</strong>имми 684<br />

Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> join 687<br />

List 687<br />

LIN Q Sequence 687<br />

List 687<br />

<strong>Дж</strong>имми изрядно сэкономил 6 8 8<br />

LINQ Sequence 689<br />

List 689<br />

Ч<br />

Со<strong>е</strong>дин<strong>е</strong>ни<strong>е</strong> LINQ с базой данных SQL 690<br />

Со<strong>е</strong>диним Starbuzz и Objectville 694<br />

22


к а к р а б о з з а а ш ь с э ш ^ й к н и Г о й<br />

Вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

в э т о м розЭ<strong>е</strong>л<strong>е</strong><br />

« т а к п о м <strong>е</strong> м у о н и б к л ю и и л<br />

" т А 1^^0 6 ^ к га ° С*?»


как работать с этой книгой<br />

Для кого написана эта книга?<br />

Если на вопросы :<br />

Вы хотит<strong>е</strong> изучать С#?<br />

Вы пр<strong>е</strong>дпочита<strong>е</strong>т<strong>е</strong> учиться практикуясь, а н<strong>е</strong> просто<br />

читая т<strong>е</strong>кст?<br />

Вы пр<strong>е</strong>дпочита<strong>е</strong>т<strong>е</strong> оживл<strong>е</strong>нную б<strong>е</strong>с<strong>е</strong>ду сухим,<br />

скучным акад<strong>е</strong>мич<strong>е</strong>ским л<strong>е</strong>кциям?<br />

вы отв<strong>е</strong>ча<strong>е</strong>т<strong>е</strong> полож ит<strong>е</strong>льно, то эта книга для вас.<br />

Кому эта книга н<strong>е</strong> подойд<strong>е</strong>т?<br />

Если вы отв<strong>е</strong>тит<strong>е</strong> «да» на любой из сл<strong>е</strong>дующих вопросов.<br />

^ Нав<strong>е</strong>ва<strong>е</strong>т ли на вас скуку и н<strong>е</strong>рвозность мысль о том,<br />

что прид<strong>е</strong>тся часто и много писать код?<br />

Вы отличный программист на C++ или Java,<br />

которому нуж<strong>е</strong>н справочник?<br />

^ Вы боит<strong>е</strong>сь попробовать что-нибудь ново<strong>е</strong>? Скор<strong>е</strong><strong>е</strong><br />

пойд<strong>е</strong>т<strong>е</strong> к зубному врачу, ч<strong>е</strong>м над<strong>е</strong>н<strong>е</strong>т<strong>е</strong> полосато<strong>е</strong><br />

с кл<strong>е</strong>тчатым? Счита<strong>е</strong>т<strong>е</strong>, что т<strong>е</strong>хнич<strong>е</strong>ская книга, в которой<br />

конц<strong>е</strong>пции 0# изображ<strong>е</strong>ны в вид<strong>е</strong> ч<strong>е</strong>лов<strong>е</strong>чков, с<strong>е</strong>рь<strong>е</strong>зной<br />

быть н<strong>е</strong> мож<strong>е</strong>т?<br />

...эта книга н<strong>е</strong> для вас.<br />

[Зам <strong>е</strong>т ка о т от д<strong>е</strong>ла продажвообщ<br />

<strong>е</strong>-т о эт а кныга для любого<br />

У кого <strong>е</strong>ст ь д<strong>е</strong>ньги.]<br />

24 вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>


вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

Mbl зна<strong>е</strong>м, о ч<strong>е</strong>м Вы дума<strong>е</strong>т<strong>е</strong><br />

«Разв<strong>е</strong> с<strong>е</strong>рь<strong>е</strong>зны<strong>е</strong> книги по программированию на <strong>C#</strong> таки<strong>е</strong>?»<br />

«И поч<strong>е</strong>му зд<strong>е</strong>сь столько рисунков?»<br />

«Можно ли так ч<strong>е</strong>му-нибудь научиться?»<br />

U мы зна<strong>е</strong>м, о ч<strong>е</strong>м дума<strong>е</strong>т Ваш мозг<br />

Мозг жажд<strong>е</strong>т новых вп<strong>е</strong>чатл<strong>е</strong>ний. Он постоянно ищ<strong>е</strong>т,<br />

анализиру<strong>е</strong>т, ожида<strong>е</strong>т ч<strong>е</strong>го-то н<strong>е</strong>обычного. Он так устро<strong>е</strong>н, и это<br />

помога<strong>е</strong>т нам выжить.<br />

В наши дни вы вряд ли попад<strong>е</strong>т<strong>е</strong> на об<strong>е</strong>д к тигру. Но наш мозг<br />

постоянно оста<strong>е</strong>тся насторож<strong>е</strong>. Просто мы об этом н<strong>е</strong> зна<strong>е</strong>м.<br />

Как ж<strong>е</strong> наш мозг поступа<strong>е</strong>т со вс<strong>е</strong>ми обычными, повс<strong>е</strong>дн<strong>е</strong>вными<br />

в<strong>е</strong>щами? Он вс<strong>е</strong>ми силами пыта<strong>е</strong>тся оградиться от них, чтобы<br />

они н<strong>е</strong> м<strong>е</strong>шали <strong>е</strong>го настоящ<strong>е</strong>й работ<strong>е</strong> —сохран<strong>е</strong>нию того, что<br />

д<strong>е</strong>йствит<strong>е</strong>льно важно. Мозг н<strong>е</strong> счита<strong>е</strong>т нужным сохранять<br />

скучную информацию. Она н<strong>е</strong> проходит фильтр, отс<strong>е</strong>кающий<br />

«оч<strong>е</strong>видно н<strong>е</strong>сущ<strong>е</strong>ств<strong>е</strong>нно<strong>е</strong>».<br />

Но как ж<strong>е</strong> мозг узна<strong>е</strong>т, что важно? Пр<strong>е</strong>дставьт<strong>е</strong>, что вы вы<strong>е</strong>хали<br />

на прогулку, и вдруг прямо п<strong>е</strong>р<strong>е</strong>д вами появля<strong>е</strong>тся тигр. Что<br />

происходит в ваш<strong>е</strong>й голов<strong>е</strong> и в т<strong>е</strong>л<strong>е</strong>?<br />

Активизируются н<strong>е</strong>йроны. Вспыхивают эмоции. Происходят<br />

химич<strong>е</strong>ски<strong>е</strong> р<strong>е</strong>акции.<br />

И тогда ваш мозг понима<strong>е</strong>т...<br />

М озг ги,<br />

^^Ж но. ^<br />

/<br />

Кон<strong>е</strong>чно, это важно! Н<strong>е</strong> забывать!<br />

А т<strong>е</strong>п<strong>е</strong>рь пр<strong>е</strong>дставьт<strong>е</strong>, что вы находит<strong>е</strong>сь дома или в библиот<strong>е</strong>к<strong>е</strong>,<br />

в т<strong>е</strong>плом, уютном м<strong>е</strong>ст<strong>е</strong>, гд<strong>е</strong> тигры н<strong>е</strong> водятся. Вы<br />

учит<strong>е</strong>сь —готовит<strong>е</strong>сь к экзам<strong>е</strong>ну. Или пыта<strong>е</strong>т<strong>е</strong>сь освоить<br />

сложную т<strong>е</strong>хнич<strong>е</strong>скую т<strong>е</strong>му, на которую вам выд<strong>е</strong>лили н<strong>е</strong>д<strong>е</strong>лю...<br />

максимум д<strong>е</strong>сять дн<strong>е</strong>й.<br />

И тут возника<strong>е</strong>т пробл<strong>е</strong>ма: ваш мозг пыта<strong>е</strong>тся оказать вам<br />

услугу. Он стара<strong>е</strong>тся сд<strong>е</strong>лать так, чтобы на эту оч<strong>е</strong>видно н<strong>е</strong>сущ<strong>е</strong>ств<strong>е</strong>нную<br />

информацию н<strong>е</strong> тратились драгоц<strong>е</strong>нны<strong>е</strong> р<strong>е</strong>сурсы.<br />

Их лучш<strong>е</strong> потратить на что-нибудь важно<strong>е</strong>. На тигров,<br />

наприм<strong>е</strong>р. Или на то, что к огню лучш<strong>е</strong> н<strong>е</strong> прикасаться.<br />

Или что ни в ко<strong>е</strong>м случа<strong>е</strong> н<strong>е</strong>льзя выв<strong>е</strong>шивать фото с этой<br />

в<strong>е</strong>ч<strong>е</strong>ринки на сво<strong>е</strong>й страничк<strong>е</strong> в Facebook.<br />

Н<strong>е</strong>т простого способа сказать сво<strong>е</strong>му мозгу: «Послушай,<br />

мозг, я т<strong>е</strong>б<strong>е</strong>, кон<strong>е</strong>чно, благодар<strong>е</strong>н, но какой бы скучной ни была<br />

эта книга, и пусть мой датчик эмоций с<strong>е</strong>йчас на нул<strong>е</strong>, я хочу<br />

запомнить то, что зд<strong>е</strong>сь написано».<br />

дальш <strong>е</strong> > 25


как работать с этой книгой<br />

V a к н и г а ДЛЯ г о <strong>е</strong> - . Н £ 5<br />

к а к « ы ч то -то<br />

" ^ к о<br />

Затолкать в голову поболь Ф g ^огии и психологии обуч<strong>е</strong>ния, для<br />

Мы зна<strong>е</strong>м, как заставить ваш мозг работать.<br />

О с н о в н ы <strong>е</strong> п р и н ц и п ы с <strong>е</strong> р и и « H e a d F irst» ;<br />

наглядность. Графика запомина<strong>е</strong>тся гораздо лучш<strong>е</strong>, ч<strong>е</strong>м обьнны и<br />

V o I<br />

- »-»пож<strong>е</strong>ния. Н<strong>е</strong>давни<strong>е</strong> иссл<strong>е</strong>дования показали,<br />

р а з г о в о р н ы й с т и л ь изло*о«ия.» „<strong>е</strong><br />

. о п р . р а , г о з о р „ о » с т и „ <strong>е</strong> _ ~ ^<br />

(вм<strong>е</strong>сто фор«льныхл«цш),лучш<strong>е</strong>й.»<br />

р<strong>е</strong>зультатов на итоговом т<strong>е</strong>стиров<br />

относит<strong>е</strong>сь к с<strong>е</strong>б<strong>е</strong> слишком<br />

—<br />

столом или л<strong>е</strong>кция?<br />

Ппка вы н<strong>е</strong> начн<strong>е</strong>т<strong>е</strong> напрягать извилины,<br />

А к т и в н о <strong>е</strong> у ч а с т и <strong>е</strong> ч и т ‘ читат<strong>е</strong>ль долж<strong>е</strong>н быть заинт<strong>е</strong>р<strong>е</strong>в<br />

ваш<strong>е</strong>й голов<strong>е</strong> нич<strong>е</strong>го н<strong>е</strong> про<br />

формулировать выводы<br />

сован в р<strong>е</strong>зультат<strong>е</strong>; он долж р g д^^^лы упражн<strong>е</strong>ния и<br />

= <strong>е</strong> Г п " ; „ : = ^ ^<br />

мозга и разны<strong>е</strong> чувства.<br />

Привл<strong>е</strong>ч<strong>е</strong>ни<strong>е</strong> (и<br />

ой страниц<strong>е</strong>». Мозг обраща<strong>е</strong>т внимани<strong>е</strong> на инт<strong>е</strong>оч<strong>е</strong>нь<br />

хочу изучить это, но зась.<br />

н<strong>е</strong>ожиданно<strong>е</strong>. Изуч<strong>е</strong>ни<strong>е</strong> сложной т<strong>е</strong>хнич<strong>е</strong>-<br />

А - = Е<br />

• Х Г = Г о , . т <strong>е</strong> ^ и ^<br />

\ ; г : ; г г г : : ; « ч » . с <strong>е</strong> , „ , й к . 5 о а<br />

26 вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>


вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

М<strong>е</strong>тапознани<strong>е</strong>: наука о мышл<strong>е</strong>нии<br />

Если вы д<strong>е</strong>йствит<strong>е</strong>льно хотит<strong>е</strong> быстр<strong>е</strong><strong>е</strong> и глубж<strong>е</strong> усваивать новы<strong>е</strong><br />

знания —задумайт<strong>е</strong>сь над т<strong>е</strong>м, как вы задумыва<strong>е</strong>т<strong>е</strong>сь. Учит<strong>е</strong>сь учиться.<br />

Мало кто из нас изуча<strong>е</strong>т т<strong>е</strong>орию м<strong>е</strong>тапознания во вр<strong>е</strong>мя уч<strong>е</strong>бы. Нам<br />

полож<strong>е</strong>ноучитъся, но нас р<strong>е</strong>дко этому учат.<br />

Но раз вы чита<strong>е</strong>т<strong>е</strong> эту книгу, то, в<strong>е</strong>роятно, вы хотит<strong>е</strong> узнать, как<br />

программировать на С#, и по возможности быстр<strong>е</strong><strong>е</strong>. Вы хотит<strong>е</strong><br />

запомнить прочитанно<strong>е</strong> и прим<strong>е</strong>нять новую информацию на практик<strong>е</strong>.<br />

Чтобы извл<strong>е</strong>чь максимум пользы из уч<strong>е</strong>бного проц<strong>е</strong>сса, нужно<br />

заставить ваш мозг воспринимать новый мат<strong>е</strong>риал как Н<strong>е</strong>что Важно<strong>е</strong>.<br />

Критично<strong>е</strong> для ваш<strong>е</strong>го суш;<strong>е</strong>ствования. Тако<strong>е</strong> ж<strong>е</strong> важно<strong>е</strong>, как тигр.<br />

Инач<strong>е</strong> вам пр<strong>е</strong>дстоит б<strong>е</strong>скон<strong>е</strong>чная борьба с вашим мозгом,<br />

который вс<strong>е</strong>ми силами уклоня<strong>е</strong>тся от запоминания новой<br />

информации.<br />

К а к ж <strong>е</strong> У Б Е Д И Т Ь м озг, ч т о п р о г р а м м и р о в а н и <strong>е</strong> н а С #<br />

т а к ж <strong>е</strong> в а ж н о , к а к и т и гр ?<br />

Есть способ м<strong>е</strong>дл<strong>е</strong>нный и скучный, а <strong>е</strong>сть быстрый и<br />

эфф<strong>е</strong>ктивный. П<strong>е</strong>рвый основан на тупом повтор<strong>е</strong>нии.<br />

Вс<strong>е</strong>м изв<strong>е</strong>стно, что даж<strong>е</strong> самую скучную информацию можно<br />

запомнить, <strong>е</strong>сли повторять <strong>е</strong><strong>е</strong> снова и снова. При достаточном<br />

колич<strong>е</strong>ств<strong>е</strong> повтор<strong>е</strong>ний ваш мозг прикидыва<strong>е</strong>т: «Врод<strong>е</strong> бы н<strong>е</strong>сущ<strong>е</strong>ств<strong>е</strong>нно,<br />

но раз одно и то ж<strong>е</strong> повторя<strong>е</strong>тся столько раз... Ладно, уговорил».<br />

Быстрый способ основан на повыш <strong>е</strong>нии активности мозга, и особ<strong>е</strong>нно<br />

на соч<strong>е</strong>тании разных <strong>е</strong><strong>е</strong> видов. Доказано, что вс<strong>е</strong> факторы, п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>нны<strong>е</strong><br />

на пр<strong>е</strong>дыдущ<strong>е</strong>й страниц<strong>е</strong>, помогают ваш<strong>е</strong>му мозгу работать на вас.<br />

Наприм<strong>е</strong>р, исс<strong>е</strong>дования показали, что разм<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> слов вмут<strong>е</strong>/ж рисунков<br />

(а н<strong>е</strong> в подписях, в основном т<strong>е</strong>кст<strong>е</strong> и т. д.) заставля<strong>е</strong>т мозг анализировать<br />

связи м<strong>е</strong>жду т<strong>е</strong>кстом и графикой, а это приводит к активизации больш<strong>е</strong>го<br />

колич<strong>е</strong>ства н<strong>е</strong>йронов. Больш<strong>е</strong> н<strong>е</strong>йронов = выш<strong>е</strong> в<strong>е</strong>роятность того, что<br />

информация буд<strong>е</strong>т сочт<strong>е</strong>на важной и достойной запоминания.<br />

Разговорный стиль тож<strong>е</strong> важ<strong>е</strong>н: обычно люди проявляют больш<strong>е</strong> внимания,<br />

когда они участвуют в разговор<strong>е</strong>, так как им приходится сл<strong>е</strong>дить за ходом<br />

б<strong>е</strong>с<strong>е</strong>ды и высказывать сво<strong>е</strong> мн<strong>е</strong>ни<strong>е</strong>. Прич<strong>е</strong>м мозг сов<strong>е</strong>рш<strong>е</strong>нно н<strong>е</strong> инт<strong>е</strong>р<strong>е</strong>су<strong>е</strong>т,<br />

что вы «разговарива<strong>е</strong>т<strong>е</strong>» с книгой! С другой стороны, <strong>е</strong>сли т<strong>е</strong>кст сух<br />

и формал<strong>е</strong>н, то мозг чувству<strong>е</strong>т то ж<strong>е</strong>, что чувству<strong>е</strong>т<strong>е</strong> вы на скучной л<strong>е</strong>кции<br />

в роли пассивного участника. Его клонит в сон.<br />

Но рисунки и разговорный стиль —это только начало.<br />

дальш <strong>е</strong> > 27


как работать с этой книгой<br />

Вот что сд<strong>е</strong>лали МЫ<br />

0 >^.р<strong>е</strong>.д<strong>е</strong>ля» к/.асс. вы о л р <strong>е</strong> -<br />

Мы использовали рисунки, потому что мозг лучш<strong>е</strong> приспособл<strong>е</strong>н для<br />

восприятия графики, ч<strong>е</strong>м т<strong>е</strong>кста. С точки зр<strong>е</strong>ния мозга рисунок стоит<br />

тысячи слов. А когда т<strong>е</strong>кст комбиниру<strong>е</strong>тся с графикой, мы вн<strong>е</strong>дря<strong>е</strong>м<br />

т<strong>е</strong>кст прямо в рисунки, потому что мозг при этом работа<strong>е</strong>т эфф<strong>е</strong>ктивн<strong>е</strong><strong>е</strong>.<br />

Мы использу<strong>е</strong>м избыточность: повторя<strong>е</strong>м одно и то ж<strong>е</strong> н<strong>е</strong>сколько раз, прим<strong>е</strong>няя<br />

разны<strong>е</strong> ср<strong>е</strong>дства п<strong>е</strong>р<strong>е</strong>дачи информации, обраща<strong>е</strong>мся к разным чувствам —и<br />

вс<strong>е</strong> для повыш<strong>е</strong>ния в<strong>е</strong>роятности того, что мат<strong>е</strong>риал буд<strong>е</strong>т закодирован в н<strong>е</strong>скольких<br />

областях ваш<strong>е</strong>го мозга.<br />

Мы использу<strong>е</strong>м конц<strong>е</strong>пции и рисунки н<strong>е</strong>сколько н<strong>е</strong>ожиданным образом, потому<br />

что мозг лучш<strong>е</strong> воспринима<strong>е</strong>т новую информацию. Кром<strong>е</strong> того, рисунки и<br />

ид<strong>е</strong>и обычно им<strong>е</strong>ют эшщитшльно<strong>е</strong> сод<strong>е</strong>ржант, потому что мозг обраща<strong>е</strong>т внимани<strong>е</strong><br />

на биохимию эмоций. То, что заставля<strong>е</strong>т нас чувствовать, лучш<strong>е</strong> запомина<strong>е</strong>тся<br />

—будь то гиутка, удивл<strong>е</strong>ни<strong>е</strong> или инт<strong>е</strong>р<strong>е</strong>с.<br />

Мы использу<strong>е</strong>м/»озгово/шый стиль, потому что мозг лучш<strong>е</strong> воспринима<strong>е</strong>т информацию,<br />

когда вы участву<strong>е</strong>т<strong>е</strong> в разговор<strong>е</strong>, а н<strong>е</strong> пассивно слуша<strong>е</strong>т<strong>е</strong> л<strong>е</strong>кцию. Это<br />

происходит и при чт<strong>е</strong>нии.<br />

В книгу включ<strong>е</strong>ны многочисл<strong>е</strong>нны<strong>е</strong> упражн<strong>е</strong>ния, потому что мозг лучш<strong>е</strong> запомина<strong>е</strong>т,<br />

когда вы работа<strong>е</strong>т<strong>е</strong> самостоят<strong>е</strong>льно. Мы постарались сд<strong>е</strong>лать их н<strong>е</strong>простыми,<br />

но инт<strong>е</strong>р<strong>е</strong>сными —то, что пр<strong>е</strong>дпочита<strong>е</strong>т большинство читат<strong>е</strong>л<strong>е</strong>й.<br />

Мы совм<strong>е</strong>стили н<strong>е</strong>сколько стил<strong>е</strong>й обуч<strong>е</strong>ния, потому что одни читат<strong>е</strong>ли любят пошаговы<strong>е</strong><br />

описания, други<strong>е</strong> стр<strong>е</strong>мятся сначала пр<strong>е</strong>дставить «общую картину»,<br />

а тр<strong>е</strong>тьим хвата<strong>е</strong>т фрагм<strong>е</strong>нта кода. Н<strong>е</strong>зависимо от ваших личных пр<strong>е</strong>дпочт<strong>е</strong>ний<br />

пол<strong>е</strong>зно вид<strong>е</strong>ть н<strong>е</strong>сколько вариантов пр<strong>е</strong>дставл<strong>е</strong>ния одного мат<strong>е</strong>риала.<br />

Мы постарались зад<strong>е</strong>йствовать оба полуишрия ваш<strong>е</strong>го мозга; это повыша<strong>е</strong>т в<strong>е</strong>роятность<br />

усво<strong>е</strong>ния мат<strong>е</strong>риала. Пока одна сторона мозга работа<strong>е</strong>т, другая часто им<strong>е</strong><strong>е</strong>т<br />

возможность отдохнуть; это повыша<strong>е</strong>т эфф<strong>е</strong>ктивность обуч<strong>е</strong>ния в т<strong>е</strong>ч<strong>е</strong>ни<strong>е</strong><br />

продолжит<strong>е</strong>льного вр<strong>е</strong>м<strong>е</strong>ни.<br />

А <strong>е</strong>щ<strong>е</strong> в книгу включ<strong>е</strong>ны истории и упражн<strong>е</strong>ния, отражающи<strong>е</strong> други<strong>е</strong> точки зр<strong>е</strong>ния.<br />

Мозг кач<strong>е</strong>ств<strong>е</strong>нн<strong>е</strong><strong>е</strong> усваива<strong>е</strong>т информацию, когда <strong>е</strong>му приходится оц<strong>е</strong>нивать<br />

и выносить сужд<strong>е</strong>ния.<br />

в книг<strong>е</strong> часто встр<strong>е</strong>чаются вопросы, на которы<strong>е</strong> н<strong>е</strong> вс<strong>е</strong>гда можно дать простой<br />

отв<strong>е</strong>т, потому что мозг быстр<strong>е</strong><strong>е</strong> учится и запомина<strong>е</strong>т, когда <strong>е</strong>му приходится чтото<br />

д<strong>е</strong>лать. Н<strong>е</strong>возможно накачать мышцы, наблюдая за т<strong>е</strong>м, как занимаются други<strong>е</strong>.<br />

Однако мы позаботились о том, чтобы усилия читат<strong>е</strong>л<strong>е</strong>й были прилож<strong>е</strong>ны<br />

в в<strong>е</strong>рном направл<strong>е</strong>нии. Вам н<strong>е</strong> прид<strong>е</strong>тся ломать голову над н<strong>е</strong>вразумит<strong>е</strong>льными<br />

прим<strong>е</strong>рами или разбираться в сложном, п<strong>е</strong>р<strong>е</strong>насыщ<strong>е</strong>нном т<strong>е</strong>хнич<strong>е</strong>ским жаргоном<br />

или слишком лаконичном т<strong>е</strong>кст<strong>е</strong>.<br />

В историях, прим<strong>е</strong>рах, на картинках использованы антропоморфны<strong>е</strong> образы.<br />

В<strong>е</strong>дь вы ч<strong>е</strong>лов<strong>е</strong>к, и ваш мозг уд<strong>е</strong>ля<strong>е</strong>т больш<strong>е</strong> внимания людям, а н<strong>е</strong> в<strong>е</strong>щам.<br />

зсля<strong>е</strong>т<strong>е</strong>. Э<strong>е</strong>ля<strong>е</strong>т<strong>е</strong>. £20A1^^vvcl^, <strong>е</strong>го м<strong>е</strong>>^\01л>1, тс/ч«у<br />

л\акис<strong>е</strong> кдк и<strong>е</strong>^-т<strong>е</strong>жслр<strong>е</strong>Звточно<br />

ляг('л вн<strong>е</strong>шний вид рома.<br />

. На оснсв<strong>е</strong> о(Ь


Что мо)к<strong>е</strong>т<strong>е</strong> сд<strong>е</strong>лать ВЫ, чтобы<br />

заставить сбой мозг поВиноВаться<br />

вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

Мы сво<strong>е</strong> д<strong>е</strong>ло сд<strong>е</strong>лали. Остально<strong>е</strong> за вами. Эти сов<strong>е</strong>ты станут<br />

отправной точкой; прислушайт<strong>е</strong>сь к сво<strong>е</strong>му мозгу и опр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong>,<br />

что вам подходит, а что н<strong>е</strong> подходит. Пробуйт<strong>е</strong> ново<strong>е</strong>.<br />

Выр<strong>е</strong>жьт<strong>е</strong> ы прикр<strong>е</strong>пит<strong>е</strong><br />

НД холодильник.<br />

^ Н<strong>е</strong> торопит<strong>е</strong>сь. Ч<strong>е</strong>м больш<strong>е</strong> вы пойм<strong>е</strong>т<strong>е</strong>, т<strong>е</strong>м<br />

м<strong>е</strong>ньш<strong>е</strong> прид<strong>е</strong>тся запоминать.<br />

Просто читать н<strong>е</strong>достаточно. Когда книга зада<strong>е</strong>т<br />

вам вопрос, н<strong>е</strong> п<strong>е</strong>р<strong>е</strong>ходит<strong>е</strong> к отв<strong>е</strong>ту. Пр<strong>е</strong>дставьт<strong>е</strong>,<br />

что кто-то д<strong>е</strong>йствит<strong>е</strong>льно зада<strong>е</strong>т вам вопрос. Ч<strong>е</strong>м<br />

глубж<strong>е</strong> ваш мозг буд<strong>е</strong>т мыслить, т<strong>е</strong>м скор<strong>е</strong><strong>е</strong> вы<br />

пойм<strong>е</strong>т<strong>е</strong> и запомнит<strong>е</strong> мат<strong>е</strong>риал.<br />

Выполняйт<strong>е</strong> упражн<strong>е</strong>ния, д<strong>е</strong>лайт<strong>е</strong> зам<strong>е</strong>тки.<br />

Мы включили упражн<strong>е</strong>ния в книгу, но выполнять<br />

их за вас н<strong>е</strong> собира<strong>е</strong>мся. И н<strong>е</strong> разглядывайт<strong>е</strong><br />

упражн<strong>е</strong>ния. Б<strong>е</strong>рит<strong>е</strong> карандаш и пишит<strong>е</strong>. Физич<strong>е</strong>ски<strong>е</strong><br />

д<strong>е</strong>йствия во вр<strong>е</strong>мяуч<strong>е</strong>ния повышают <strong>е</strong>го<br />

эфф<strong>е</strong>ктивность.<br />

Читайт<strong>е</strong> вр<strong>е</strong>зки.<br />

Это значит: читайт<strong>е</strong> всё. Вр<strong>е</strong>жи —часть основного<br />

мат<strong>е</strong>риала! Н<strong>е</strong> пропускайт<strong>е</strong> их.<br />

^ Н<strong>е</strong> читайт<strong>е</strong> други<strong>е</strong> книги посл<strong>е</strong> этой п<strong>е</strong>р<strong>е</strong>д сном.<br />

Часть обуч<strong>е</strong>ния (особ<strong>е</strong>нно п<strong>е</strong>р<strong>е</strong>нос информации<br />

в долгосрочную память) происходит посл<strong>е</strong> того,<br />

как вы откладыва<strong>е</strong>т<strong>е</strong> книгу. Ваш мозг н<strong>е</strong> сразу усваива<strong>е</strong>т<br />

информацию. Если во вр<strong>е</strong>мя обработки<br />

поступит новая информация, часть того, что вы<br />

узнали ран<strong>е</strong><strong>е</strong>, мож<strong>е</strong>т быть пот<strong>е</strong>ряна.<br />

П<strong>е</strong>йт<strong>е</strong> воду, и побольш<strong>е</strong>.<br />

Мозг лучш<strong>е</strong> вс<strong>е</strong>го работа<strong>е</strong>т в условиях высокой<br />

влажности. Д<strong>е</strong>гидратация (которая мож<strong>е</strong>т наступить<br />

<strong>е</strong>щ<strong>е</strong> до того, как вы почувству<strong>е</strong>т<strong>е</strong> жажду)<br />

снижа<strong>е</strong>т когнитивны<strong>е</strong> функции.<br />

Говорит<strong>е</strong> вслух.<br />

Р<strong>е</strong>чь активизиру<strong>е</strong>т други<strong>е</strong> участки мозга. Если<br />

вы пыта<strong>е</strong>т<strong>е</strong>сь что-то понять или получш<strong>е</strong> запомнить,<br />

произн<strong>е</strong>сит<strong>е</strong> вслух. А <strong>е</strong>щ<strong>е</strong> лучш<strong>е</strong> —попробуйт<strong>е</strong><br />

объяснить кому-нибудь другому. Вы буд<strong>е</strong>т<strong>е</strong><br />

быстр<strong>е</strong><strong>е</strong> усваивать мат<strong>е</strong>риал и, возможно, откро<strong>е</strong>т<strong>е</strong><br />

для с<strong>е</strong>бя что-то ново<strong>е</strong>.<br />

Прислушивайт<strong>е</strong>сь к сво<strong>е</strong>му мозгу.<br />

Сл<strong>е</strong>дит<strong>е</strong> за т<strong>е</strong>м, когда ваш мозг начина<strong>е</strong>т уставать.<br />

Если вы начина<strong>е</strong>т<strong>е</strong> пов<strong>е</strong>рхностно воспринимать<br />

мат<strong>е</strong>риал или забыва<strong>е</strong>т<strong>е</strong> только что прочитанно<strong>е</strong><br />

—пора сд<strong>е</strong>лать п<strong>е</strong>р<strong>е</strong>рыв.<br />

Чувствуйт<strong>е</strong>!<br />

Ваш мозг долж<strong>е</strong>н знать, что мат<strong>е</strong>риал книги<br />

д<strong>е</strong>йствит<strong>е</strong>льно важ<strong>е</strong>н. П<strong>е</strong>р<strong>е</strong>живайт<strong>е</strong> за г<strong>е</strong>ро<strong>е</strong>в<br />

наших историй. Придумывайт<strong>е</strong> собств<strong>е</strong>нны<strong>е</strong><br />

подписи к фотографиям. Поморщиться над н<strong>е</strong>удачной<br />

шуткой вс<strong>е</strong> равно лучш<strong>е</strong>, ч<strong>е</strong>м н<strong>е</strong> почувствовать<br />

нич<strong>е</strong>го.<br />

Пишит<strong>е</strong> программы!<br />

Научиться программировать можно только одним<br />

способом: писать код. Им<strong>е</strong>нно этим вам<br />

пр<strong>е</strong>дстоит заняться, читая книгу. Подобны<strong>е</strong> навыки<br />

лучш<strong>е</strong> вс<strong>е</strong>го закр<strong>е</strong>пляются практикой. В<br />

каждой глав<strong>е</strong> вы найд<strong>е</strong>т<strong>е</strong> упражн<strong>е</strong>ния. Н<strong>е</strong> пропускайт<strong>е</strong><br />

их. Н<strong>е</strong> бойт<strong>е</strong>сь подсмотр<strong>е</strong>ть в р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

задачи, <strong>е</strong>сли н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что д<strong>е</strong>лать дальш<strong>е</strong>! (Иногда<br />

можно застрять на эл<strong>е</strong>м<strong>е</strong>нтарном.) Но вс<strong>е</strong><br />

равно пытайт<strong>е</strong>сь р<strong>е</strong>шать задачи самостоят<strong>е</strong>льно.<br />

Пока ваш код н<strong>е</strong> начн<strong>е</strong>т работать, н<strong>е</strong> стоит п<strong>е</strong>р<strong>е</strong>ходить<br />

к сл<strong>е</strong>дующим страницам книги.<br />

дальш <strong>е</strong> > 29


как работать с этой книгой<br />

Ч то Вам потр<strong>е</strong>бу<strong>е</strong>тся<br />

Эта книга написана при помощи Visual <strong>C#</strong> 2010 Express Edition, работающ<strong>е</strong>й с <strong>C#</strong> 4.0 и .NET Framework<br />

4.0. Им<strong>е</strong>нно в этом прилож<strong>е</strong>нии были сняты вс<strong>е</strong> скриншоты, поэтому мы р<strong>е</strong>ком<strong>е</strong>нду<strong>е</strong>м установить<br />

с<strong>е</strong>б<strong>е</strong> им<strong>е</strong>нно <strong>е</strong>го. Если у вас установл<strong>е</strong>на Visual Studio 2010 Professional, Premium, Ultimate или Test<br />

Professional-в<strong>е</strong>рсия, картинки будут отличаться. Гд<strong>е</strong> н<strong>е</strong>обходимо, это буд<strong>е</strong>т оговариваться. Б<strong>е</strong>сплатно скачать<br />

в<strong>е</strong>рсию Express можно с сайта Microsoft.<br />

Настройка VISUAL STUDIO 2010 EXPRESS EDITION --------------------------------------------------<br />

Скачать и установить в<strong>е</strong>рсию Visual <strong>C#</strong> 2010 Express довольно л<strong>е</strong>гко. Дистрибутив программы находится<br />

зд<strong>е</strong>сь:<br />

h t t p : / / w w w . m i c r o s o f t . c o m / e x p r e s s / d o w n l o a d s /<br />

Для выполн<strong>е</strong>ния упражн<strong>е</strong>ний из этой книги вам н<strong>е</strong> потр<strong>е</strong>буются никаки<strong>е</strong> дополнит<strong>е</strong>льны<strong>е</strong> парам<strong>е</strong>тры<br />

установки, но вы мож<strong>е</strong>т<strong>е</strong> воспользоваться ими, <strong>е</strong>сли хотит<strong>е</strong>.<br />

IfistaMatkm Options<br />

Sefect iht Gp^on^ produst(s) you wouki ice to îTBîsi.'<br />

O Q * ^ I O »-2010<br />

^HiCK»softS


вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

информация<br />

Это уч<strong>е</strong>бник, а н<strong>е</strong> справочник. Мы нам<strong>е</strong>р<strong>е</strong>нно убрали из книги вс<strong>е</strong>, что<br />

могло бы пом<strong>е</strong>шать изуч<strong>е</strong>нию мат<strong>е</strong>риала, над которым вы работа<strong>е</strong>т<strong>е</strong>. И<br />

при п<strong>е</strong>рвом чт<strong>е</strong>нии книги начинать сл<strong>е</strong>ду<strong>е</strong>т с самого начала, потому что<br />

книга пр<strong>е</strong>дполага<strong>е</strong>т наличи<strong>е</strong> у читат<strong>е</strong>ля опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных знаний и опыта.<br />

Для наглядного пр<strong>е</strong>доставл<strong>е</strong>ния<br />

сложит<br />

п о н я т и й б кнмг<strong>е</strong><br />

исТользун>тся дыагрйммс>|-<br />

I<br />

Упраж н<strong>е</strong>ния обязат<strong>е</strong>льны к вы полн<strong>е</strong>нию .<br />

Упражн<strong>е</strong>ния и задачи являются частью основного сод<strong>е</strong>ржания книги,<br />

а н<strong>е</strong> дополнит<strong>е</strong>льным мат<strong>е</strong>риалом. Н<strong>е</strong>которы<strong>е</strong> помогают запомнить<br />

новую информацию, н<strong>е</strong>которы<strong>е</strong> —лучш<strong>е</strong> понять <strong>е</strong><strong>е</strong>, а н<strong>е</strong>которы<strong>е</strong> —научиться<br />

прим<strong>е</strong>нять <strong>е</strong><strong>е</strong> на практик<strong>е</strong>. Н<strong>е</strong>обязат<strong>е</strong>льными являются только<br />

«Р<strong>е</strong>бусы в басс<strong>е</strong>йн<strong>е</strong>», но сл<strong>е</strong>ду<strong>е</strong>т помнить, что они хорошо развивают логич<strong>е</strong>ско<strong>е</strong><br />

мышл<strong>е</strong>ни<strong>е</strong>.<br />

П овтор<strong>е</strong>ни<strong>е</strong> прим <strong>е</strong>ня<strong>е</strong>тся нам <strong>е</strong>р<strong>е</strong>нно.<br />

У книг этой с<strong>е</strong>рии <strong>е</strong>сть одна принципиальная особ<strong>е</strong>нность: мы хотим,<br />

чтобы вы д<strong>е</strong>йствит<strong>е</strong>льно хорошо усвоили мат<strong>е</strong>риал. И чтобы вы запомнили<br />

вс<strong>е</strong>, что узнали. Большинство справочников н<strong>е</strong> ставит сво<strong>е</strong>й ц<strong>е</strong>лью<br />

усп<strong>е</strong>шно<strong>е</strong> запоминани<strong>е</strong>, но это н<strong>е</strong> справочник, а уч<strong>е</strong>бник, поэтому н<strong>е</strong>которы<strong>е</strong><br />

конц<strong>е</strong>пции излагаются в книг<strong>е</strong> по н<strong>е</strong>сколько раз.<br />

В ы п о л н я й т <strong>е</strong><br />

вс<strong>е</strong> упражн<strong>е</strong>ния<br />

этого разд<strong>е</strong>ла-<br />

iserrt<br />

Возьми в руку карандаш<br />

Вы полняйт<strong>е</strong> вс<strong>е</strong> упражн<strong>е</strong>ния!<br />

Пр<strong>е</strong>дполага<strong>е</strong>тся, что читат<strong>е</strong>ли этой книги хотят научиться программировать<br />

на С#. Что им н<strong>е</strong> т<strong>е</strong>рпится приступить к написанию кода. И мы<br />

дали им массу возможност<strong>е</strong>й сд<strong>е</strong>лать это. В фрагм<strong>е</strong>нтах, пом<strong>е</strong>ч<strong>е</strong>нных<br />

значком Ут^ажн<strong>е</strong>ни<strong>е</strong>!, д<strong>е</strong>монстриру<strong>е</strong>тся пошагово<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> конкр<strong>е</strong>тных<br />

задач. А вот картинка с кроссовками сигнализиру<strong>е</strong>т о н<strong>е</strong>обходимости самостоят<strong>е</strong>льного<br />

поиска р<strong>е</strong>ш<strong>е</strong>ния. Н<strong>е</strong> бойт<strong>е</strong>сь подглядывать на страницу<br />

с отв<strong>е</strong>том! Просто помнит<strong>е</strong>, что информация лучш<strong>е</strong> вс<strong>е</strong>го усваива<strong>е</strong>тся,<br />

когда вы пыта<strong>е</strong>т<strong>е</strong>сь р<strong>е</strong>шать задачки б<strong>е</strong>з посторонн<strong>е</strong>й помощи.<br />

Код для упражн<strong>е</strong>ний из книги можно скачать зд<strong>е</strong>сь<br />

h t t p ; / / w w w . h e a d f i r s t l a b s . c o m / b o o k s / h f c s h a r p /<br />

Упраж н<strong>е</strong>ния «М озговой ш турм » н<strong>е</strong> им <strong>е</strong>ю т отв<strong>е</strong>тов.<br />

В н<strong>е</strong>которых из них правильного отв<strong>е</strong>та вообщ<strong>е</strong> н<strong>е</strong>т, в других вы должны<br />

сами р<strong>е</strong>шить, насколько правильны ваши отв<strong>е</strong>ты (это явля<strong>е</strong>тся частью<br />

проц<strong>е</strong>сса обуч<strong>е</strong>ния). В н<strong>е</strong>которых упражн<strong>е</strong>ниях «Мозговой штурм» приводятся<br />

подсказки, которы<strong>е</strong> помогут вам найти нужно<strong>е</strong> направл<strong>е</strong>ни<strong>е</strong>.<br />

Н<strong>е</strong> >^ропускайт<strong>е</strong> эти<br />

хотит<strong>е</strong> изучить С*.<br />

К<br />

н<strong>е</strong>ни<strong>е</strong><br />

А э т и м значком<br />

пом<strong>е</strong>ч<strong>е</strong>ны дополнит<strong>е</strong>льны<strong>е</strong><br />

упражн<strong>е</strong>ния для<br />

любит<strong>е</strong>л<strong>е</strong>й логич<strong>е</strong>ских<br />

задач.<br />

дальш <strong>е</strong> ► 31


обзор команды<br />

Т<strong>е</strong>хнич<strong>е</strong>ски<strong>е</strong> р<strong>е</strong>ц<strong>е</strong>нз<strong>е</strong>нты<br />

Лиза К<strong>е</strong>льн<strong>е</strong>р<br />

!


вв<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

Благодарности<br />

Р<strong>е</strong>дакторы<br />

Мы хотим поблагодарить наших р<strong>е</strong>дакторов Б р <strong>е</strong> т т а<br />

Маклафлина и Кортни Нэш за работу над этой книгой.<br />

Бр<strong>е</strong>тт был автором большинства рассказов, а ид<strong>е</strong>я главы 14<br />

принадл<strong>е</strong>жит <strong>е</strong>му полностью. Спасибо!<br />

Бр<strong>е</strong>т т Маклафлин<br />

Кортни Нэш<br />

Команда издат<strong>е</strong>лг>ства O’Reilly<br />

Лу —зам<strong>е</strong>чат<strong>е</strong>льный дизайн<strong>е</strong>р, постигший вс<strong>е</strong> с<strong>е</strong>кр<strong>е</strong>ты сво<strong>е</strong>й проф<strong>е</strong>ссии.<br />

Она пров<strong>е</strong>ла н<strong>е</strong>забыва<strong>е</strong>мы<strong>е</strong> часы и сд<strong>е</strong>лала для книги<br />

потрясающи<strong>е</strong> графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты. Если вы видит<strong>е</strong> в книг<strong>е</strong><br />

н<strong>е</strong>что фантастич<strong>е</strong>ско<strong>е</strong> —благодарит<strong>е</strong> <strong>е</strong><strong>е</strong> (и <strong>е</strong><strong>е</strong> ум<strong>е</strong>ни<strong>е</strong> работать<br />

с InDesign). Вс<strong>е</strong> комиксы являются <strong>е</strong><strong>е</strong> твор<strong>е</strong>ни<strong>е</strong>м. Спасибо огромно<strong>е</strong>,<br />

Лу! С тобой потрясающ<strong>е</strong> приятно работать!<br />

Т<br />

Санд<strong>е</strong>рс Кл<strong>е</strong>йнф<strong>е</strong>лд<br />

В O ’Reilly оч<strong>е</strong>нь много сотрудников, которых мы хот<strong>е</strong>ли бы поблагодарить,<br />

над<strong>е</strong><strong>е</strong>мся, что никого н<strong>е</strong> забыли. Особо<strong>е</strong> спасибо<br />

выпускающ<strong>е</strong>му р<strong>е</strong>дактору Раш<strong>е</strong>ль Монаган и инд<strong>е</strong>ксатору Люси<br />

Хаскинс, Эмили Квил за отм<strong>е</strong>нную корр<strong>е</strong>ктуру, Рону Билодо, который<br />

н<strong>е</strong> жал<strong>е</strong>л сво<strong>е</strong>го вр<strong>е</strong>м<strong>е</strong>ни на эксп<strong>е</strong>ртны<strong>е</strong> заключ<strong>е</strong>ния, Санд<strong>е</strong>рсу<br />

Кл<strong>е</strong>йнф<strong>е</strong>лду за пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> пров<strong>е</strong>рить вс<strong>е</strong> <strong>е</strong>щ<strong>е</strong> один раз —вс<strong>е</strong>м,<br />

кто помог подготовить эту книгу к п<strong>е</strong>чати в р<strong>е</strong>кордно коротки<strong>е</strong> сроки.<br />

Мы любим Мэри Тр<strong>е</strong>сл<strong>е</strong>р и жд<strong>е</strong>м случая поработать с н<strong>е</strong>й снова!<br />

Жм<strong>е</strong>м руку нашим друзьям и р<strong>е</strong>дакторам Энди Сраму и Майку Х<strong>е</strong>ндриксону.<br />

И за то, что вы с<strong>е</strong>йчас чита<strong>е</strong>т<strong>е</strong> эту книгу, нужно поблагодарить<br />

лучшую команду р<strong>е</strong>кламистов: Марси Х<strong>е</strong>нон, Сару П<strong>е</strong>йтон,<br />

Мэри Ротман, <strong>Дж</strong><strong>е</strong>ссику Бойд, К<strong>е</strong>трин Бар<strong>е</strong>т и остальных сотрудников<br />

из города С<strong>е</strong>вастополь, штат Калифорния.<br />

дальш <strong>е</strong> > 33


1 = * <strong>е</strong> к ш и Б н о с т ь с<br />

Визуальны<strong>е</strong> прилож<strong>е</strong>ния<br />

за 10 минут<br />

Хотит<strong>е</strong> программировать д<strong>е</strong>йствит<strong>е</strong>льно быстро? C # — это<br />

м ощ ны й я зы к програм мирования. Благодаря V isual Studio вам<br />

н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся писать н<strong>е</strong>понятный код, чтобы заставить кнопку работать.<br />

Вм<strong>е</strong>сто того чтобы запоминать парам<strong>е</strong>тры м<strong>е</strong>тода для им<strong>е</strong>ни<br />

и для ярлыка кнопки, вы смож<strong>е</strong>т<strong>е</strong> сф о куси р оват ься на дост иж <strong>е</strong>­<br />

нии р<strong>е</strong>зульт ат а. Звучит заманчиво? Тогда п<strong>е</strong>р<strong>е</strong>в<strong>е</strong>рнит<strong>е</strong> страницу<br />

и приступим к д<strong>е</strong>лу.


с c# это л<strong>е</strong>гко<br />

Зач<strong>е</strong>м В ш изучать C #<br />

lACPj или Инт<strong>е</strong>грированная<br />

<strong>C#</strong> и ИСР Visual Studio обл<strong>е</strong>гчают и ускоряют проц<strong>е</strong>сс Ср<strong>е</strong>да Разработки, --<br />

написания кода.<br />

э т о программа для<br />

р<strong>е</strong>дактирования кода,<br />

управл<strong>е</strong>ния файлами<br />

_ , ^ и публикации про<strong>е</strong>ктов.<br />

Задачи, которы<strong>е</strong> за бас р<strong>е</strong>ша<strong>е</strong>т UCP<br />

Чтобы пом<strong>е</strong>стить на форму кнопку, вам потр<strong>е</strong>буются<br />

больши<strong>е</strong> куски повторяющ<strong>е</strong>гося кода.<br />

v o id I n itia H .e C o m p o n e n tT ,<br />

t h i s . S uspSi,|y“ “, f ■W ndow B. Porm a. B u tto n () ;<br />

/ / b u t t o n l<br />

i n , . s i . e „ s , . 3 , ,<br />

56) ;<br />

/ / Pom.1 "'“ '‘^ '" ’“ “ ‘* l « < t h i a . b u t t o n l _ c l i c k ) , .<br />

‘ s t a t i c claBB p ro g ram<br />

' / / S ” S S ’ e n t r y p o i n t f o r t h e a p p l i c a t i o n .<br />

/ / / < /sum mary><br />

S S ’^^f.MainO<br />

' Wplic.tion.|ngleVi-al|tyl«^^^^<br />

)<br />

t h i s . R e s u m e L a y o u t ( f a l s e ) ;<br />

f<br />

Пр<strong>е</strong>имущ<strong>е</strong>ства Visual Studio u C #<br />

Язык С#, оптимизированный для программирования<br />

в Windows, вм<strong>е</strong>ст<strong>е</strong> с Visual Studio позволя<strong>е</strong>т<br />

сфокусироваться на н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нных задачах.<br />

Встро<strong>е</strong>нны<strong>е</strong> в С*<br />

j^g-f FrAmeworK<br />

i / i r p V i S M ^ !<br />

Studio с т р и ^ '<br />

избавляют » f .<br />

0^ рутинно<strong>е</strong> paoom<br />

Р<strong>е</strong>ш<strong>е</strong>ния .NET<br />

Framework<br />

C =3I<br />

доступ К данным<br />

i ÿ Your Program<br />

T ‘ТОЛЬКО личщ<strong>е</strong>,<br />

f ‘глядит, но a<br />

^


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

С#, UCP Visual Studio много<strong>е</strong> ynpoutaiom<br />

Язык <strong>C#</strong> и Visual Studio позволят б<strong>е</strong>з дополнит<strong>е</strong>льных<br />

усилий выполнять сл<strong>е</strong>дующи<strong>е</strong> задачи:<br />

Быстро создавать прилож<strong>е</strong>ния. Программировать на <strong>C#</strong> оч<strong>е</strong>нь просто.<br />

Это мощный, л<strong>е</strong>гко осваива<strong>е</strong>мый язык, а Visual Studio позволя<strong>е</strong>т автоматизировать<br />

большинство проц<strong>е</strong>ссов.<br />

О<br />

О<br />

Разрабатывать красивый пользоват<strong>е</strong>льский инт<strong>е</strong>рд><strong>е</strong>йс. Инструм<strong>е</strong>нт<br />

Form Designer в Visual Studio пр<strong>е</strong>враща<strong>е</strong>т создани<strong>е</strong> в<strong>е</strong>ликол<strong>е</strong>пного пользоват<strong>е</strong>льского<br />

инт<strong>е</strong>рф<strong>е</strong>йса в одну из самых увл<strong>е</strong>кат<strong>е</strong>льных задач при разработк<strong>е</strong><br />

прилож<strong>е</strong>ний на С#. Вам больш<strong>е</strong> н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся тратить часы на<br />

написани<strong>е</strong> графич<strong>е</strong>ских эл<strong>е</strong>м<strong>е</strong>нтов с нуля.<br />

Создавать базы данны х и взаимод<strong>е</strong>йствовать с н и м и . ИСР снабж<strong>е</strong>на<br />

простым инт<strong>е</strong>рф<strong>е</strong>йсом для создания баз данных, которы<strong>е</strong> зат<strong>е</strong>м л<strong>е</strong>гко<br />

инт<strong>е</strong>грируются в SQL Server Compact Edition и други<strong>е</strong> популярны<strong>е</strong> прилож<strong>е</strong>ния.<br />

1окусироваться на р<strong>е</strong>ш <strong>е</strong>нии РЕАЛЬНЫ Х пробл<strong>е</strong>м. За кон<strong>е</strong>чный р<strong>е</strong>зультат<br />

работы, разум<strong>е</strong><strong>е</strong>тся, отв<strong>е</strong>ча<strong>е</strong>т<strong>е</strong> вы и только вы. Но ИСР позволя<strong>е</strong>т<br />

конц<strong>е</strong>нтрироваться на глобальных в<strong>е</strong>щах, взяв на с<strong>е</strong>бя:<br />

★<br />

★<br />

★<br />

★<br />

сл<strong>е</strong>ж<strong>е</strong>ни<strong>е</strong> за вс<strong>е</strong>ми про<strong>е</strong>ктами;<br />

упрощ<strong>е</strong>нно<strong>е</strong> р<strong>е</strong>дактировани<strong>е</strong> кода;<br />

отсл<strong>е</strong>живани<strong>е</strong> графики, аудиофайлов, значков и прочих р<strong>е</strong>сурсов;<br />

управл<strong>е</strong>ни<strong>е</strong> базами данных и взаимод<strong>е</strong>йстви<strong>е</strong> с ними.<br />

Т<strong>е</strong>п<strong>е</strong>рь вм<strong>е</strong>сто рутинного написания кода вы мож<strong>е</strong>т<strong>е</strong> потратить вр<strong>е</strong>мя на<br />

создани<strong>е</strong> потрясающих программ.<br />

Скоро бы пойм<strong>е</strong>т<strong>е</strong>,<br />

что мы им<strong>е</strong><strong>е</strong>м в виду.<br />

дальш<strong>е</strong> > 37


помогит<strong>е</strong> начальнику<br />

11зба6ьт<strong>е</strong> дир<strong>е</strong>ктора о т бумаг<br />

в объ<strong>е</strong>ктвильской фирм<strong>е</strong> по производству бумаги появился новый исполнит<strong>е</strong>льный<br />

дир<strong>е</strong>ктор. Он любит п<strong>е</strong>ши<strong>е</strong> прогулки, коф<strong>е</strong> и природу... и с ц<strong>е</strong>лью<br />

сохран<strong>е</strong>ния л<strong>е</strong>сов р<strong>е</strong>шил п<strong>е</strong>р<strong>е</strong>йти на б<strong>е</strong>збумажный докум<strong>е</strong>нтооборот. На выходны<strong>е</strong><br />

он у<strong>е</strong>хал кататься на лыжах в Асп<strong>е</strong>н, а вам приказал к пон<strong>е</strong>д<strong>е</strong>льнику<br />

написать программу для хран<strong>е</strong>ния контактной информации. Если этого<br />

н<strong>е</strong> сд<strong>е</strong>лать... хм... вы составит<strong>е</strong> компанию пр<strong>е</strong>дыдущ<strong>е</strong>му дир<strong>е</strong>ктору ваш<strong>е</strong>й<br />

фирмы, который ищ<strong>е</strong>т новую работу.<br />

Имя: Laverne Smith<br />

Фирма: XYZ Industries<br />

Т<strong>е</strong>л<strong>е</strong>фон; ( z i z ) s s s - s i z ‘i<br />

Email:<br />

Кли<strong>е</strong>нт; Yes<br />

LavemeSmith^XyZindustriescoM<br />

По<strong>е</strong>л, звонок: 05/я&/07<br />

I<br />

Найдит<strong>е</strong> способ<br />

быстро п<strong>е</strong>р<strong>е</strong>кинуть<br />

эти данны<strong>е</strong> на<br />

ноутбук дир<strong>е</strong>ктора.<br />

“ " Т “", .Г'<br />

■Muirtiiiiln'ir<br />

..,- 1 - W « * ,<br />

чш—<br />

38 глава 1


эфф<strong>е</strong>ктивность с С#<br />

П<strong>е</strong>р<strong>е</strong>д началом работы быяснит<strong>е</strong>, что им<strong>е</strong>нно<br />

ну)кно пользоват<strong>е</strong>лю<br />

П<strong>е</strong>р<strong>е</strong>д началом работы над любым прилож<strong>е</strong>ни<strong>е</strong>м нужно понять,<br />

кто буд<strong>е</strong>т <strong>е</strong>го использовать и каким ожиданиям оно должно соотв<strong>е</strong>тствовать.<br />

Дир<strong>е</strong>ктор хоч<strong>е</strong>т, чтобы программа работала н<strong>е</strong> только<br />

на <strong>е</strong>го офисном компьют<strong>е</strong>р<strong>е</strong>, но и на <strong>е</strong>го ноутбук<strong>е</strong>.<br />

Значит, вам потр<strong>е</strong>бу<strong>е</strong>тся инсталлятор, который позволит<br />

пом<strong>е</strong>стить нужны<strong>е</strong> файлы на любой компьют<strong>е</strong>р.<br />

Так как прилож<strong>е</strong>ни<strong>е</strong> должно<br />

работам.^ н<strong>е</strong> молько в офис<strong>е</strong>,<br />

но и на ноутбук<strong>е</strong> дир<strong>е</strong>ктора,<br />

б<strong>е</strong>з установщика н<strong>е</strong> обойтись.<br />

Другим сотрудникам фирмы такж<strong>е</strong> понадобится доступ<br />

к контактной информации. Как ж<strong>е</strong> в противном<br />

случа<strong>е</strong> они сформируют списки рассылки, чтобы<br />

сд<strong>е</strong>лать фирму лид<strong>е</strong>ром по продаж<strong>е</strong> бумаги.<br />

П<strong>е</strong>р<strong>е</strong>д началом работы<br />

над программой вс<strong>е</strong>гда<br />

думайт<strong>е</strong> о нуждах<br />

кон<strong>е</strong>чных пользоват<strong>е</strong>л<strong>е</strong>й,<br />

только так можно<br />

создать по-настоящ<strong>е</strong>му<br />

кач<strong>е</strong>ств<strong>е</strong>нный продукт!<br />

дальш<strong>е</strong> ► 39


ваша ц<strong>е</strong>ль<br />

Ч т о мы собира<strong>е</strong>мся сд<strong>е</strong>лать<br />

Нам потр<strong>е</strong>бу<strong>е</strong>тся прилож<strong>е</strong>ни<strong>е</strong> с графич<strong>е</strong>ским инт<strong>е</strong>рф<strong>е</strong>йсом<br />

пользоват<strong>е</strong>ля, объ<strong>е</strong>кты, взаимод<strong>е</strong>йствующи<strong>е</strong> с базой данных,<br />

собств<strong>е</strong>нно база данных и программа установки. Вся эта<br />

огромная с виду работа буд<strong>е</strong>т прод<strong>е</strong>лана к концу этой главы.<br />

Вот структура наш<strong>е</strong>й будущ<strong>е</strong>й программы:<br />

В<strong>е</strong>>|<br />

упрлбд<strong>е</strong>ния.<br />

э л <strong>е</strong> м <strong>е</strong> и ^ б<br />

Визуальны<strong>е</strong> объ<strong>е</strong>кты .НЕТ Объ<strong>е</strong>кты б»ы данных .N£T | ко „,кд а u p d a te |<br />

Команда DELETE ^<br />

ОЭь<strong>е</strong>ктВ«'*''<br />

Э ти обь<strong>е</strong>кты являются<br />

эл<strong>е</strong>м<strong>е</strong>нтами управл<strong>е</strong>ния<br />

адр<strong>е</strong>сной книги.<br />

'Ш ^<br />

\ г Ш у -<br />

обгр<br />

40 глава 1<br />

„ „ „ Z I


эфф<strong>е</strong>ктивность с С#<br />

Готовая программа<br />

пом<strong>е</strong>-ща<strong>е</strong>тсй внутрь<br />

инсталлятора \лЛпйо^5.<br />

Хранилищ<strong>е</strong> данных<br />

инструм<strong>е</strong>нты Вн<strong>е</strong>др<strong>е</strong>ния<br />

Ол<br />

б аза данных<br />

'ч<br />

4 л<br />

I<br />

.<strong>е</strong> х <strong>е</strong><br />

Файл<br />

программы<br />

Отд<strong>е</strong> -<br />

лу продаж<br />

остан<strong>е</strong>тся<br />

>^олько за ~<br />

1лустить<br />

этот инсталлятор.<br />

3<br />

дальш<strong>е</strong> > 41


приступим<br />

Э то Вы д<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> 6 Visual Studio<br />

Запустит<strong>е</strong> Visual Studio, <strong>е</strong>сли вы <strong>е</strong>щ<strong>е</strong> это н<strong>е</strong> сд<strong>е</strong>лали. Пропустит<strong>е</strong> начальную страницу и выб<strong>е</strong>рит<strong>е</strong> в м<strong>е</strong>ню<br />

File команду New Project. В открывш<strong>е</strong>мся окн<strong>е</strong> диалога New Project выб<strong>е</strong>рит<strong>е</strong> тип про<strong>е</strong>кта W indows Form s<br />

Application, а в т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong> Name в нижн<strong>е</strong>й части окна вв<strong>е</strong>дит<strong>е</strong> названи<strong>е</strong> про<strong>е</strong>кта Contacts.<br />

Im t^T em p t^es<br />

....<br />

i Srai^hbsSailedTempiatti<br />

УвиЫС»<br />

№tdov«sFt»msAf)pn<br />

Visual <strong>C#</strong><br />

о С Ш о |= > о Ж Н ь 1<br />

Consol« Application<br />

; : Empty Project<br />

Vtsuel<strong>C#</strong><br />

Visu»! С *<br />

В ваш<strong>е</strong>й ИСР вс<strong>е</strong> мож<strong>е</strong>т<br />

выгляд<strong>е</strong>ть по-другому.<br />

На рисунк<strong>е</strong> показан вид<br />

окна New Project в Visual<br />

Studio 2010 Express Edition.<br />

В Professional или Team<br />

Foundation edition оно мож<strong>е</strong>т<br />

выгляд<strong>е</strong>ть по-другому.<br />

Но суть <strong>е</strong>го от этого<br />

н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся.<br />

А это Visual Studio д<strong>е</strong>ла<strong>е</strong>т за Вас<br />

в мом<strong>е</strong>нт сохран<strong>е</strong>ния про<strong>е</strong>кта ИСР созда<strong>е</strong>т файлы F o rm l. cs,<br />

F o rm l. D e s ig n e r. cs и Program , cs. Они добавляются в окно<br />

Solution Explorer и по умолчанию сохраняются в папк<strong>е</strong> Му<br />

D ocum ents\V isual S tu d io 2 0 1 0 \P r o je c ts \C o n ta c ts \.<br />

Этот файл сод<strong>е</strong>ржит<br />

код, опр<strong>е</strong>д<strong>е</strong>ляющий<br />

пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> формы.<br />

Команда Save All<br />

■из м<strong>е</strong>ню File сохраня<strong>е</strong>т<br />

вс<strong>е</strong> открыты<strong>е</strong> файлы,<br />

в то вр<strong>е</strong>мя как команда<br />

Save — только файл,<br />

активный в данный<br />

мом<strong>е</strong>нт.<br />

^Од, опр<strong>е</strong>д<strong>е</strong>ляющий<br />

форму и <strong>е</strong><strong>е</strong> объ<strong>е</strong>кты.<br />

at<br />

Forml.cs<br />

Forml.Deslgner.cs<br />

42 глава 1<br />

ßce эти файлы Visual Studio<br />

созда<strong>е</strong>т автоматич<strong>е</strong>ски.


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

«.ВВозьми О ЗІ в руку карандаш<br />

Ниж<strong>е</strong> показан возможный вид экрана. Вы должны понимать назнач<strong>е</strong>ни<strong>е</strong> большинства окон<br />

ч<br />

и файлов. Уб<strong>е</strong>дит<strong>е</strong>сь в наличии пан<strong>е</strong>л<strong>е</strong>й Toolbox и Error List, вызыва<strong>е</strong>мых одноим<strong>е</strong>нными<br />

командами м<strong>е</strong>ню View » Other Windows. В пусты<strong>е</strong> строки впишит<strong>е</strong> назнач<strong>е</strong>ни<strong>е</strong> каждой части<br />

ИСР, как показано в прим<strong>е</strong>р<strong>е</strong>.<br />

^^.^■й^.выбираются<br />

р абот ы .................<br />

Если ваша ИСР выглядит<br />

по-другому, воспользуйт<strong>е</strong>сь<br />

командой W indow»Reset<br />

Это окно было<br />

ув<strong>е</strong>лич<strong>е</strong>но,, чтобы<br />

дать вам больш<strong>е</strong><br />

пространства.<br />

дальш<strong>е</strong> > 43


изучи ИСР<br />

Возьми в руку карандаш<br />

Зд<strong>е</strong>сь выдираются<br />

6Ш6НИ6<br />

Итак, вы описали назнач<strong>е</strong>ни<strong>е</strong> различных част<strong>е</strong>й ИСР Visual Studio С#.<br />

Зд<strong>е</strong>сь вы мож<strong>е</strong>т<strong>е</strong> сравнить написанно<strong>е</strong> с правильными вариантами<br />

отв<strong>е</strong>та.<br />

ЗЭ<strong>е</strong>сь собраны<br />

визуальны<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния, ^<br />

которы<strong>е</strong> \ ®<br />

можно<br />

п<strong>е</strong>р<strong>е</strong>тащить<br />

на форму.<br />

зд<strong>е</strong>сь<br />

\^оказаны<br />

свойства<br />

выбранного<br />

эд<strong>е</strong>м<strong>е</strong>нилд<br />

управл<strong>е</strong>ния<br />

суормы-<br />

Formi.cs и<br />

•появляются<br />

В окн<strong>е</strong> Error List<br />

отображаются<br />

вкравши<strong>е</strong>ся в коо<br />

оилибки.<br />

Щ <strong>е</strong>лчок на этой<br />

кнопк<strong>е</strong> вклю ча<strong>е</strong>т<br />

и отклю ча<strong>е</strong>т<br />

ф ункцию<br />

автоматич<strong>е</strong>ского<br />

сворачивания<br />

окна. У пан<strong>е</strong>ли<br />

Toolbox она<br />

вклю ч<strong>е</strong>на<br />

по ум олчанию .<br />

44 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

_ Часзцо<br />

ЧадаБа<strong>е</strong>Мы<strong>е</strong><br />

Б оЦ Р оСь !<br />

Если код созда<strong>е</strong>тся автоматич<strong>е</strong>ски,<br />

н<strong>е</strong> сводится ли изуч<strong>е</strong>ни<strong>е</strong> <strong>C#</strong> к изуч<strong>е</strong>нию<br />

функциональности ИСР?<br />

I Н<strong>е</strong>т. ИСР помож<strong>е</strong>т вам в выбор<strong>е</strong><br />

начальных точ<strong>е</strong>к или изм<strong>е</strong>нии свойств<br />

эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния форм, но понять,<br />

какую работу должна выполнять программа<br />

и как достичь поставл<strong>е</strong>нной ц<strong>е</strong>ли,<br />

мож<strong>е</strong>т<strong>е</strong> только вы.<br />

Я создал новый про<strong>е</strong>кт, но н<strong>е</strong><br />

наш<strong>е</strong>л <strong>е</strong>го в папк<strong>е</strong> Projects, влож<strong>е</strong>нной<br />

в папку Му Documents. Поч<strong>е</strong>му?<br />

Q ; Новы<strong>е</strong> про<strong>е</strong>кты Visual Studio 2010<br />

Express пом<strong>е</strong>ща<strong>е</strong>т в папку L o c a l<br />

S e t t i n g s \ A p p l i c a t i o n<br />

D a t a \ T e m p o r a r y P r o j e c t s . При<br />

п<strong>е</strong>рвом сохран<strong>е</strong>нии вам пр<strong>е</strong>длага<strong>е</strong>тся<br />

задать ново<strong>е</strong> имя и пом<strong>е</strong>стить в папку<br />

Му D o c u m e n t s \V is u a l S t u d i o<br />

2 0 l 0 \ P r o j e c t s . При открытии нового<br />

про<strong>е</strong>кта или закрытии вр<strong>е</strong>м<strong>е</strong>нного, вам<br />

пр<strong>е</strong>длага<strong>е</strong>тся сохранить или удалить<br />

посл<strong>е</strong>дний. (ПРИМЕЧАНИЕ: Отличны<strong>е</strong><br />

от Express в<strong>е</strong>рсии Visual Studio н<strong>е</strong> используют<br />

папку вр<strong>е</strong>м<strong>е</strong>нных про<strong>е</strong>ктов,<br />

а пом<strong>е</strong>щают файлы н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно<br />

в папку Projects!)<br />

Что д<strong>е</strong>лать с н<strong>е</strong>нужным кодом,<br />

автоматич<strong>е</strong>ски созданным ИСР?<br />

; Его можно отр<strong>е</strong>дактировать. Если<br />

по умолчанию создан н<strong>е</strong> тот код, который<br />

вам тр<strong>е</strong>бу<strong>е</strong>тся, достаточно вн<strong>е</strong>сти в н<strong>е</strong>го<br />

н<strong>е</strong>обходимы<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ния — вручную или<br />

ср<strong>е</strong>дствами пользоват<strong>е</strong>льского инт<strong>е</strong>рф<strong>е</strong>йса<br />

ИСР.<br />

я загрузил и установил б<strong>е</strong>сплатную<br />

в<strong>е</strong>рсию Visual Studio Express.<br />

Достаточно ли этого для выполн<strong>е</strong>ния<br />

упражн<strong>е</strong>ний из данной книги или мн<strong>е</strong><br />

потр<strong>е</strong>бу<strong>е</strong>тся купить другую в<strong>е</strong>рсию<br />

прилож<strong>е</strong>ния?<br />

! Вс<strong>е</strong> упражн<strong>е</strong>ния из этой книги выполняются<br />

в б<strong>е</strong>сплатной в<strong>е</strong>рсии Visual<br />

Studio (которую можно получить на сайт<strong>е</strong><br />

Microsoft). Различия м<strong>е</strong>жду в<strong>е</strong>рсиями<br />

Express, Professional и Team Foundation<br />

никак н<strong>е</strong> повлияют на проц<strong>е</strong>сс написания<br />

профамм на <strong>C#</strong> и создания полнофункциональных<br />

прилож<strong>е</strong>ний.<br />

Mojy ли я п<strong>е</strong>р<strong>е</strong>им<strong>е</strong>новывать файлы,<br />

созданный ИСР?<br />

Q ; Кон<strong>е</strong>чно. Новому про<strong>е</strong>кту ИСР<br />

по умолчанию присваива<strong>е</strong>т имя F o rm l<br />

(F o r m l. c s , F o r m l. D e s i g n e r . c s<br />

и F o r m l. r e s x ). Ho <strong>е</strong>го можно пом<strong>е</strong>нять<br />

в окн<strong>е</strong> Solution Explorer. По умолчанию<br />

им<strong>е</strong>на файлов совпадают с им<strong>е</strong>н<strong>е</strong>м<br />

формы. Как можно вид<strong>е</strong>ть в окн<strong>е</strong> Properties,<br />

их изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> н<strong>е</strong> влия<strong>е</strong>т на имя формы.<br />

Посл<strong>е</strong>дн<strong>е</strong><strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong>м поля<br />

(Name) в окн<strong>е</strong> Properties. Имя файла при<br />

этом оста<strong>е</strong>тся т<strong>е</strong>м ж<strong>е</strong>.<br />

Для файлов, форм (и других част<strong>е</strong>й программы)<br />

можно выбирать произвольны<strong>е</strong><br />

им<strong>е</strong>на. Выбор значимых им<strong>е</strong>н обл<strong>е</strong>гча<strong>е</strong>т<br />

работу с программой, но об этом пока<br />

можно н<strong>е</strong> думать.<br />

Окно ИСР отлича<strong>е</strong>тся от показанного<br />

на картинк<strong>е</strong> в книг<strong>е</strong>. Что д<strong>е</strong>лать?<br />

; Для п<strong>е</strong>р<strong>е</strong>хода к настройкам по умолчанию<br />

выб<strong>е</strong>рит<strong>е</strong> команду Reset Window<br />

Layout в м<strong>е</strong>ню Window, зат<strong>е</strong>м воспользуйт<strong>е</strong>сь<br />

командами м<strong>е</strong>ню View » Other<br />

Windows, чтобы открыть н<strong>е</strong>достающи<strong>е</strong><br />

окна.<br />

Visual Studio<br />

г<strong>е</strong>н<strong>е</strong>риру<strong>е</strong>т код,<br />

который можно<br />

использовать<br />

как основу для<br />

программы.<br />

Но только вы<br />

отв<strong>е</strong>ча<strong>е</strong>т<strong>е</strong> за<br />

корр<strong>е</strong>ктную работу<br />

это11 программы.<br />

дальш<strong>е</strong> > 45


лучш<strong>е</strong> один раз увид<strong>е</strong>ть<br />

Созда<strong>е</strong>м пользоват<strong>е</strong>льский инт<strong>е</strong>рф<strong>е</strong>йс<br />

Добавл<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния в ИСР Visual Studio<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся м<strong>е</strong>тодом Drag&Drop (п<strong>е</strong>р<strong>е</strong>тащить и бросить).<br />

Рассмотрим проц<strong>е</strong>сс добавл<strong>е</strong>ния логотипа к форм<strong>е</strong>:<br />

Q<br />

Эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния PictureBox.<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> на форму эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния PictureBox<br />

из окна Toolbox. ИСР при этом добавит в файл<br />

F o rm l. D e s ig n e r . c s код нового изображ<strong>е</strong>ния.<br />

Чтобы увид<strong>е</strong>ть<br />

список инструм<strong>е</strong>нтов,<br />

нав<strong>е</strong>дит<strong>е</strong><br />

указат<strong>е</strong>ль мыши<br />

на слово Toolbox<br />

в в<strong>е</strong>рхн<strong>е</strong>м л<strong>е</strong>вом<br />

углу ИСР. Если<br />

оно отсутству<strong>е</strong>т,<br />

выб<strong>е</strong>рит<strong>е</strong> команду<br />

Toolbox в м<strong>е</strong>ню<br />

View.<br />

& All W indows Forms<br />

л C om m on Controfs<br />

@<br />

S<br />

Pointer<br />

Button<br />

Checkeox<br />

§ 3 CheckedLtstBox<br />

Э ComboBox<br />

A<br />

A<br />

DateTtmePjcfcer<br />

Labet<br />

ImkLabel<br />

^ ^<br />

Start Рзд<br />

5 1 ListBox<br />

ListVtew<br />

Й<br />

MaskedlextBox<br />

^ M onthCstendar<br />

Tt! Notr^kon<br />

^ PictureBox —<br />

l‘' W ¥ \ \ .<br />

0 RaAfcbt\toi<br />

RkhTextBox<br />

Щ. TextBox<br />

0 файл<strong>е</strong> Forml.Designer.es.<br />

Forml.Designer.cs<br />

вы н<strong>е</strong> им<strong>е</strong><strong>е</strong>т<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ния<br />

разработк<strong>е</strong> пользоват<strong>е</strong>льских инт<strong>е</strong>рф<strong>е</strong>йсов,<br />

нич<strong>е</strong>го страшного.<br />

О разработк<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсов мы поговорим поздн<strong>е</strong><strong>е</strong>. На данном<br />

этап<strong>е</strong> соср<strong>е</strong>доточьт<strong>е</strong>сь на пов<strong>е</strong>д<strong>е</strong>нии создава<strong>е</strong>мых эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния.<br />

46 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Визуальны<strong>е</strong><br />

объ<strong>е</strong>кты<br />

.NET<br />

Kj}3KI]AU^e<br />

данных<br />

Иншрум<strong>е</strong>йгпы<br />

зд<strong>е</strong>сь<br />

О<br />

Р<strong>е</strong>жим Zoom для эл<strong>е</strong>м<strong>е</strong>нта PictureBox.<br />

Доступ к свойствам эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

щ<strong>е</strong>лчком на мал<strong>е</strong>нькой ч<strong>е</strong>рной<br />

стр<strong>е</strong>лк<strong>е</strong>. Для свойства Size эл<strong>е</strong>м<strong>е</strong>нта PictureBox<br />

выб<strong>е</strong>рит<strong>е</strong> тип Zoom:<br />

С<br />

Задать разАА&р<br />

эл<strong>е</strong>м <strong>е</strong>нта<br />

можно б окн<strong>е</strong><br />

prope-rtie-s-<br />

Щ<strong>е</strong>лчок<br />

на ч<strong>е</strong>рной<br />

стр<strong>е</strong>лк<strong>е</strong> datm<br />

б ы с т р ш<br />

доступ к общим<br />

свойствам<br />

эл<strong>е</strong>м<strong>е</strong>нтов.<br />

Pormi<br />

ш ш<br />

@ W i e r ^ 1r«d«s<br />

I Choose Im sge.<br />

Size M o d e<br />

Dock in Par<br />

(Д<strong>е</strong>дчок на<br />

мал<strong>е</strong>нькой<br />

S P « г»'“<br />

9 o cm y i^/<br />

свойст оам<br />

эл<strong>е</strong>м <strong>е</strong>нт а<br />

управл<strong>е</strong>ния.<br />

Щ<strong>е</strong>лчок на строчк<strong>е</strong> Choose Imaa^<br />

e Зогрузка л о го ти п а фирмы по производству бум аги.<br />

Архив с логотипом находится на сайт<strong>е</strong> ( h t t p ; / /w w w . h e a d f I r s t l a b s . c o m /b o o k s /h f c s h a r p /<br />

H F C s h a r p _ g r a p h ic s _ c h 0 1 .z ip ) . Сохранит<strong>е</strong> <strong>е</strong>го на ж<strong>е</strong>стком диск<strong>е</strong> сво<strong>е</strong>го компьют<strong>е</strong>ра. Щ<strong>е</strong>лкнит<strong>е</strong><br />

на ч<strong>е</strong>рной стр<strong>е</strong>лк<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нта PictureBox и выб<strong>е</strong>рит<strong>е</strong> в появивш<strong>е</strong>мся м<strong>е</strong>ню команду Choose<br />

Image. Откро<strong>е</strong>тся окно диалога Select Resources. Установит<strong>е</strong> п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>ль в полож<strong>е</strong>ни<strong>е</strong> Local<br />

Resource и щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Import... Оста<strong>е</strong>тся только указать путь к файлу с картинкой.<br />

дальш<strong>е</strong> > 47


экономим р<strong>е</strong>сурсы<br />

Visual Studio, за сц<strong>е</strong>ной<br />

Кажо<strong>е</strong> ваш<strong>е</strong> д<strong>е</strong>йстви<strong>е</strong> Visual Studio сопровожда<strong>е</strong>тся написани<strong>е</strong>м<br />

кода. В мом<strong>е</strong>нт загрузки логотипа Visual Studio создала р<strong>е</strong>сурс<br />

и связала <strong>е</strong>го с вашим прилож<strong>е</strong>ни<strong>е</strong>м. Р<strong>е</strong>сурсом называ<strong>е</strong>тся любой<br />

графич<strong>е</strong>ский или звуковой файл, значок или други<strong>е</strong> данны<strong>е</strong>,<br />

подгружа<strong>е</strong>мы<strong>е</strong> к прилож<strong>е</strong>нию. Логотип инт<strong>е</strong>грировался в программу,<br />

и при открытии на другом компьют<strong>е</strong>р<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

PictureBox смож<strong>е</strong>т <strong>е</strong>го использовать.<br />

В мом<strong>е</strong>нт п<strong>е</strong>р<strong>е</strong>таскивания эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния PictureBox на<br />

форму для хран<strong>е</strong>ния данного р<strong>е</strong>сурса и <strong>е</strong>го связи с про<strong>е</strong>ктом автоматич<strong>е</strong>ски<br />

был создан файл F o rm l. re sx . Двойной щ<strong>е</strong>лчок на<br />

им<strong>е</strong>ни этого файла позволит увид<strong>е</strong>ть импортированно<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong>.<br />

!Г<br />

Q -<br />

/<br />

Логотип стал<br />

р<strong>е</strong>сурсом прилож<strong>е</strong>ния<br />

Contact List.<br />

S olu tron Explorer<br />

d<br />

Solution 'Contacts' CI project)<br />

C m tecte<br />

|> i l i Properties<br />

b 9 References<br />

Л Ц ] Form l.cs<br />

^ Form l.Designer.es<br />

Form l.resc*<br />

Program .cs<br />

в окн<strong>е</strong> Solution Explorer щ<strong>е</strong>лкнит<strong>е</strong> на квадратик<strong>е</strong><br />

со знаком «плюс» сл<strong>е</strong>ва от им<strong>е</strong>ни файла F o rm l. cs.<br />

Это откро<strong>е</strong>т доступ к файлам: Forml .D e s ig n e r, cs<br />

и F o rm l.re sx . Дважды щ<strong>е</strong>лкнит<strong>е</strong> на файл<strong>е</strong> Form l.<br />

re s x , зат<strong>е</strong>м на стр<strong>е</strong>лк<strong>е</strong> рядом со словом Strings и выб<strong>е</strong>рит<strong>е</strong><br />

в м<strong>е</strong>ню вариант Images (или нажмит<strong>е</strong> Ctrl-2),<br />

чтобы увид<strong>е</strong>ть импортированный логотип.<br />

Forml.resx X I<br />

i ü Im ages » J| A d d Resource<br />

Вторая кнопка<br />

Import в окн<strong>е</strong><br />

Select Resource<br />

пом<strong>е</strong>ща<strong>е</strong>т<br />

логотип в папку<br />

Resources окна<br />

Solution Explorer.<br />

Чтобы исправить<br />

ситуацию,<br />

установит<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>ль<br />

Local Resource<br />

и повторно<br />

импортируйт<strong>е</strong><br />

файл.<br />

э т о<br />

созЗанны<strong>е</strong> -<br />

рйНйв'<br />

Program.cs<br />

Forml.resx<br />

Этот файл ИСР<br />

создала при импорт<strong>е</strong><br />

изображ<strong>е</strong>ния. Сюда<br />

пом<strong>е</strong>щаются любы<strong>е</strong><br />

р<strong>е</strong>сурсы, связанны<strong>е</strong><br />

с формой.<br />

48 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Р<strong>е</strong>дактировани<strong>е</strong> кода<br />

Иногда в автоматич<strong>е</strong>ски созданный код тр<strong>е</strong>бу<strong>е</strong>тся вн<strong>е</strong>сти изм<strong>е</strong>н<strong>е</strong>ния.<br />

Рассмотрим эту проц<strong>е</strong>дуру на прим<strong>е</strong>р<strong>е</strong> добавл<strong>е</strong>ния<br />

к логотипу всплывающ<strong>е</strong>го т<strong>е</strong>кста.<br />

При р<strong>е</strong>дактировании формы двойной щ<strong>е</strong>лчок на любом эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong><br />

управл<strong>е</strong>ния автоматич<strong>е</strong>ски добавля<strong>е</strong>т в про<strong>е</strong>кт код.<br />

Дважды щ<strong>е</strong>лкнит<strong>е</strong> на фр<strong>е</strong>йм<strong>е</strong> PictureBox и вы увидит<strong>е</strong> код, который<br />

выполня<strong>е</strong>тся при каждом щ<strong>е</strong>лчк<strong>е</strong> на данном эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong><br />

управл<strong>е</strong>ния. Этот код долж<strong>е</strong>н выгляд<strong>е</strong>ть прим<strong>е</strong>рно так:<br />

p u b l i c p a r t i a l c l a s s F o rm l : Form<br />

{<br />

p u b l i c F o r m l{)<br />

при каждом щ<strong>е</strong>лчк<strong>е</strong><br />

пользоват<strong>е</strong>ля на логотип<strong>е</strong>.<br />

I n i t i a l i z e C o m p o n e n t O ;<br />

1 Названи<strong>е</strong> м<strong>е</strong>тода<br />

^ , п о к а з ы б а ^ ^ 1^ л ч к о М<br />

p r i v a t e v o i d p i c t u r e B o x l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) ^ а п уска<strong>е</strong>т ^ ^ ^ p ic tu r e B o X .<br />

{<br />

----------------------. U/2 на эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong><br />

M e s s a g e B o x .S h o w ("C o n t a o t L i s t 1 . 0 . \ n W r it t e n bys Zour Name". " A b o u t " ) ;<br />

}<br />

V<br />

Посл<strong>е</strong> двойного щ<strong>е</strong>лчка<br />

на эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong> РкЫг<strong>е</strong>Вок<br />

курсор окаж<strong>е</strong>тся<br />

зд<strong>е</strong>сь. При ввод<strong>е</strong><br />

кода игнорируйт<strong>е</strong><br />

всплывающи<strong>е</strong> окна.<br />

Вв<strong>е</strong>дит<strong>е</strong> этот код Пи<br />

Ч а с зц о<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

вв<strong>е</strong>дя код, щ<strong>е</strong>лкнит<strong>е</strong><br />

на кнопк<strong>е</strong> Save пан<strong>е</strong>ли<br />

инструм<strong>е</strong>нтов ИСР<br />

выб<strong>е</strong>рит<strong>е</strong> команду Save<br />

в м<strong>е</strong>ню File.<br />

Что тако<strong>е</strong> м<strong>е</strong>тод?<br />

О! М<strong>е</strong>тодом называ<strong>е</strong>тся им<strong>е</strong>нованный блок<br />

кода. Бол<strong>е</strong><strong>е</strong> подробную информацию вы получит<strong>е</strong><br />

в глав<strong>е</strong> 2.<br />

Зач<strong>е</strong>м нуж<strong>е</strong>н символ \п ?<br />

О! Это знак п<strong>е</strong>р<strong>е</strong>носа строки. Он показыва<strong>е</strong>т,<br />

что Contact List 1.0 буд<strong>е</strong>т написан на строк<strong>е</strong>,<br />

а Written by: записыва<strong>е</strong>тся с новой строки.<br />

дальш<strong>е</strong> k 49


запуск прилож<strong>е</strong>ния (након<strong>е</strong>ц-то!)<br />

П<strong>е</strong>рбый запуск прило)к<strong>е</strong>ния<br />

Нажмит<strong>е</strong> кнопку F5 или щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> с з<strong>е</strong>л<strong>е</strong>ной<br />

стр<strong>е</strong>лкой I (^ ) на пан<strong>е</strong>ли инструм<strong>е</strong>нтов, чтобы прот<strong>е</strong>стировать<br />

р<strong>е</strong>зультат сво<strong>е</strong>й работы. (Это называ<strong>е</strong>тся<br />

«отладкой», то <strong>е</strong>сть запуском программы в ИСР.) Для<br />

остановки проц<strong>е</strong>сса выб<strong>е</strong>рит<strong>е</strong> Stop Debugging в м<strong>е</strong>ню<br />

Debug или щ<strong>е</strong>лкнит<strong>е</strong> на кнопш j на пан<strong>е</strong>ли инструм<strong>е</strong>нтов.<br />

сг, ; IS :<br />

а<br />

Вс<strong>е</strong> три кнопки<br />

работают, и вам<br />

н<strong>е</strong> ^^отр<strong>е</strong>бовало,^<br />

J^ucamb для этого код.<br />

About<br />

C ontact List 1,0.<br />

Written b f. Your N am e<br />

Щ<strong>е</strong>лчок на логотип<strong>е</strong><br />

вызыва<strong>е</strong>т только<br />

что созданно<strong>е</strong> окно<br />

About.<br />

OK<br />

Гд<strong>е</strong> )ke Mou файлы?<br />

При запуск<strong>е</strong> программы Visual<br />

Studio копиру<strong>е</strong>т файлы в папку<br />

Му D o c u m e n ts\V isu a l S tu d io<br />

2 0 1 0 \ P r o j e c ts \C o n ta c t s \<br />

C o n ta c ts \b in \d e b u g . Дважды щ<strong>е</strong>лк-<br />

/<br />

нит<strong>е</strong> на созданном ИСР файл<strong>е</strong> .<strong>е</strong>х<strong>е</strong>,<br />

и программа начн<strong>е</strong>т работать.<br />

С* пр<strong>е</strong>враща<strong>е</strong>т<br />

вашу программу<br />

в исполня<strong>е</strong>мый<br />

Гайл, находящийся<br />

папк<strong>е</strong> debug.<br />

_ Часвдо<br />

--------- ^ а Д а В а <strong>е</strong> М ы <strong>е</strong> ------------<br />

Bonj=*oc:bi<br />

в мо<strong>е</strong>й ИСР кнопка с з<strong>е</strong>л<strong>е</strong>ной стр<strong>е</strong>лкой<br />

называ<strong>е</strong>тся Debug (Начать отладку). Она<br />

запустит программу?<br />

• Кон<strong>е</strong>чно. Щ<strong>е</strong>лчок на н<strong>е</strong>й прив<strong>е</strong>д<strong>е</strong>т к выполн<strong>е</strong>нию<br />

программы внутри ИСР, что в данный<br />

мом<strong>е</strong>нт вам, собств<strong>е</strong>нно, и тр<strong>е</strong>бу<strong>е</strong>тся.<br />

О проц<strong>е</strong>дур<strong>е</strong> отладки мы поговорим поздн<strong>е</strong><strong>е</strong>.<br />

сй<br />

Form1.cs<br />

с»<br />

1=orm1 Ш ]<br />

Designer.cs шти<br />

Forml.resx<br />

Это н<strong>е</strong> ошибка. Сущ<strong>е</strong>ствуют два<br />

уровня папок, файлы с кодом С #<br />

находятся во внутр<strong>е</strong>нних папках.<br />

Properties<br />

Я н<strong>е</strong> вижу на пан<strong>е</strong>ли инструм<strong>е</strong>нтов<br />

кнопку Stop Debugging. Что д<strong>е</strong>лать?<br />

Q l Эта кнопка появля<strong>е</strong>тся только при запущ<strong>е</strong>нной<br />

на выполн<strong>е</strong>ни<strong>е</strong> программ<strong>е</strong>. Запустит<strong>е</strong><br />

прилож<strong>е</strong>ни<strong>е</strong>, и вы увидит<strong>е</strong>, как она появится.<br />

50 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Bom что у)к<strong>е</strong> сд<strong>е</strong>лано<br />

Итак, мы создали форму и объ<strong>е</strong>кт PictureBox, щ<strong>е</strong>лчок на котором<br />

вызыва<strong>е</strong>т диалогово<strong>е</strong> окно с т<strong>е</strong>кстом. Т<strong>е</strong>п<strong>е</strong>рь нужно<br />

добавить поля с информаци<strong>е</strong>й; им<strong>е</strong>на и т<strong>е</strong>л<strong>е</strong>фоны из списка<br />

контактов.<br />

Эту информацию мы сохраним в баз<strong>е</strong> данных. Visual Studio со<strong>е</strong>динит<br />

с н<strong>е</strong>й поля, то <strong>е</strong>сть нам н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся вручную писать<br />

код для доступа к этой баз<strong>е</strong>. С<strong>е</strong>йчас мы займ<strong>е</strong>мся <strong>е</strong><strong>е</strong> написани<strong>е</strong>м,<br />

то <strong>е</strong>сть п<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>м от разд<strong>е</strong>ла Визуальны<strong>е</strong> объ<strong>е</strong>кты .NET прямо<br />

к разд<strong>е</strong>лу Запись данных.<br />

Визуальны<strong>е</strong><br />

объ<strong>е</strong>кты .NET<br />

Объ<strong>е</strong>кты Хранилищ<strong>е</strong> иис1л|»ум<strong>е</strong>иты<br />

в)


сохранит<strong>е</strong>, чтобы потом использовать<br />

Для хран<strong>е</strong>ния информации ну>кна база данных<br />

Код, связывающий форму с данными ИСР, г<strong>е</strong>н<strong>е</strong>риру<strong>е</strong>тся<br />

автоматич<strong>е</strong>ски, так что нам нужно вс<strong>е</strong>го<br />

лишь:<br />

О Добавить к про<strong>е</strong>кту базу данны х S Q L .<br />

В окн<strong>е</strong> Solution Explorer щ<strong>е</strong>лкнит<strong>е</strong> правой<br />

кнопкой мыши на про<strong>е</strong>кт<strong>е</strong> Contacts, выб<strong>е</strong>рит<strong>е</strong><br />

команду A dd»N ew Item. В открывш<strong>е</strong>мся<br />

окн<strong>е</strong> выд<strong>е</strong>лит<strong>е</strong> строчку Local database, а в пол<strong>е</strong><br />

Name укажит<strong>е</strong> имя файла ContactDB.sdf.<br />

AebSNew№em-C&ftacts<br />

УЗ<strong>е</strong>Зцил<strong>е</strong>сь, иило<br />

Э т о ф а й л<br />

наш<strong>е</strong>й новой<br />

базы данных-<br />

ТШШ<br />

S Q L<br />

ContactDB.sdf<br />

Выбрав Local<br />

Database,<br />

вы создадит<strong>е</strong><br />

файл<br />

SQL Server<br />

Compact<br />

Edition, в котором<br />

и буд<strong>е</strong>т<br />

храниться<br />

наша база.<br />

SetBigsR<br />

ResouKUFite<br />

Veoal<strong>C#</strong>Bemi<br />

ё Tet File V'«uat<strong>C#</strong>Kems<br />

Interfec*<br />

Vi«ualC»items<br />

Vt5ue!C«Rems<br />

Й Cod«F>


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

База данных, созданная UCP<br />

База данных SQL —это способ сист<strong>е</strong>матизированного<br />

хран<strong>е</strong>ния информации. ИСР да<strong>е</strong>т вам<br />

вс<strong>е</strong> инструм<strong>е</strong>нты для управл<strong>е</strong>ния как данными,<br />

так и самой базой.<br />

Визуальны<strong>е</strong> Объ<strong>е</strong>кты ХранцАищ<strong>е</strong> инструм<strong>е</strong>нты<br />

бнвзрвнця<br />

U v<br />

Данны<strong>е</strong> в баз<strong>е</strong> хранятся в вид<strong>е</strong> таблиц. Столбцы<br />

разд<strong>е</strong>ляют данны<strong>е</strong> по кат<strong>е</strong>гориям (наприм<strong>е</strong>р,<br />

«имя» или «ном<strong>е</strong>р т<strong>е</strong>л<strong>е</strong>фона»), а строки сод<strong>е</strong>ржат<br />

информацию о каждом контакт<strong>е</strong>.<br />

База SQL сод<strong>е</strong>ржит<br />

оаши данны<strong>е</strong>,<br />

информацию о5 их<br />

структур<strong>е</strong> и код<br />

доступа к ним.<br />

Вами Злин^!<strong>е</strong><br />

хранятся 6 вид<strong>е</strong><br />

Эикамми<strong>е</strong>ском<br />

илаблиц<strong>е</strong>'-<br />

проц<strong>е</strong>дуры<br />

Язык SQ L<br />

SQL расшифровыва<strong>е</strong>тся как Structured Query<br />

Language —язык структурированных запросов.<br />

Он пр<strong>е</strong>дназнач<strong>е</strong>н для доступа к данным в базах<br />

и им<strong>е</strong><strong>е</strong>т собств<strong>е</strong>нный синтаксис и структуру. Код<br />

SQL пр<strong>е</strong>дставл<strong>е</strong>н в вид<strong>е</strong> оп<strong>е</strong>раторов (statements)<br />

и запросов (queries), а такж<strong>е</strong> хранимых проц<strong>е</strong>дур<br />

(stored procedures). ИСР г<strong>е</strong>н<strong>е</strong>риру<strong>е</strong>т за вас<br />

оп<strong>е</strong>раторы SQL и хранимы<strong>е</strong> проц<strong>е</strong>дуры, позволяя<br />

создава<strong>е</strong>мому вами прилож<strong>е</strong>нию осущ<strong>е</strong>ствлять<br />

доступ к данным базы.<br />

S Q L<br />

ContactDB.sdf<br />

Этот файл сод<strong>е</strong>ржит базу<br />

SQL. Им<strong>е</strong>нно 3dect> будут<br />

сохран<strong>е</strong>ны наши таблицы<br />

и данны<strong>е</strong>.<br />

дальш<strong>е</strong> ► 53


хранить данны<strong>е</strong> л<strong>е</strong>гко<br />

Создани<strong>е</strong> таблицы для списка контактов<br />

Т<strong>е</strong>п<strong>е</strong>рь базу нужно наполнить данными. Обычно использу<strong>е</strong>тся<br />

пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> в вид<strong>е</strong> таблицы, поэтому сначала создадим<br />

таблицу People, в которую и пом<strong>е</strong>стим контактную<br />

информацию:<br />

Добавл<strong>е</strong>ни<strong>е</strong> таблицы<br />

Щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на строчк<strong>е</strong><br />

Tables в окн<strong>е</strong> Database Explorer и выб<strong>е</strong>рит<strong>е</strong> команду<br />

Create Table.<br />

Ч а с т о<br />

,аДаБа<strong>е</strong>Мы<strong>е</strong><br />

B o lïp o C jjI<br />

• Что ж<strong>е</strong> тако<strong>е</strong> столб<strong>е</strong>ц?<br />

Q * Столб<strong>е</strong>ц — это одно из пол<strong>е</strong>й таблицы.<br />

В таблиц<strong>е</strong> People можно создать<br />

столбцы FirstName и LastName, относящи<strong>е</strong>ся<br />

к типу String или Date или Bool.<br />

Database Exptorer - X<br />

M<br />

Dffta Connections<br />

ySj ContactDB.sdf<br />

i> ______,___<br />

!> iJJ R- Create Table<br />

New Query<br />

i ^ Refresh<br />

i S Properties Alt+Enter<br />

Т<strong>е</strong>п<strong>е</strong>рь к таблиц<strong>е</strong> нужно добавить столбцы. Начн<strong>е</strong>м<br />

со столбца ContactID, чтобы присвоить каждому<br />

контакту уникальный ном<strong>е</strong>р.<br />

T<br />

• Зач<strong>е</strong>м нам столб<strong>е</strong>ц Соп1ас1Ю?<br />

^ ! Он позволит присвоить уникальный<br />

ном<strong>е</strong>р каждой записи в таблицах базы. Так<br />

как мы сохраня<strong>е</strong>м контактны<strong>е</strong> данны<strong>е</strong> отд<strong>е</strong>льных<br />

люд<strong>е</strong>й, им<strong>е</strong><strong>е</strong>т смысл их пронум<strong>е</strong>ровать.<br />

Что тако<strong>е</strong> тип данных Int?<br />

Ql Int — это сокращ<strong>е</strong>нни<strong>е</strong> от Integer<br />

(ц<strong>е</strong>ло<strong>е</strong> число). То <strong>е</strong>сть в столбц<strong>е</strong> ContactID<br />

могут сод<strong>е</strong>ржаться только ц<strong>е</strong>лы<strong>е</strong> числа.<br />

О<br />

I Column Name<br />

ContactiD<br />

Создани<strong>е</strong> столбца C o n ta c tID<br />

Вв<strong>е</strong>дит<strong>е</strong> в пол<strong>е</strong> Column Name названи<strong>е</strong><br />

ContactID, а в раскрываюш;<strong>е</strong>мся списк<strong>е</strong> Data<br />

Тур<strong>е</strong> выб<strong>е</strong>рит<strong>е</strong> вариант Int. В списк<strong>е</strong> Allow Nulls<br />

долж<strong>е</strong>н быть выбран вариант No.<br />

В списк<strong>е</strong> Primary Key выб<strong>е</strong>рит<strong>е</strong> вариант Yes. То<br />

<strong>е</strong>сть им<strong>е</strong>нно это пол<strong>е</strong> буд<strong>е</strong>т использоваться в кач<strong>е</strong>ств<strong>е</strong><br />

уникального ид<strong>е</strong>нтификатора записи.<br />

T<br />

Data Type<br />

Ji8L<br />

Nüils<br />

Unique Primary<br />

А о б а в ^ <strong>е</strong> столб<strong>е</strong>ц ContactID с типом данных int. В<br />

М <strong>е</strong> р и т <strong>е</strong> вариант No, а в списках Unique и Primary<br />

Yes<br />

Информации слишком много, долж<strong>е</strong>н<br />

ли я во вс<strong>е</strong>м этом разбираться?<br />

^ ! Нич<strong>е</strong>го страшного, <strong>е</strong>сли на данном<br />

этап<strong>е</strong> что-то оста<strong>е</strong>тся н<strong>е</strong>понятным. Пока<br />

что ваша основная задача — получ<strong>е</strong>ни<strong>е</strong><br />

навыков работы с ИСР Visual Studio. Достаточно<br />

научиться подготавливать формы<br />

и запускать программу (Если ж<strong>е</strong> вы<br />

хотит<strong>е</strong> узнать больш<strong>е</strong> о базах данных, почитайт<strong>е</strong>,<br />

наприм<strong>е</strong>р, книгу «<strong>Изуча<strong>е</strong>м</strong> SQL».<br />

списк<strong>е</strong> Allow Nulls<br />

Key вариант Yes.<br />

54 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Визу»л11ны<strong>е</strong><br />

объ<strong>е</strong>кты<br />

■NET<br />

О бъ<strong>е</strong>кты<br />

6«Ь1 jasBW x<br />

.NET<br />

Храимлищ<strong>е</strong><br />

данных<br />

1!я<strong>е</strong>трумвншы<br />

Вн<strong>е</strong>з(;<strong>е</strong>ния<br />

О<br />

Г<strong>е</strong>н<strong>е</strong>рация ид<strong>е</strong>нтиф икационны х ном<strong>е</strong>ров<br />

Информация в столбц<strong>е</strong> ContactID буд<strong>е</strong>т использоваться<br />

только базой данных, нам она н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся,<br />

<strong>е</strong><strong>е</strong> им<strong>е</strong><strong>е</strong>т смысл г<strong>е</strong>н<strong>е</strong>рировать автоматич<strong>е</strong>ски.<br />

В окн<strong>е</strong> свойств присвойт<strong>е</strong> свойству Identity знач<strong>е</strong>ни<strong>е</strong><br />

True, чтобы сд<strong>е</strong>лать столб<strong>е</strong>ц ContactID<br />

ид<strong>е</strong>нтификатором для вс<strong>е</strong>й таблицы.<br />

В пол<strong>е</strong> Name в в<strong>е</strong>рхн<strong>е</strong>й части окна вв<strong>е</strong>дит<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

People.<br />

I<br />

^Ь1 зд<strong>е</strong>сь<br />

в о к к . з о г « " «<br />

сU<br />

■3 E^i^tTriЯe-^*eop^e<br />

ш iJ Rdresh М<strong>е</strong>}р<br />

Generei<br />

Istame Peopie<br />

Column Name<br />

Datatype<br />

length AllowNutts Uniqu« PrtmaryKey<br />

4 Mo Yes ¥e<br />

П<strong>е</strong>рвичный ключ<br />

явля<strong>е</strong>тся уникальным<br />

ид<strong>е</strong>нтификатором<br />

записи, поэтому<br />

он обязат<strong>е</strong>льно<br />

долж<strong>е</strong>н быть задан.<br />

Micfosoft SQLServer Compact<br />

1<br />

Ы«-<br />

ContactD6.sdf<br />

is WmisiffisdsniKOEHtiss<br />

Det^Vah«'............<br />

Ddault vafoe for ^iis coSumrv.<br />

8 раскрывающ<strong>е</strong>мся списк<strong>е</strong> справа от поля<br />

Identity нужно указать знач<strong>е</strong>ни<strong>е</strong> True,<br />

чтобы сд<strong>е</strong>лать столд<strong>е</strong>ц Contact!Р<br />

ид<strong>е</strong>нтификатором запис<strong>е</strong>й таблицы.<br />

OK<br />

Cftncet<br />

добавл<strong>е</strong>нии<br />

»овои записи пол<strong>е</strong><br />

^о>л^лсИО буд<strong>е</strong>т<br />

обновляться<br />

‘^°


оформим в таблицу<br />

Поля 6 контактной карт<strong>е</strong> — это<br />

столбцы таблицы People<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда у нас <strong>е</strong>сть п<strong>е</strong>рвичный ключ таблицы,<br />

нужно опр<strong>е</strong>д<strong>е</strong>лить вс<strong>е</strong> остальны<strong>е</strong> поля. Каждо<strong>е</strong> пол<strong>е</strong><br />

должно стать столбцом в таблиц<strong>е</strong> People.<br />

Имя: Laverne Smith<br />

Фирма: XYZ Industries<br />

Т<strong>е</strong>л<strong>е</strong>фон: ( z iz )s s s ~ s x z ‘i<br />

p.«.<br />

Email; Laverne.Smith@XyZindustries.com<br />

Кли<strong>е</strong>нт: Yes<br />

По<strong>е</strong>л, звонок: o s/z& /o i<br />

JLJI<br />

р <strong>е</strong> о р '®<br />

о каждом ч<strong>е</strong>лов<strong>е</strong>к<strong>е</strong> мы<br />

^осл<strong>е</strong>дтго звонт ^'''^'^^<br />

ШТУРМ<br />

Каки<strong>е</strong> пробл<strong>е</strong>мы могут возникнуть, <strong>е</strong>сли одному<br />

ч<strong>е</strong>лов<strong>е</strong>ку сопоставить н<strong>е</strong>сколько запис<strong>е</strong>й?<br />

56 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

КТ9 И Н Т


это им<strong>е</strong>нно мой тип<br />

КТО<br />

Пров<strong>е</strong>рьт<strong>е</strong>, правильно ли вы сопоставили типы данных и описания таблицы People.<br />

Названи<strong>е</strong> столбца Тип данных Описани<strong>е</strong><br />

58 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Заб<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> таблицы<br />

Ввзуальямв<br />

объ<strong>е</strong>кты<br />

.NET<br />

О бъ<strong>е</strong>кты<br />

6»зь15«в»ых<br />

.NET<br />

хранилищ<strong>е</strong><br />

данных<br />

инструм<strong>е</strong>нты<br />

Зн<strong>е</strong>^р<strong>е</strong>ния<br />

По аналогии со столбцом ContactID добавьт<strong>е</strong><br />

<strong>е</strong>щ<strong>е</strong> пять столбцов. Вот как должно выгляд<strong>е</strong>ть<br />

окно Edit Table посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния работы:<br />

...<br />

Г .<br />

X V<br />

0<br />

] ) ы зд<strong>е</strong>сь<br />

Поля типа<br />

Bit при -<br />

нимают<br />

знач<strong>е</strong>ния True<br />

или False и<br />

могут быть<br />

пр<strong>е</strong>дставл<strong>е</strong>ны<br />

в вид<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>ключа -<br />

т<strong>е</strong>ля.<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> ОК для сохран<strong>е</strong>ния таблицы. Она буд<strong>е</strong>т добавл<strong>е</strong>на к ваш<strong>е</strong>й<br />

баз<strong>е</strong> данных.<br />

, Если<br />

, парам<strong>е</strong>тр<br />

i Allow Nulls<br />

им<strong>е</strong><strong>е</strong>т<br />

' знач<strong>е</strong>ни<strong>е</strong><br />

NOj столб<strong>е</strong>ц<br />

н<strong>е</strong> мож<strong>е</strong>т<br />

оставаться<br />

•пустым.<br />

^ ^ф о р м а ц и я<br />

о кли<strong>е</strong>нт<strong>е</strong><br />

мож<strong>е</strong>т, быть<br />

,н<strong>е</strong>полной,<br />

.^о эт о м у<br />

o f io u p a c M<br />

знач<strong>е</strong>ни<strong>е</strong> Yes<br />

ЕМ.?»«<br />

•<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong>^<br />

ОК добавит<br />

таблиц!^ People<br />

к баз<strong>е</strong> Эанных.<br />

р<strong>е</strong>ор'в<br />

Новая таблица пот<br />

дАя вв% 7 д а н н ь !Т ° ^ "<br />

дальш<strong>е</strong> ► 59


добавля<strong>е</strong>м данны<strong>е</strong><br />

П<strong>е</strong>р<strong>е</strong>нос 6 базу данных с карточ<strong>е</strong>к<br />

Вс<strong>е</strong> готово для ввода данных в базу. Для начала<br />

возьм<strong>е</strong>м ш<strong>е</strong>сть карточ<strong>е</strong>к с контактной информаци<strong>е</strong>й<br />

от ваш<strong>е</strong>го босса.<br />

Ф<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на квадратик<strong>е</strong> со знаком<br />

«плюс» сл<strong>е</strong>ва от строчки<br />

Tables в окн<strong>е</strong> Database Explorer<br />

(или Server Explorer), зат<strong>е</strong>м<br />

щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши<br />

на им<strong>е</strong>ни таблицы People и выб<strong>е</strong>рит<strong>е</strong><br />

команду Show Table Data<br />

в появивш<strong>е</strong>мся м<strong>е</strong>ню.<br />

Database Estploret<br />

s<br />

[ p Data C onnections<br />

j<br />

Л<br />

h<br />

ContectDB.s(if<br />

l J Tables<br />

■<br />

Peop‘-<br />

1 л P.ephcati<br />

!<br />

Q-<br />

- X<br />

Drop Tabte<br />

Table Properties<br />

ttfit Table Schem#<br />

NevSfQueiy<br />

Show Table Data j<br />

Copy<br />

Rrfrah<br />

Properties<br />

Нужно вн<strong>е</strong>сти<br />

данны<strong>е</strong> с этих<br />

ил<strong>е</strong>сти карточ<strong>е</strong>к<br />

в таблицу People.<br />

Ctrl-i-C<br />

Ait+Er.ter<br />

В ц<strong>е</strong>нтральном окн<strong>е</strong> появится<br />

с<strong>е</strong>тка таблицы, куда нужно вв<strong>е</strong>сти<br />

данны<strong>е</strong> с карточ<strong>е</strong>к. (Изначально<br />

во вс<strong>е</strong>х яч<strong>е</strong>йках стоит<br />

знач<strong>е</strong>ни<strong>е</strong> null, вв<strong>е</strong>дит<strong>е</strong> вм<strong>е</strong>сто<br />

н<strong>е</strong>го свою информацию.) Столб<strong>е</strong>ц<br />

ContactID буд<strong>е</strong>т заполн<strong>е</strong>н<br />

автоматич<strong>е</strong>ски.<br />

ЗН»'<br />

Имя: Ыг Nelson<br />

Фирма: JTP<br />

т<strong>е</strong>л<strong>е</strong>фон: (40--^)?^^-^^<br />

Erna«-. L.feMelsoneJTP.ORa<br />

Кли<strong>е</strong>нт;<br />

Имя: L loyd Jones<br />

Фирма: Black Box Inc.<br />

Т<strong>е</strong>л<strong>е</strong>фон: ( 7 i S ) S S S - S & 3 8<br />

Email: LJones@Xblackboxmc-com<br />

Кли<strong>е</strong>нт: Yes По<strong>е</strong>л, звонок: o s /z & /to<br />

Имя: Luanda Ericson О Paper свич>в(^<br />

Фирма: Ericson Events<br />

Т<strong>е</strong>л<strong>е</strong>фон; (2 .iz )sss-^ s z s<br />

Email: LucySEricsonEvents.info<br />

Кли<strong>е</strong>нт: No По<strong>е</strong>л, звонок: £35/17/10<br />

60 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Имя: Matt Franks. (<br />

Фирма: XYZ Industries<br />

Т<strong>е</strong>л<strong>е</strong>фон: (ZX Z)SSS-8i-ZS<br />

Email: Matt.Franks&XyZindustries.com<br />

1Сли<strong>е</strong>нт: Yes По<strong>е</strong>л, звонок: 05/26/10<br />

Имя: Sarak Kalter ^<br />

Фирма: Kalter. Riddle and Stoft<br />

Т<strong>е</strong>л<strong>е</strong>фон: (6 3 -4 )555--5641.<br />

Email: Sarah^KRS.org<br />

Кли<strong>е</strong>нт: No По<strong>е</strong>л, звонок: i z / i o / o s<br />

Фирма находится в США,<br />

поэтому дир<strong>е</strong>ктор записыва<strong>е</strong>т<br />

даты как 0S/Z & /1 0 , что<br />

означа<strong>е</strong>т 2.6 мая ЯОЮ. Вы<br />

мож<strong>е</strong>т<strong>е</strong> вводить их в другом<br />

формат<strong>е</strong>.<br />

1мя: Laverne Smth.<br />

Фирма: XYZ Industries<br />

Т<strong>е</strong>л<strong>е</strong>фон; ( z i- z ) s s s -s iz ^<br />

Email: Laverne.Smith@XyZindustries.com<br />

Кли<strong>е</strong>нт: Yes По<strong>е</strong>л, звонок: 04/ 1 1 /1 0<br />

^ Посл<strong>е</strong> ввода вс<strong>е</strong>х данных .<br />

снова выб<strong>е</strong>рит<strong>е</strong> в м<strong>е</strong>ню File сГ<br />

команду Save All. Записи будут<br />

сохран<strong>е</strong>ны в баз<strong>е</strong> данных.<br />

Команда Save Al! сохраня<strong>е</strong>т б<strong>е</strong><strong>е</strong><br />

открыты<strong>е</strong> файлы, а команда Save<br />

Z Z k o файл, над которым вы<br />

с<strong>е</strong>йчас работа<strong>е</strong>т<strong>е</strong>.<br />

Б:<br />

О<br />

Куда попадают вв<strong>е</strong>д<strong>е</strong>ны<strong>е</strong> мной данны<strong>е</strong>?<br />

Частно<br />

; ИСР автоматич<strong>е</strong>ски сохраня<strong>е</strong>т данны<strong>е</strong> в таблиц<strong>е</strong> People<br />

ваш<strong>е</strong>й базы данных. При этом таблица, <strong>е</strong><strong>е</strong> столбцы, типы<br />

данных и сами данны<strong>е</strong> хранятся в файл<strong>е</strong> ContactDB.sdf, который<br />

явля<strong>е</strong>тся частью ваш<strong>е</strong>го про<strong>е</strong>кта, поэтому ИСР автоматич<strong>е</strong>ски<br />

обновля<strong>е</strong>т <strong>е</strong>го при вн<strong>е</strong>с<strong>е</strong>нии любых изм<strong>е</strong>н<strong>е</strong>ний.<br />

Л а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Б о Л р о С ь !<br />

Становятся ли вв<strong>е</strong>д<strong>е</strong>нны<strong>е</strong> записи частью мо<strong>е</strong>й программы?<br />

0:<br />

Да, данны<strong>е</strong> — такая ж<strong>е</strong> часть программы, как код или<br />

созданны<strong>е</strong> формы. Файл ContactDB.sdf копиру<strong>е</strong>тся и хранится<br />

вм<strong>е</strong>ст<strong>е</strong> с исполня<strong>е</strong>мым файлом. Для доступа к данным<br />

прилож<strong>е</strong>ни<strong>е</strong> чита<strong>е</strong>т файл ContactDB.sdf и вносит в н<strong>е</strong>го новы<strong>е</strong><br />

записи.<br />

^ в « S


вс<strong>е</strong> данны<strong>е</strong> в одном м<strong>е</strong>ст<strong>е</strong><br />

источник данных со<strong>е</strong>динит форму с базой<br />

Вс<strong>е</strong> готово для создания объ<strong>е</strong>кта базы данных .NET, который буд<strong>е</strong>т использовать для взаимод<strong>е</strong>йствия<br />

с базой. Нам потр<strong>е</strong>бу<strong>е</strong>тся источник данных. Он пр<strong>е</strong>дставля<strong>е</strong>т собой вс<strong>е</strong>го лишь набор оп<strong>е</strong>раторов SQL,<br />

при помощи которых ваша программа буд<strong>е</strong>т обращаться к баз<strong>е</strong> ContactDB<br />

Зав<strong>е</strong>ршив ввод данных,<br />

О Возвращ<strong>е</strong>ни<strong>е</strong> к ф орм<strong>е</strong>. ^<br />

Закройт<strong>е</strong> таблицу People и сх<strong>е</strong>му базы данных ContactDB к форм<strong>е</strong>.<br />

для возвращ<strong>е</strong>ния на вкладку Forml.cs [Design].<br />

People Query(OW...cts\ContactDB.sdf)^X j<br />

1<br />

2<br />

3<br />

4<br />

5<br />

§<br />

ContactID<br />

NULL<br />

Name Company Telephone<br />

Lloyd Jones<br />

Lucinda Ericson<br />

Liz Nelson<br />

Matt Franks<br />

Sarah Kalter<br />

Laverne Smith<br />

Black Box Inc.<br />

Ericson Events<br />

JTP<br />

XYZ Industries<br />

Kalter, Riddle a„<br />

X¥Z Industries<br />

NULL<br />

(Л8)555-5638<br />

C212)555-9523<br />

(419)555-2578<br />

(Л2}555-8125<br />

(614)555-5641<br />

(22)555-8129<br />

NULL<br />

Email<br />

Client<br />

Uones@xbtack.„ True<br />

lucy@ericsonev... False<br />

liznelson@JTP.... True<br />

M8tt.Franks@x... True<br />

sarah@krs.,org False<br />

Laverne.Smith... True<br />

NULL<br />

NULL<br />

LasCail<br />

5/26/201012:00..<br />

5 Л 7 /Ж 0 12:00..<br />

3/4/200S12;00:...<br />

5/26/201012:00..<br />

12,^0/200812:0..<br />

4/ll/201012iOO..<br />

NULL<br />

О Добавл<strong>е</strong>ни<strong>е</strong> к прилож <strong>е</strong>нию нового источника данны х.<br />

Выб<strong>е</strong>рит<strong>е</strong> в м<strong>е</strong>ню Data команду Add New Data Source.<br />

Создава<strong>е</strong>мый исмочник<br />

данных буд<strong>е</strong>т отв<strong>е</strong>чать<br />

за вс<strong>е</strong> взаимод<strong>е</strong>йствия<br />

формы с базой.<br />

3<br />

62 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Визуальны<strong>е</strong> Объ<strong>е</strong>кты Хранилищ<strong>е</strong><br />

объ<strong>е</strong>кты данных данных<br />

-NET<br />

„.NET<br />

Ин<strong>е</strong>трум<strong>е</strong>ншы<br />

ЗН1§^<strong>е</strong>НЦЯ<br />

О<br />

Конф игурация нового источника данны х<br />

Т<strong>е</strong>п<strong>е</strong>рь нужно указать парам<strong>е</strong>тры взаимод<strong>е</strong>йствия источника<br />

данных с базой ContactDB. Вот как это сд<strong>е</strong>лать:<br />

★<br />

★<br />

★<br />

★<br />

В пол<strong>е</strong> Data Source Type выб<strong>е</strong>рит<strong>е</strong> вариант Database<br />

и щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Next.<br />

В пол<strong>е</strong> Database Model выб<strong>е</strong>рит<strong>е</strong> вариант Dataset<br />

и щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Next.<br />

Раскрывающийся список Choose Your Data<br />

Connection сод<strong>е</strong>ржит только один вариант, соотв<strong>е</strong>тствующий<br />

ваш<strong>е</strong>й баз<strong>е</strong> Contact. Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong><br />

Next.<br />

В пол<strong>е</strong> Choose Your Database Objects установит<strong>е</strong><br />

флажок Tables.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что в пол<strong>е</strong> Dataset Name вв<strong>е</strong>д<strong>е</strong>но знач<strong>е</strong>ни<strong>е</strong><br />

ContactDBDataSet и щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Finish.<br />

1ы зд<strong>е</strong>сь<br />

к л<br />

ТйКйМ способом вы со-<br />

Л л<br />

People<br />

&баз<strong>е</strong> данных ContactDB.<br />

Express, пр<strong>е</strong>длага<strong>е</strong>тся<br />

сохранить строки подключ<strong>е</strong>ния<br />

в ф1йлТкТн -<br />

^Р’^^ож<strong>е</strong>ния.<br />

^т о<strong>е</strong>т ьт <strong>е</strong> «Yes».<br />

Form!<br />

- взаимод<strong>е</strong>йствия с базой ContactPB-<br />

A bout<br />

"► ContactD BD ataSet.xsd<br />

C ontact List 1.0.<br />

Written byi Vour N am e<br />

C ontactD B .sdf<br />

1 L<br />

Это ваша<br />

форма.<br />

OK<br />

C ontactD BDataSet.<br />

D esigner.cs<br />

Эти файлы созданы<br />

данных, парам<strong>е</strong>тры которого вы<br />

только что выдрали.<br />

Файл с базой<br />

данных.<br />

дальш<strong>е</strong> > 63


со<strong>е</strong>диним вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong><br />

Добабл<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов, обязанных с базой данных<br />

Добавим на форму други<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния. Вс<strong>е</strong> они<br />

должны быть связаны с базой данных и со столбцами таблицы<br />

People.<br />

То <strong>е</strong>сть изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> данных в любом эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong> управл<strong>е</strong>ния<br />

формы должно отображаться в соотв<strong>е</strong>тствующ<strong>е</strong>м столбц<strong>е</strong><br />

таблицы.<br />

Выбор источника данны х.<br />

В м<strong>е</strong>ню Data выб<strong>е</strong>рит<strong>е</strong> команду Show Data Sources. Откро<strong>е</strong>тся<br />

окно Data Sources с п<strong>е</strong>р<strong>е</strong>чн<strong>е</strong>м настро<strong>е</strong>нных<br />

источников данных.<br />

I<br />

Database Exptorer<br />

Мы возвраща<strong>е</strong>мся к созданию<br />

объ<strong>е</strong>ктов формы, которы<strong>е</strong><br />

будут взаимод<strong>е</strong>йствовать<br />

с хранилищ<strong>е</strong>м данных.<br />

Если вы н<strong>е</strong> видит<strong>е</strong> эту<br />

вкладку, 6 м<strong>е</strong>ню Pata<br />

выб<strong>е</strong>рит<strong>е</strong> команду<br />

Show Pata Sources.<br />

Можно щ<strong>е</strong>лкнуть<br />

на кор<strong>е</strong>шк<strong>е</strong><br />

вкладки Data<br />

Sources, располож<strong>е</strong>нном<br />

внизу<br />

окна Database<br />

Explore.<br />

О<br />

Выд<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> таблицы People.<br />

Под пунктом ContactDBDataSet вы увидит<strong>е</strong> таблицу People со вс<strong>е</strong>ми столбцами. Если выд<strong>е</strong>лить<br />

строчку People в окн<strong>е</strong> Data Sources и зат<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>тащить мышью на форму, автоматич<strong>е</strong>ски появится<br />

<strong>е</strong>щ<strong>е</strong> один эл<strong>е</strong>м<strong>е</strong>нт, при помощи которого можно просматривать и вводить данны<strong>е</strong>. По<br />

умолчанию это буд<strong>е</strong>т DataGridView, то <strong>е</strong>сть <strong>е</strong>щ<strong>е</strong> одна таблица. Щ<strong>е</strong>лкнит<strong>е</strong> на располож<strong>е</strong>нной<br />

сл<strong>е</strong>ва от им<strong>е</strong>ни таблицы People и выб<strong>е</strong>рит<strong>е</strong> команду Details, чтобы получить возможность добавлять<br />

индивидуальны<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния для каждого столбца.<br />

С<br />

Зд<strong>е</strong>сь должны<br />

быть показаны<br />

вс<strong>е</strong> созданны<strong>е</strong><br />

столбцы.<br />

Data S ources<br />

::<br />

л [дЗ C ontactD B D ataS etl<br />

- ^<br />

1|Ы| C ontactID<br />

И N am e<br />

Jgii C o m p a n y<br />

Q T e lep h o n e<br />

jabi! Email<br />

0 C lient<br />

LastCatt<br />

- Д X<br />

Щ <strong>е</strong>лкнит<strong>е</strong> нй стр<strong>е</strong>лк<strong>е</strong><br />

и выб<strong>е</strong>рит<strong>е</strong> в м<strong>е</strong>ню команоу<br />

PetlЯ^(sJ чтобы добавить<br />

к форм<strong>е</strong> н<strong>е</strong>сколько разных<br />

эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния.<br />

64 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Bu3ys«Mbie Объ<strong>е</strong>кты<br />

объ<strong>е</strong>кты<br />

б н ы данных<br />

.NET .NET l = = l<br />

Храаидищ<strong>е</strong><br />

данных<br />

- cS<br />

ингт^ум<strong>е</strong>ні<br />

Вн<strong>е</strong>;{»»іія<br />

Щ ^ в<br />

щ<br />

зд<strong>е</strong>сь<br />

о Создани<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния связанных с таблиц<strong>е</strong>й People<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> таблицу People на форму. Появятся эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния,<br />

соотв<strong>е</strong>тствующи<strong>е</strong> столбцам базы данных. Волноваться о том, как<br />

им<strong>е</strong>нно они выглядят, пока н<strong>е</strong> нужно, важно, чтобы они просто появились.<br />

Для п<strong>е</strong>р<strong>е</strong>вода формы в активно<strong>е</strong> состояни<strong>е</strong>, достаточно<br />

п<strong>е</strong>р<strong>е</strong>йти на вкладку Forml .cs [Design] или открыть файл<br />

Forml. es из окна Solution Explorer.<br />

Э ту пан<strong>е</strong>ль<br />

управл<strong>е</strong>ния<br />

Зля навигации<br />

по таблиц<strong>е</strong><br />

создала ИСР-<br />

Э ти компон<strong>е</strong>нта<br />

н<strong>е</strong> видны на самой<br />

форм<strong>е</strong>, они AUUAt?<br />

указывают на коо,<br />

который 5ыл<br />

создан ИСР для —ч<br />

взаимод<strong>е</strong>йствия / ^<br />

с таблиц<strong>е</strong>й People<br />

и базой данных<br />

ContactPB-<br />

0)шрапу:<br />

Тв1<strong>е</strong>«йэсят<strong>е</strong>:<br />

ВШ:<br />

dent:<br />

Ы я М ;<br />

IdieckBoxI<br />

Thuredäy . December 24,2(ЮЗ<br />

Эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния,<br />

созданны<strong>е</strong><br />

посл<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>скивания<br />

3 таблицы<br />

People нл<br />

форму.<br />

äcortSKtDBDaföSeÜ peepteBirntingSource ■^'peopieT aH eftdspte-<br />

^ ta b le A ita p le fM sn s s e r.i!^ !J*peo(ilei(«äin3l«»igatof<br />

Этот объ<strong>е</strong>кт<br />

со<strong>е</strong>диня<strong>е</strong>т форму<br />

с і^адлиц<strong>е</strong>и People.<br />

Этот адапт<strong>е</strong>р<br />

отв<strong>е</strong>ча<strong>е</strong>т<br />

за взаимод<strong>е</strong>йстви<strong>е</strong><br />

с командами SQL.<br />

^лн<strong>е</strong>ль<br />

дальш<strong>е</strong> ► 65


сд<strong>е</strong>ла<strong>е</strong>м красиво<br />

Хороши<strong>е</strong> программы понятны интуитибно<br />

Т<strong>е</strong>п<strong>е</strong>рь наша форма работа<strong>е</strong>т. Но при этом она<br />

им<strong>е</strong><strong>е</strong>т н<strong>е</strong> самый пр<strong>е</strong>з<strong>е</strong>нтаб<strong>е</strong>льный вид, а в<strong>е</strong>дь прилож<strong>е</strong>ни<strong>е</strong><br />

ж<strong>е</strong>лат<strong>е</strong>льно д<strong>е</strong>лать н<strong>е</strong> только функциональным.<br />

Им должно быть приятно пользоваться.<br />

Сд<strong>е</strong>ла<strong>е</strong>м <strong>е</strong>го похожим на карточки, с которых мы<br />

п<strong>е</strong>р<strong>е</strong>писывали контактную информацию.<br />

форма с т а ­<br />

н <strong>е</strong> т 5ол<strong>е</strong><strong>е</strong><br />

понятной,<br />

<strong>е</strong>сли придать<br />

<strong>е</strong>й вот<br />

такой вид.<br />

Имя: taveme Smith<br />

Фирма: XYZ Industries<br />

^om ф oн:(z^z)sss-8tzя<br />

Email: Laverne.Smith@XijZindustries.com<br />

Кли<strong>е</strong>нт: Yes<br />

По<strong>е</strong>л, звонок: 0S/Z&/07<br />

Ж<br />

Выравнивани<strong>е</strong> пол<strong>е</strong>й и и х названий.<br />

Выровня<strong>е</strong>м поля и их названия по л<strong>е</strong>вому краю формы.<br />

В таком вид<strong>е</strong> <strong>е</strong>ю буд<strong>е</strong>т удобн<strong>е</strong>й пользоваться.<br />

•i* Forml<br />

И er 24.2009<br />

-fflo<br />

6<br />

... -jQ<br />

Удал <strong>е</strong>ни<strong>е</strong> подписи к q)лaжкy Client.<br />

Посл<strong>е</strong> п<strong>е</strong>р<strong>е</strong>таскивания на форму флажка Client справа<br />

от н<strong>е</strong>го оказалась н<strong>е</strong>нужная подпись. В окн<strong>е</strong> Properties,<br />

располож<strong>е</strong>нном под окном Solution Explorer найдит<strong>е</strong><br />

свойство Text и удалит<strong>е</strong> слово checkboxl.<br />

Properties<br />

' a X<br />

cKentCheckBox System.Wmdows.Porms..Check »<br />

• )1<br />

TsbStop<br />

True<br />

.<br />

Для удал<strong>е</strong>ния м <strong>е</strong>тки<br />

очистит<strong>е</strong> это пол<strong>е</strong>.<br />

{cbedcBoxl 4<br />

TextAlign Middieleft<br />

TexUmageRetation Overiay<br />

ThreeState False<br />

UseCompetibteT ect( Fat»<br />

UseMnemonk True<br />

UseVtsualStyleBeckC Tnie<br />

UseWaitCursoF FaEse<br />

___ iOsible--___ ____ Тш<strong>е</strong>_ ............<br />

Tert<br />

The text associated with the cofrtiel<br />

m _<br />

66 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

В изуиьны <strong>е</strong><br />

объ<strong>е</strong>кты<br />

.NET<br />

Объ<strong>е</strong>кты<br />

6вЬ1 gsHHW*<br />

.NET<br />

Х^вшищ<strong>е</strong><br />

данных<br />

иист(»умвктьг<br />

^Ь1зд<strong>е</strong>сь<br />

@<br />

П р ид ани<strong>е</strong> процз<strong>е</strong>ссионального вида.<br />

Щ<strong>е</strong>лкнит<strong>е</strong> в произвольном м<strong>е</strong>ст<strong>е</strong> формы в окн<strong>е</strong> Properties<br />

и найдит<strong>е</strong> свойство Text. Вв<strong>е</strong>дит<strong>е</strong> в это пол<strong>е</strong> названи<strong>е</strong><br />

Objectville Paper Company Contact List.<br />

Присвоив свойствам MaximizeBox и MinimizeBox знау<br />

ч<strong>е</strong>ни<strong>е</strong> False, можно убрать возможность разворачивать<br />

и сворачивать форму.<br />

При раскрытии формы<br />

на полный экран полож<strong>е</strong>ни<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся, форма<br />

выглядит н<strong>е</strong>красиво.<br />

Поэтому мы просто<br />

уб<strong>е</strong>р<strong>е</strong>м эту возможность.<br />

Propertws<br />

должно<br />

„одд<br />

Forml Sy5tem.Windows.Fortns.Form<br />

^owbTaskbar<br />

p- Size<br />

SizeGripS'^te<br />

StartPositior»<br />

Tag<br />

........:<br />

True<br />

408, 261<br />

Auto<br />

WindowsDefauttlocati.<br />

Свойство Text<br />

зада<strong>е</strong>т названи<strong>е</strong><br />

формы.<br />

Если окно Properties отсутству<strong>е</strong>т, выб<strong>е</strong>рит<strong>е</strong><br />

одноим<strong>е</strong>нную команду в м<strong>е</strong>ню View.<br />

Хорошим счита<strong>е</strong>тся прилож<strong>е</strong>ни<strong>е</strong>, с которым<br />

л<strong>е</strong>гко работать. Его функциональность должна<br />

соотв<strong>е</strong>тствовать ожиданиям ср<strong>е</strong>дн<strong>е</strong>статистич<strong>е</strong>ского<br />

пользоват<strong>е</strong>ля.<br />

дальш<strong>е</strong> > 67


напосл<strong>е</strong>док<br />

Т<strong>е</strong>стировани<strong>е</strong><br />

Осталось запустить программу и уб<strong>е</strong>диться, что она работа<strong>е</strong>т<br />

правильно! Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, как это сд<strong>е</strong>лать, поэтому просто<br />

нажмит<strong>е</strong> F5 или щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> с з<strong>е</strong>л<strong>е</strong>ной стр<strong>е</strong>лкой<br />

на пан<strong>е</strong>ли инструм<strong>е</strong>нтов (такж<strong>е</strong> можно выбрать команду<br />

Run из м<strong>е</strong>ню Debug).<br />

Запускать можно даж<strong>е</strong> н<strong>е</strong> полностью готовы<strong>е</strong> программы.<br />

Если в код<strong>е</strong> ИСР <strong>е</strong>сть ошибки, программа н<strong>е</strong> запустится.<br />

Компиляция<br />

профаммы<br />

п<strong>е</strong>р<strong>е</strong>писыва<strong>е</strong>т<br />

данны<strong>е</strong> в баз<strong>е</strong>.<br />

Э ти эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния<br />

П<strong>е</strong>р<strong>е</strong>ходить от одной<br />

записи базы к Эругом.<br />

UCP сначала компилиру<strong>е</strong>т,<br />

потом запуска<strong>е</strong>т на Выполн<strong>е</strong>ни<strong>е</strong><br />

Этот асп<strong>е</strong>кт<br />

буд<strong>е</strong>т подробно<br />

рассмотр<strong>е</strong>н<br />

в сл<strong>е</strong>дующ<strong>е</strong>й глав<strong>е</strong><br />

Objectville Paper Company Contact List<br />

И < n<br />

Contad 10:<br />

Name:<br />

Смтрапу:<br />

Tel^hone:<br />

БпаЙ;<br />

(Sent:<br />

UrtM:<br />

При запуск<strong>е</strong> программы ИСР выполня<strong>е</strong>т дв<strong>е</strong> оп<strong>е</strong>рации. Сначала<br />

она строит программу, зат<strong>е</strong>м вы полня<strong>е</strong>т <strong>е</strong><strong>е</strong>. Эта работа<br />

состоит из н<strong>е</strong>скольких этапов. Код компилиру<strong>е</strong>тся, то <strong>е</strong>сть<br />

пр<strong>е</strong>враща<strong>е</strong>тся в исполня<strong>е</strong>мый файл. Этот файл вм<strong>е</strong>ст<strong>е</strong> с другими<br />

р<strong>е</strong>сурсами пом<strong>е</strong>ща<strong>е</strong>тся в подпапку папки bin.<br />

Свой исполня<strong>е</strong>мый файл вм<strong>е</strong>ст<strong>е</strong> с базой SQL вы найд<strong>е</strong>т<strong>е</strong><br />

в папк<strong>е</strong> b in /d e b u g . Его запуск позволя<strong>е</strong>т сохранить вс<strong>е</strong> вн<strong>е</strong>с<strong>е</strong>нны<strong>е</strong><br />

в проц<strong>е</strong>сс<strong>е</strong> пользования прилож<strong>е</strong>ни<strong>е</strong>м изм<strong>е</strong>н<strong>е</strong>ния.<br />

В то вр<strong>е</strong>мя как при запуск<strong>е</strong> из ИСР база зам<strong>е</strong>ня<strong>е</strong>тся копи<strong>е</strong>й<br />

с данными из окна database Explorer.<br />

0<br />

Lloyd Jones<br />

0ad< Bax inc.<br />

(7181555-Ж8<br />

LJones@xbiad


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Как пр<strong>е</strong>вратить ВАШ Е прило)к<strong>е</strong>ни<strong>е</strong><br />

В прило)к<strong>е</strong>ни<strong>е</strong> для ВСЕХ<br />

Пока что прилож<strong>е</strong>ни<strong>е</strong> работа<strong>е</strong>т только на ваш<strong>е</strong>м компьют<strong>е</strong>р<strong>е</strong>.<br />

Никто н<strong>е</strong> мож<strong>е</strong>т им воспользоваться, купить <strong>е</strong>го у вас,<br />

увид<strong>е</strong>ть, какой вы зам<strong>е</strong>чат<strong>е</strong>льный программист и нанять<br />

на работу... даж<strong>е</strong> начальник и кли<strong>е</strong>нты н<strong>е</strong> видят сообщ<strong>е</strong>ния<br />

из ваш<strong>е</strong>й базы данных.<br />

<strong>C#</strong> позволя<strong>е</strong>т л<strong>е</strong>гко вн<strong>е</strong>дрить созданно<strong>е</strong> вами прилож<strong>е</strong>ни<strong>е</strong>.<br />

Вн<strong>е</strong>др<strong>е</strong>ни<strong>е</strong>м называ<strong>е</strong>тся установка программы на други<strong>е</strong><br />

компьют<strong>е</strong>ры. В ИСР Visual <strong>C#</strong> эта проц<strong>е</strong>дура осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

в два этапа.<br />

Выб<strong>е</strong>рит<strong>е</strong> команду Publish<br />

Contacts в м<strong>е</strong>ню Project.<br />

'СктШН -<br />

» Wew Project „<br />

0^<br />

' 2 3 'H / M Add Windows Form...<br />

^ jj ''J Add Class...<br />

M d Me» item...<br />

1' ^ Add Existing Item.,.<br />

@<br />

MA Ref«teiKe...<br />

M i Seiwce Reference.,,<br />

SelasaaitUpPmject<br />

Contorts Properties.«<br />

Publish Contacts k<br />

Визуальны<strong>е</strong><br />

о бьвкты<br />

■NET<br />

W<br />

Обмкты<br />

базы данных<br />

• НЕТ<br />

j<br />

Х{;айиАищ<strong>е</strong><br />

Ззяных<br />

И и "<br />

инструм<strong>е</strong>нты<br />

вн<strong>е</strong>др<strong>е</strong>ния<br />

.1 зд<strong>е</strong>сь<br />

При посмюо<strong>е</strong>нии<br />

р<strong>е</strong>ш<strong>е</strong>ния файлы<br />

копируются на<br />

ваш компьют<strong>е</strong>р.<br />

Проц<strong>е</strong>дура п у ­<br />

бликации созда<strong>е</strong>т<br />

выполня<strong>е</strong>мый<br />

конфигурационный<br />

файл, при помощи<br />

которого<br />

программу можно<br />

установить на<br />

любой компьют<strong>е</strong>р.<br />

О<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Finish<br />

в окн<strong>е</strong> Publish Wizard. Ваш<strong>е</strong><br />

прилож<strong>е</strong>ни<strong>е</strong> буд<strong>е</strong>т обработано,<br />

и вы увидит<strong>е</strong> папку<br />

в которую сохраня<strong>е</strong>тся<br />

файл setup.exe.<br />

Publish Wo:a*ti<br />

Where do you w ant to publish tfw application?<br />

^ c % th e location to pubfehthK si^iltcattore<br />

ШШ<br />

You may pubfish the appftcetton to a web site, FTP s«ver, or Шp i^ .<br />

bamptes:<br />

#<br />

В Visual Studio Express<br />

Команда Publish<br />

находится в м<strong>е</strong>ню Project,<br />

в то вр<strong>е</strong>мя как в других<br />

в<strong>е</strong>рсиях Visual Studio<br />

<strong>е</strong><strong>е</strong> можно обнаружить<br />

в м<strong>е</strong>ню Build.<br />

Fife share<br />

Web 5й<strong>е</strong><br />

WarveAmyappBcatton<br />

htt(K//www. mkroEt^conv'myappfic*rtion<br />

1 ^ Previ&us j| ... ] ( Imish J j. ^ ^ 1<br />

дальш<strong>е</strong> > 69


под<strong>е</strong>лит<strong>е</strong>сь любовью<br />

П<strong>е</strong>р<strong>е</strong>да<strong>е</strong>м прило}к<strong>е</strong>ни<strong>е</strong> пользоват<strong>е</strong>лям<br />

Посл<strong>е</strong> вн<strong>е</strong>др<strong>е</strong>ния у вас появится папка с им<strong>е</strong>н<strong>е</strong>м p u b lis h /.<br />

В н<strong>е</strong>й находятся вс<strong>е</strong> компон<strong>е</strong>нты, н<strong>е</strong>обходимы<strong>е</strong> для установки.<br />

Самым важным из них явля<strong>е</strong>тся файл se tu p . Им<strong>е</strong>нно он позволя<strong>е</strong>т<br />

установить прилож<strong>е</strong>ни<strong>е</strong> на любой компьют<strong>е</strong>р.<br />

цНСтДЛАЯЦи^.<br />

р у д ы п <strong>е</strong><br />

оСЩ о|ЭоЖ Н Ь1<br />

Д ля инсталляции вам<br />

могут понадобиться права<br />

адм инистратора.<br />

Если у вас <strong>е</strong>щ<strong>е</strong> н<strong>е</strong>т базы<br />

SQL Server Compact, инсталлятор<br />

автоматич<strong>е</strong>ски<br />

скача<strong>е</strong>т и установит <strong>е</strong><strong>е</strong>.<br />

На н<strong>е</strong>которых компьют<strong>е</strong>рах<br />

это возможно только<br />

при наличии у вас прав<br />

администратора. Щ<strong>е</strong>лкнит<strong>е</strong><br />

правой кнопкой мыши<br />

на файл<strong>е</strong> setup и выб<strong>е</strong>рит<strong>е</strong><br />

команду Run as administrator.<br />

Если у вас н<strong>е</strong>т такой возможности,<br />

нич<strong>е</strong>го страшного.<br />

Это н<strong>е</strong> пом<strong>е</strong>ша<strong>е</strong>т<br />

вам выполнять сл<strong>е</strong>дующи<strong>е</strong><br />

задания.<br />

э т о т файл говорит<br />

в инстйлдмру^ллу<br />

прогряллму-<br />

С помощью этого<br />

файла осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

инсталляция.<br />

С<strong>е</strong>кр<strong>е</strong>тарь сказала, что у нас уж<strong>е</strong><br />

работа<strong>е</strong>т новая база данных с контактами.<br />

Вы хорошо поработали и заслужили<br />

н<strong>е</strong>большой отдых...<br />

А<br />

1Саж<strong>е</strong>,тся, начальник довол<strong>е</strong>н.<br />

V Но п<strong>е</strong>р<strong>е</strong>д т <strong>е</strong> м кяк собирать<br />

^ i o /a H b b -Р от <strong>е</strong>ст ируш<br />

р<strong>е</strong>зулЕ?тдтЬ1сво<strong>е</strong>го тру<br />

70 глава 1


эфф<strong>е</strong>ктивность с <strong>C#</strong><br />

Работа НЕ оконч<strong>е</strong>на: пров<strong>е</strong>рим<br />

проц<strong>е</strong>сс установки<br />

П<strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м как открыть бутылку шампанского и отпраздновать<br />

поб<strong>е</strong>ду, нужно прот<strong>е</strong>стировать вн<strong>е</strong>др<strong>е</strong>ни<strong>е</strong> и установку<br />

Закройт<strong>е</strong> ИСР Visual Studio. Запустит<strong>е</strong> файл setup и укажит<strong>е</strong>,<br />

куда сл<strong>е</strong>ду<strong>е</strong>т установить ваш<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong>. Уб<strong>е</strong>дит<strong>е</strong>сь,<br />

что вс<strong>е</strong> работа<strong>е</strong>т так, как вы ожидали, —можно<br />

добавлять и р<strong>е</strong>дактировать записи, и вс<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ния сохраняются<br />

в баз<strong>е</strong> данных.<br />

Визуадьны<strong>е</strong> О бъ<strong>е</strong>кты<br />

объ<strong>е</strong>кты<br />

базы ааявы*<br />

• NET . .NET<br />

It<br />

XfsBu/iim«<br />

данных<br />

ІІн<strong>е</strong>трумвиі<br />

вн<strong>е</strong>др<strong>е</strong>ния<br />

В ; Щ<br />

Б: ы зд<strong>е</strong>сь<br />

Стр<strong>е</strong>лки<br />

и т<strong>е</strong>кстово<strong>е</strong><br />

пол<strong>е</strong> позволяют<br />

п<strong>е</strong>р<strong>е</strong>ходить<br />

от одной записи<br />

к другой, ч ^<br />

Objectville Paper Com pany Contact List<br />

la ill of§ I ^И!ФК a<br />

Coftad ID; I '<br />

Name:<br />

Company:<br />

Black Bax Inc.<br />

Tdephone: (718)555-5638<br />

Попробуйт<strong>е</strong>,<br />

вн&сти изм<strong>е</strong>н<strong>е</strong>ния<br />

б данны<strong>е</strong>.<br />

Bnail:<br />

Oert:<br />

ТЕСТИ РУЙ ТЕ В СЁ!<br />

Uones@d3lackbo3dnc .com<br />

a<br />

Т<strong>е</strong>стируйт<strong>е</strong> вашу программу,<br />

проц<strong>е</strong>дуру вн<strong>е</strong>др<strong>е</strong>ния, данны<strong>е</strong><br />

в ваш<strong>е</strong>м прилож<strong>е</strong>нии.<br />

LaS Ы1: edi sda , fv:3>‘ 26. 201С Q » "<br />

< -<br />

Вс<strong>е</strong> контакты<br />

на м<strong>е</strong>ст<strong>е</strong>. В<strong>е</strong>дь<br />

они являются<br />

частью<br />

базы данных<br />

ContactDB.sdf,<br />

которая была<br />

установл<strong>е</strong>на<br />

вм<strong>е</strong>ст<strong>е</strong><br />

с прилож<strong>е</strong>ни<strong>е</strong>м.<br />

дальш<strong>е</strong> ► 71


быстр<strong>е</strong><strong>е</strong> н<strong>е</strong> быва<strong>е</strong>т<br />

Управляющ<strong>е</strong><strong>е</strong> данными<br />

прилож<strong>е</strong>ни<strong>е</strong> готово<br />

Визуальны<strong>е</strong><br />

объ<strong>е</strong>кты<br />

■NET<br />

О бмкш ы<br />

базы данных<br />

.NET<br />

Х|1ана«ощ<strong>е</strong><br />

данных<br />

инструм<strong>е</strong>нты<br />

Вн<strong>е</strong>др<strong>е</strong>ния<br />

Visual Studio позволя<strong>е</strong>т с л<strong>е</strong>гкостью разработать<br />

Windows-прилож<strong>е</strong>ни<strong>е</strong>, написать базу данных и связать<br />

эти два объ<strong>е</strong>кта вм<strong>е</strong>ст<strong>е</strong>. Вы даж<strong>е</strong> смогли построить<br />

программу-инсталлятор вс<strong>е</strong>го н<strong>е</strong>сколькими<br />

дополнит<strong>е</strong>льным щ<strong>е</strong>лчками мыши.<br />

Q m б ум аж ной ка]= ^оЧ ки<br />

Имя: LloydJones О —<br />

Фирма: Black Box Inc.<br />

Т<strong>е</strong>л<strong>е</strong>фон: (718)555-5638<br />

Email: Uones@Xblackboxinc.com<br />

Кли<strong>е</strong>нт; Yes По<strong>е</strong>л, звонок: 05/26/07<br />

Д о э Л <strong>е</strong> К -<br />

ЗРроННой<br />

«Ц: Objectville Paper Company Contact list<br />

H i 4 \1 crf6 : ► И ! Я<br />

Cortad ID: 1 ............ }<br />

Name; Ltoyd Jones<br />

Csmpanjr: Hack Box Inc.<br />

Tdeptone; (718)555^638<br />

finaS:<br />

a « : В<br />

U o n e s # > d 3 la c k b o * in c .c o n i<br />

LaSCd: Wednesday, May Ж 2010<br />

наМноГо бьхсгор<strong>е</strong><strong>е</strong>,<br />

Ч<strong>е</strong>м к а за л о сь.<br />

Ср<strong>е</strong>дства Visual C # позволяют сфокусироваться на<br />

выполн<strong>е</strong>нии задания, в<strong>е</strong>дь вам уж<strong>е</strong> н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся<br />

писать код для окон, кнопок и доступа к баз<strong>е</strong> SQ,L.<br />

72 глава 1


2 ЭЗЦО Б с <strong>е</strong> Г о Л и Ш ь К о д<br />

+<br />

Под покровом<br />

Вы — программист, а н<strong>е</strong> просто пользоват<strong>е</strong>ль ИСР.<br />

И С Р мож<strong>е</strong>т сд<strong>е</strong>лать за вас много<strong>е</strong>, но н<strong>е</strong> всё. При написании прилож<strong>е</strong>ний<br />

часто приходится р<strong>е</strong>шать п овт оряю щ и <strong>е</strong>ся задачи. Пусть эту работу выполня<strong>е</strong>т<br />

ИСР. Вы ж<strong>е</strong> буд<strong>е</strong>т<strong>е</strong> в это вр<strong>е</strong>мя думать над бол<strong>е</strong><strong>е</strong> глобальными в<strong>е</strong>щами.<br />

Научившись писат ь код, вы получит<strong>е</strong> возможность р<strong>е</strong>шить любую<br />

задачу.


к вашим услугам<br />

Когда ßbi д<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> это...<br />

ИСР —это мощный инструм<strong>е</strong>нт. Но это вс<strong>е</strong>го лишь инструм<strong>е</strong>нт. При<br />

каждом ваш<strong>е</strong>м д<strong>е</strong>йствии он автоматич<strong>е</strong>ски созда<strong>е</strong>т код. Но это хорошо<br />

только при выполн<strong>е</strong>нии шаблонных задач или в случа<strong>е</strong>, когда код мож<strong>е</strong>т<br />

быть использован б<strong>е</strong>з дополнит<strong>е</strong>льных изм<strong>е</strong>н<strong>е</strong>ний.<br />

Посмотрим на д<strong>е</strong>йствия ИСР при разработк<strong>е</strong> типичного прилож<strong>е</strong>ния.<br />

Вс<strong>е</strong> эти задачи являются<br />

стандартными<br />

и тр<strong>е</strong>буют шаблонного<br />

кода. Поэтому их можно<br />

отдать на откуп ИСР.<br />

Создани<strong>е</strong> формы в Windows<br />

ИСР позволя<strong>е</strong>т строить различны<strong>е</strong> прилож<strong>е</strong>ния,<br />

но с<strong>е</strong>йчас мы рассмотрим вариант Windows<br />

Forms — программу, им<strong>е</strong>ющую визуальны<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты,<br />

наприм<strong>е</strong>р, формы и кнопки.<br />

! :т<br />

'9 =<br />

О<br />

При выбор<strong>е</strong> варианта<br />

W indows Form s A p p lic a tio n<br />

ИСР созда<strong>е</strong>т пустую ф орм<br />

у и добавля<strong>е</strong>т <strong>е</strong><strong>е</strong> к новому<br />

про<strong>е</strong>кту.<br />

П <strong>е</strong>р<strong>е</strong>таскивани<strong>е</strong> кнопки с пан<strong>е</strong>ли инструм<strong>е</strong>нтов<br />

на qx>pMy и двойной щ <strong>е</strong>лчок на н<strong>е</strong>й.<br />

Им<strong>е</strong>нно кнопки заставляют форму работать.<br />

На их прим<strong>е</strong>р<strong>е</strong> мы буд<strong>е</strong>м рассматривать различны<strong>е</strong><br />

асп<strong>е</strong>кты языка С#. Кром<strong>е</strong> того, они являются<br />

частью практич<strong>е</strong>ски любого создава<strong>е</strong>мого<br />

прилож<strong>е</strong>ния.<br />

о Задани<strong>е</strong> свойств qjopMU<br />

Окно Properties позволя<strong>е</strong>т л<strong>е</strong>гко пом<strong>е</strong>нять<br />

атрибуты практич<strong>е</strong>ски любого компон<strong>е</strong>нта<br />

программы.<br />

Окно Properties<br />

^<br />

‘простой способ самый /<br />

>^мит<strong>е</strong> клавишу<br />

Properties<br />

Form! Sy5tem.Window$.Ferms.Form<br />

.<br />

SbowlnTasfcbar "frt«“<br />

I' Size 4 0a 261<br />

StzeGnpStyte Auto<br />

StartPosJtron WirvdowsOefaultlocatt.<br />

Tag<br />

TopMost<br />

T ransparencvKey<br />

1O t^ ect^ ^<br />

False<br />

□<br />

Cons<br />

UieWaitCursor Fafs« .'3<br />

WindowState Normet<br />

Text<br />

Th« text essocmed wrtb the control.<br />

X<br />

74 глава 2


это вс<strong>е</strong>го лишь код<br />

...UCP д<strong>е</strong>ла<strong>е</strong>т это.<br />

Любы<strong>е</strong> ваши д<strong>е</strong>йствия приводят к изм<strong>е</strong>н<strong>е</strong>ниям<br />

кода, а значит, и файлов, которы<strong>е</strong> сод<strong>е</strong>ржат этот<br />

код. Иногда р<strong>е</strong>дактируются вс<strong>е</strong>го н<strong>е</strong>сколько строч<strong>е</strong>к,<br />

а иногда сист<strong>е</strong>ма созда<strong>е</strong>т новы<strong>е</strong> файлы.<br />

Эти файлы были<br />

созданы на баз<strong>е</strong> шаблона<br />

.ИСР созда<strong>е</strong>т ф айлы и п ап ки .<br />

— '1 ^<br />

М<br />

cU» FmS<br />

- Г»«**-«<br />

; J ^ 1 J<br />

W indow sA pplicationI<br />

.csproj<br />

Ь'<br />

ijs<br />

F o rm l .cs F o rm l .Designer.cs Program .cs Properties<br />

О<br />

...И С Р добавля<strong>е</strong>т код в qэaйл F o r m l . D e s i g n e r . c s , отв<strong>е</strong>чаю<br />

щ ий за появл<strong>е</strong>ни<strong>е</strong> кнопки на 75


ср<strong>е</strong>дства коммуникации<br />

Как ро)кдаются программы<br />

Программа на С# мож<strong>е</strong>т начинаться как набор оп<strong>е</strong>раторов в различных файлах, но в конц<strong>е</strong> должна получиться<br />

программа, работающая на ваш<strong>е</strong>м компьют<strong>е</strong>р<strong>е</strong>. Вот как это происходит.<br />

Любая программа начина<strong>е</strong>тся с файлов, т<strong>е</strong>кста кода<br />

Как вы уж<strong>е</strong> вид<strong>е</strong>ли, ИСР сохраня<strong>е</strong>т вашу программу в файлы. Эти файлы<br />

можно открыть и найти вс<strong>е</strong> добавл<strong>е</strong>нны<strong>е</strong> к про<strong>е</strong>кту эл<strong>е</strong>м<strong>е</strong>нты: формы,<br />

р<strong>е</strong>сурсы, код и проч<strong>е</strong><strong>е</strong>.<br />

ИСР можно пр<strong>е</strong>дставить как хороший р<strong>е</strong>дактор файлов. Он автоматич<strong>е</strong>ски<br />

д<strong>е</strong>ла<strong>е</strong>т отступы, выд<strong>е</strong>ля<strong>е</strong>т ключ<strong>е</strong>вы<strong>е</strong> слова цв<strong>е</strong>том, закрыва<strong>е</strong>т<br />

скобки и даж<strong>е</strong> пр<strong>е</strong>дполага<strong>е</strong>т, что вы напиш<strong>е</strong>т<strong>е</strong> в сл<strong>е</strong>дующую с<strong>е</strong>кунду.<br />

Другими словами, им<strong>е</strong>нно ИСР р<strong>е</strong>дактиру<strong>е</strong>т файлы, сод<strong>е</strong>ржащи<strong>е</strong> вашу<br />

программу.<br />

ИСР связыва<strong>е</strong>т вс<strong>е</strong> файлы программы в р<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong> пут<strong>е</strong>м создания файла<br />

(. s in ) и папки, в которой оказываются вс<strong>е</strong> мат<strong>е</strong>риалы. Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

сод<strong>е</strong>ржит список вс<strong>е</strong>х входящих в про<strong>е</strong>кт файлов (оно им<strong>е</strong><strong>е</strong>т расшир<strong>е</strong>ни<strong>е</strong><br />

. c s p ro j), посл<strong>е</strong>дни<strong>е</strong> ж<strong>е</strong> в свою оч<strong>е</strong>р<strong>е</strong>дь включают в с<strong>е</strong>бя список<br />

вс<strong>е</strong>х файлов, связанных с программой. В этой книг<strong>е</strong> мы буд<strong>е</strong>м строить<br />

р<strong>е</strong>ш<strong>е</strong>ния на основ<strong>е</strong> вс<strong>е</strong>го одного про<strong>е</strong>кта, но окно Solution Explorer позволя<strong>е</strong>т<br />

работать и с другими про<strong>е</strong>ктами.<br />

Программы<br />

можно писать<br />

даж<strong>е</strong> в Блокнот<strong>е</strong><br />

(Notepad), но это<br />

оч<strong>е</strong>нь долго.<br />

инструм<strong>е</strong>нты om.NET Framework<br />

<strong>C#</strong> —это вс<strong>е</strong>го лишь язык, и сам по с<strong>е</strong>б<strong>е</strong> он н<strong>е</strong> мож<strong>е</strong>т нич<strong>е</strong>го д<strong>е</strong>лать.<br />

Но зд<strong>е</strong>сь вам на помощь приходит т<strong>е</strong>хнология .NET Framework. При<br />

щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> разв<strong>е</strong>ртки окна на в<strong>е</strong>сь экран срабатыва<strong>е</strong>т код, указывающий,<br />

как им<strong>е</strong>нно должна выполняться эта оп<strong>е</strong>рация. Этот код<br />

явля<strong>е</strong>тся частью .NET Framework, как и други<strong>е</strong> кнопки, флажки, списки<br />

и даж<strong>е</strong> м<strong>е</strong>ханизмы связи с базой данных. Это хороший инструм<strong>е</strong>нт<br />

для создания графики, чт<strong>е</strong>ния и записи файлов, управл<strong>е</strong>ния наборами<br />

объ<strong>е</strong>ктов и прочих рутинных оп<strong>е</strong>раций.<br />

Инструм<strong>е</strong>нты .NET Framework находятся в пространствах им<strong>е</strong>н. Вы уж<strong>е</strong><br />

вид<strong>е</strong>ли их ран<strong>е</strong><strong>е</strong>, в в<strong>е</strong>рхн<strong>е</strong>й части кода. Это было пространство System .<br />

Windows. Forms —им<strong>е</strong>нно зд<strong>е</strong>сь сод<strong>е</strong>ржатся кнопки, флажки и формы.<br />

При создании любого про<strong>е</strong>кта Windows Forms в в<strong>е</strong>рхн<strong>е</strong>й части кода вы<br />

увидит<strong>е</strong> строчку u s in g System . Windows. Forms.<br />

76 глава 2


это вс<strong>е</strong>го лишь код<br />

Создани<strong>е</strong> исполня<strong>е</strong>мого файла<br />

Выбор команды Build Solution (м<strong>е</strong>ню Build) начина<strong>е</strong>т компиляцию<br />

ваш<strong>е</strong>й программы. Запуска<strong>е</strong>тся компилятор, то <strong>е</strong>сть<br />

инструм<strong>е</strong>нт, читающий код программы и пр<strong>е</strong>образующий <strong>е</strong>го<br />

в исполня<strong>е</strong>мый файл. Этот файл сохраня<strong>е</strong>тся на диск компьют<strong>е</strong>ра<br />

с расшир<strong>е</strong>ни<strong>е</strong>м . <strong>е</strong> х <strong>е</strong> . Для запуска программы достаточно<br />

дважды щ<strong>е</strong>лкнуть на <strong>е</strong>го им<strong>е</strong>ни. По умолчанию этот файл пом<strong>е</strong>ща<strong>е</strong>тся<br />

в папку bin, влож<strong>е</strong>нную в папку project. При публикации<br />

р<strong>е</strong>ш<strong>е</strong>ния он (вм<strong>е</strong>ст<strong>е</strong> с другими нужными файлами) копиру<strong>е</strong>тся<br />

в выбранную вами папку.<br />

В отв<strong>е</strong>т на команду Start Debugging (м<strong>е</strong>ню Debug) ИСР компилиру<strong>е</strong>т<br />

программу и запуска<strong>е</strong>т получ<strong>е</strong>нный файл на выполн<strong>е</strong>ни<strong>е</strong>.<br />

Сущ<strong>е</strong>ствуют и бол<strong>е</strong><strong>е</strong> сов<strong>е</strong>рш<strong>е</strong>нны<strong>е</strong> инструм<strong>е</strong>нты отладки,<br />

то <strong>е</strong>сть запуска программы с возможностью пр<strong>е</strong>рывания, чтобы<br />

вы могли понять м<strong>е</strong>ханизм происходящ<strong>е</strong>го.<br />

Программы работают В CLR<br />

Двойной щ<strong>е</strong>лчок на им<strong>е</strong>ни исполня<strong>е</strong>мого файла запуска<strong>е</strong>т<br />

программы. Но м<strong>е</strong>жду оп<strong>е</strong>рационной сист<strong>е</strong>мой и программой<br />

сущ<strong>е</strong>ству<strong>е</strong>т дополнит<strong>е</strong>льный «слой», называ<strong>е</strong>мый Common<br />

Language Runtime, или CLR (общ<strong>е</strong>языковая исполняющая<br />

ср<strong>е</strong>да). Раньш<strong>е</strong> (<strong>е</strong>щ<strong>е</strong> до изобр<strong>е</strong>т<strong>е</strong>ния С#) писать программы<br />

было намного сложн<strong>е</strong><strong>е</strong>, так как приходилось им<strong>е</strong>ть д<strong>е</strong>ло с аппаратным<br />

об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ни<strong>е</strong>м, заниматься низкоуровн<strong>е</strong>вым програм<br />

мировани<strong>е</strong>м. CLR —часто называ<strong>е</strong>мая такж<strong>е</strong> виртуальной машиной<br />

—явля<strong>е</strong>тся сво<strong>е</strong>го рода «п<strong>е</strong>р<strong>е</strong>водчиком» м<strong>е</strong>жду ваш<strong>е</strong>й<br />

программой и компьют<strong>е</strong>ром, на котором она работа<strong>е</strong>т.<br />

Функции CLR будут рассмотр<strong>е</strong>ны поздн<strong>е</strong><strong>е</strong>. Пока упомян<strong>е</strong>м<br />

только, что она отв<strong>е</strong>ча<strong>е</strong>т за работу с памятью компьют<strong>е</strong>ра,<br />

опр<strong>е</strong>д<strong>е</strong>ляя, что программа закончила работать с конкр<strong>е</strong>тными<br />

данными, и избавляясь от них. Н<strong>е</strong>которы<strong>е</strong> программисты привыкли<br />

самостоят<strong>е</strong>льно работать с памятью, но б<strong>е</strong>з этого можно<br />

обойтись, п<strong>е</strong>р<strong>е</strong>ложив заботу на CLR.<br />

На данном э т а п <strong>е</strong><br />

достаточно запомнить,<br />

что си я автоматич<strong>е</strong>ски<br />

запуска<strong>е</strong>т ваши<br />

программы- Бол<strong>е</strong><strong>е</strong><br />

подробно она буд<strong>е</strong>т<br />

рассмотр<strong>е</strong>на поздн<strong>е</strong><strong>е</strong>.<br />

дальш<strong>е</strong> * 77


ваш мал<strong>е</strong>нький помощник<br />

Писать код помога<strong>е</strong>т UCP<br />

с частью возможност<strong>е</strong>й ИСР вы уж<strong>е</strong> познакомились.<br />

Зд<strong>е</strong>сь ж<strong>е</strong> мы бол<strong>е</strong><strong>е</strong> д<strong>е</strong>тально рассмотрим н<strong>е</strong>которы<strong>е</strong><br />

инструм<strong>е</strong>нты.<br />

о О кно Solution E xplorer сод<strong>е</strong>ржит список вс<strong>е</strong>х част<strong>е</strong>й про<strong>е</strong>кта<br />

Вам пр<strong>е</strong>дстоит п<strong>е</strong>р<strong>е</strong>ключаться с одного класса на другой и прощ<strong>е</strong> вс<strong>е</strong>го<br />

это д<strong>е</strong>лать, используя окно Solution Explorer. Вот вид этого окна посл<strong>е</strong><br />

создания программы обм<strong>е</strong>на контактными данными:<br />

Solution Explorer<br />

Ä i j S t . ; .<br />

*33 Solution 'Contacts' (1 projectj<br />

^ I^^Contactsi<br />

^ ^ Properties<br />

l> References<br />

Ej.<br />

appxonfig<br />

ContactDB,sdf<br />

ContactDBDataSet.xsd<br />

i> Э Forml .cs<br />

Progrann.cs<br />

» П X<br />

)<br />

В окн<strong>е</strong> Solution Explorer<br />

Можно посмотр<strong>е</strong>ть,<br />

о каких папках на -<br />

ходятся т<strong>е</strong> или ины<strong>е</strong><br />

файлы.<br />

Вкладки позволяют л <strong>е</strong>гко п<strong>е</strong>р<strong>е</strong>йти от одного ф айла к другом у<br />

Так как типичная программа состоит из множ<strong>е</strong>ства файлов, приходится<br />

работать с н<strong>е</strong>сколькими файлами одновр<strong>е</strong>м<strong>е</strong>нно. Каждый из них им<strong>е</strong><strong>е</strong>т<br />

Зд<strong>е</strong>сь находится<br />

файл с р<strong>е</strong>сурсами<br />

формы,<br />

к которому вы<br />

добавляли логотип<br />

компании.<br />

открыты дв<strong>е</strong><br />

вторая с кодом,<br />

пользуйт<strong>е</strong>сь<br />

78 глава 2


это вс<strong>е</strong>го лишь код<br />

ИСР пом ога<strong>е</strong>т писать код<br />

Зам<strong>е</strong>чали ли вы в проц<strong>е</strong>сс<strong>е</strong> набора кода мал<strong>е</strong>нько<strong>е</strong> всплывающ<strong>е</strong><strong>е</strong> окошко? Это<br />

крайн<strong>е</strong> пол<strong>е</strong>зная функция 1п1<strong>е</strong>1И8<strong>е</strong>п8<strong>е</strong>. Она показыва<strong>е</strong>т возможны<strong>е</strong> способы зав<strong>е</strong>рш<strong>е</strong>ния<br />

строчки кода. Наприм<strong>е</strong>р, <strong>е</strong>сли вы набрали слово М <strong>е</strong>ззад<strong>е</strong>Вох и поставили<br />

точку, дальш<strong>е</strong> мож<strong>е</strong>т сл<strong>е</strong>довать только:<br />

MessageBox.<br />

Ф Equals<br />

# ReferenceEquals<br />

,ф|<br />

ИСР зна<strong>е</strong>т, что MessageBox им<strong>е</strong><strong>е</strong>т три<br />

м<strong>е</strong>тода: Equals,, ReferenceEquals и Show.<br />

Паи ввод<strong>е</strong> буквы S буд<strong>е</strong>т выбран вариант<br />

Show. Вам остан<strong>е</strong>тся нажать Enter.<br />

Иногда эта функция оч<strong>е</strong>нь экономит<br />

вр<strong>е</strong>мя.<br />

Если посл<strong>е</strong> выбора варианта Show нап<strong>е</strong>чатать (, функция IntelliSense пр<strong>е</strong>дложит<br />

вам варианты заполн<strong>е</strong>ния строки:<br />

Сущ<strong>е</strong>-ству<strong>е</strong>т<br />

ЯЗ- способ<br />

вызова м<strong>е</strong>тода<br />

Show для<br />

MessageBox.<br />

HessageBox.Showd<br />

______ __________________________________ _________________________ ____________<br />

«essageBox.ShOM(string text, string caption)<br />

Displays 3 message box with specified text and caption.<br />

tart; The text to display in the message box<br />

В ИСР сущ<strong>е</strong>ствуют сокращ<strong>е</strong>ния, называ<strong>е</strong>мы<strong>е</strong> фрагм<strong>е</strong>нтами кода. Для их вставки<br />

достаточно нап<strong>е</strong>чатать нужную аббр<strong>е</strong>виатуру. К прим<strong>е</strong>ру, <strong>е</strong>сли нап<strong>е</strong>чатать ttibox<br />

и дважды нажать клавишу Tab, появится строка для м<strong>е</strong>тода M essageBox. Show:<br />

MessageBox. Show!<br />

J<br />

О кно E rro r List показыва<strong>е</strong>т ошибки ком пиляции<br />

Вы даж<strong>е</strong> н<strong>е</strong> пр<strong>е</strong>дставля<strong>е</strong>т<strong>е</strong>, как л<strong>е</strong>гко сд<strong>е</strong>лать оп<strong>е</strong>чатку при набор<strong>е</strong> кода на С#!<br />

К счастью, сущ<strong>е</strong>ству<strong>е</strong>т инструм<strong>е</strong>нт, позволяющий бороться с этой пробл<strong>е</strong>мой.<br />

При постро<strong>е</strong>нии р<strong>е</strong>ш<strong>е</strong>ния всё, м<strong>е</strong>шающ<strong>е</strong><strong>е</strong> компиляции, буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>но<br />

в окн<strong>е</strong> Error List, располож<strong>е</strong>нном в нижн<strong>е</strong>й части экрана:<br />

В окн<strong>е</strong> Error<br />

List бк>! найд<strong>е</strong>т<strong>е</strong><br />

список вс<strong>е</strong>х<br />

ошибок,<br />

м<strong>е</strong>шаьош,1^Х<br />

компиляции<br />

iA.pozpaMMt>g( h i )<br />

Н<strong>е</strong>корр<strong>е</strong>ктный код<br />

подч<strong>е</strong>ркива<strong>е</strong>тся<br />

красным цв<strong>е</strong>том.<br />

дальш<strong>е</strong> ► 79


подробности<br />

Любы<strong>е</strong> д<strong>е</strong>йствия В<strong>е</strong>дут к изм<strong>е</strong>н<strong>е</strong>нию кода<br />

Посмотрим, каким образом ИСР пиш<strong>е</strong>т код. Откройт<strong>е</strong><br />

Visual Studio и создайт<strong>е</strong> новый про<strong>е</strong>кт Windows Forms<br />

Application.<br />

Значок «Упражн<strong>е</strong>ни<strong>е</strong>!»<br />

явля<strong>е</strong>тся сигналом<br />

к запуску Visual Studio, л<br />

^ ^ і/<br />

Уп]^ажн<strong>е</strong>ни<strong>е</strong>!<br />

Просмотр кода<br />

і<br />

Откройт<strong>е</strong> файл F o rm l.D e s ig n e r.c s , но н<strong>е</strong> в конструктор<strong>е</strong> форм. Для этого Ж<br />

щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на им<strong>е</strong>ни файла в окн<strong>е</strong> Solution Explorer и выб<strong>е</strong>рит<strong>е</strong><br />

команду View Code. Посмотрит<strong>е</strong> на объявл<strong>е</strong>ни<strong>е</strong> класса Forml:<br />

p a r t i a l c la s s Forml<br />

О<br />

м. .olTopZZZ.<br />

Добавл<strong>е</strong>ни<strong>е</strong> к срорм<strong>е</strong> эл<strong>е</strong>м <strong>е</strong>нта PictureBox<br />

Привыкайт<strong>е</strong> работать с множ<strong>е</strong>ством вкладок. В<strong>е</strong>рнит<strong>е</strong>сь в окно Solution Explorer<br />

и откройт<strong>е</strong> конструктор форм двойным щ<strong>е</strong>лчком на им<strong>е</strong>ни файла F o rm l. cs. П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong><br />

на форму эл<strong>е</strong>м<strong>е</strong>нт PictureBox.<br />

О<br />

Просм отр созданного конструктором для эл<strong>е</strong>м<strong>е</strong>нта PictureBox кода<br />

В<strong>е</strong>рнит<strong>е</strong>сь на вкладку Form LDesigner.es. Найдит<strong>е</strong> вот эту строчку:<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на квадратик<strong>е</strong><br />

Ґ со знаком «плюс».<br />

+ Windows Form D e sig n e r g e n e ra te d code<br />

Щ<strong>е</strong>лчок на этом квадратик<strong>е</strong> раскро<strong>е</strong>т код. Найдит<strong>е</strong> в н<strong>е</strong>м сл<strong>е</strong>дующи<strong>е</strong> строчки:<br />

/ /<br />

/ / p ic t u r e B o x l<br />

/ /<br />

t h i s . p i c t u r e B o x l .L o c a t i o n = new S y s t e m .D r a w in g .P o in t (2 7 6 , 2 8 );<br />

t h is .p ic t u r e B o x l.N a m e = " p ic tu r e B o x l" ;<br />

t h i s . p i c t u r e B o x l . S iz e = new S y s te m .D r a w in g . S i z e (100, 5 0 );<br />

t h i s .p i c t u r e B o x l .T a b ln d e x = 0;<br />

Ваши знач<strong>е</strong>ния<br />

парам<strong>е</strong>тров<br />

Location<br />

и Size будут<br />

отличать>ся<br />

от указанных<br />

в книг<strong>е</strong>.<br />

t h i s .p i c t u r e B o x l .T a b S t o p = f a l s e ;<br />

80 глава 2


это вс<strong>е</strong>го лишь код<br />

Ч т о >к<strong>е</strong> Вс<strong>е</strong> это значит?<br />

в в<strong>е</strong>рхн<strong>е</strong>й части кода вы увидит<strong>е</strong> строки:<br />

/ / /<br />

/ / /<br />

/ / /<br />

/ / /<br />

<br />

Обязат<strong>е</strong>льный м <strong>е</strong>тод для подд<strong>е</strong>ржки кон структора - н<strong>е</strong> изм <strong>е</strong>няйт<strong>е</strong><br />

сод<strong>е</strong>ржимо<strong>е</strong> данн ого м <strong>е</strong>тода при помощи р <strong>е</strong>дак тора к о д а .<br />

< / summary><br />

Чащ<strong>е</strong> вс<strong>е</strong>го комм<strong>е</strong>нтарии<br />

пом<strong>е</strong>чаются двумя косыми<br />

сл<strong>е</strong>шами (//)■ Но ИСР<br />

иногда м о ж <strong>е</strong> т поставить<br />

три сл<strong>е</strong>ша.<br />

Это комм<strong>е</strong>нтарии XML,<br />

о которых вы узна<strong>е</strong>т<strong>е</strong><br />

в разд<strong>е</strong>л<strong>е</strong> # 1 Прилож<strong>е</strong>ния.<br />

Для д<strong>е</strong>т<strong>е</strong>й н<strong>е</strong>т нич<strong>е</strong>го бол<strong>е</strong><strong>е</strong> притягат<strong>е</strong>льного, ч<strong>е</strong>м табличка с надписью<br />

«Н<strong>е</strong> трогать!» Н<strong>е</strong> отрицайт<strong>е</strong>, вы ж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что вам тож<strong>е</strong> хоч<strong>е</strong>тся...<br />

поэтому отр<strong>е</strong>дактиру<strong>е</strong>м сод<strong>е</strong>ржимо<strong>е</strong> данного м<strong>е</strong>тода, воспользовавшись<br />

р<strong>е</strong>дактором кода! Добавьт<strong>е</strong> к форм<strong>е</strong> кнопку и выполнит<strong>е</strong><br />

сл<strong>е</strong>дующи<strong>е</strong> д<strong>е</strong>йствия:<br />

О<br />

О тр<strong>е</strong>дактируйт<strong>е</strong> свойство T e x t кнопки b u tto n l. Как вы<br />

д ум а<strong>е</strong>т<strong>е</strong>, что изм<strong>е</strong>нится в окн<strong>е</strong> Properties?<br />

Сд<strong>е</strong>лайт<strong>е</strong> и посмотрит<strong>е</strong>, что получится! Зат<strong>е</strong>м в<strong>е</strong>рнит<strong>е</strong>сь в конструктор<br />

форм и пров<strong>е</strong>рьт<strong>е</strong> свойство Text. Оно изм<strong>е</strong>нилось?<br />

О<br />

Воспользуйт<strong>е</strong>сь окном Properties для р<strong>е</strong>дактирования<br />

свойства Nam e какого-нибудь объ<strong>е</strong>кта.<br />

В окн<strong>е</strong> Properties это свойство находится вв<strong>е</strong>рху и называ<strong>е</strong>тся<br />

“(Name)». Каки<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ния произойдут с кодом? Обратит<strong>е</strong> внимани<strong>е</strong><br />

на комм<strong>е</strong>нтарии.<br />

О п р и св о й т<strong>е</strong> свойству Location знач<strong>е</strong>ни<strong>е</strong> ( 0 ,0 ). И зм<strong>е</strong>нит<strong>е</strong><br />

парам<strong>е</strong>тр S ize , ув<strong>е</strong>личив разм<strong>е</strong>р кнопки.<br />

У вас получилось?<br />

Для просмотра<br />

р<strong>е</strong>зультата<br />

U запускать<br />

программу.<br />

Forml.cs [Р<strong>е</strong>ядп].<br />

0 В<strong>е</strong>рнит<strong>е</strong>сь в конструктор кода и произвольным образом<br />

пом<strong>е</strong>няйт<strong>е</strong> свойство BackColor.<br />

Внимат<strong>е</strong>льно посмотрит<strong>е</strong> на код Forml .D e s ig n e r . cs. Появились<br />

ли в н<strong>е</strong>м новы<strong>е</strong> строчки?<br />

Пом<strong>е</strong>нять код прощ<strong>е</strong> вс<strong>е</strong>го ср<strong>е</strong>дствами ИСР.<br />

дальш<strong>е</strong> > 81


программа д<strong>е</strong>ла<strong>е</strong>т заявл<strong>е</strong>ни<strong>е</strong><br />

С труктура программы<br />

Код любой программы на <strong>C#</strong> структуриру<strong>е</strong>тся<br />

одинаково. Вс<strong>е</strong> программы используют пространства<br />

им<strong>е</strong>н, классы и м<strong>е</strong>тоды.<br />

им<strong>е</strong>н, отд<strong>е</strong>ляя ^о/^®^^Я-янстбо<br />

■n e t F ra m eZ rL<br />

Класс сод<strong>е</strong>ржит^<br />

фрагм<strong>е</strong>нт ваш<strong>е</strong>й<br />

программы (оч<strong>е</strong>нь<br />

мал<strong>е</strong>ньки<strong>е</strong> программы<br />

могут состоять<br />

из вс<strong>е</strong>го одного класса)<br />

Класс включа<strong>е</strong>т один или<br />

н<strong>е</strong>сколько м<strong>е</strong>тодов. М<strong>е</strong>тоды вс<strong>е</strong>гда<br />

^инадл<strong>е</strong>ж ам какомц-лиЗп классы<br />

м<strong>е</strong>тоды. 6 сбою оч<strong>е</strong>р<strong>е</strong>дь, состоят<br />

из оп<strong>е</strong>раторов.<br />

Внимат<strong>е</strong>льно рассмотрим код<br />

Откройт<strong>е</strong> код про<strong>е</strong>кта Contacts F o rm l. cs, чтобы<br />

рассмотр<strong>е</strong>ть <strong>е</strong>го фрагм<strong>е</strong>нты.<br />

О<br />

*айл кода начина<strong>е</strong>тся с п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния инструм<strong>е</strong>нтов .NET Framework<br />

в в<strong>е</strong>рхн<strong>е</strong>й части любого файла программы вы обнаружит<strong>е</strong> набор строк, начинающихся<br />

с оп<strong>е</strong>ратора u sin g . Они указывают, с какой частью .NET Framework буд<strong>е</strong>т работать программа.<br />

Чтобы использовать классы из других пространств им<strong>е</strong>н, нужно указать их при<br />

помощи дир<strong>е</strong>ктивы u sin g . Для постро<strong>е</strong>ния форм прим<strong>е</strong>ня<strong>е</strong>тся множ<strong>е</strong>ство инструм<strong>е</strong>нтов<br />

.NET Framework, поэтому в начал<strong>е</strong> программы так много строк с дир<strong>е</strong>ктивой u sin g .<br />

using System;<br />

using System.Collections.Generic;<br />

using System.ComponentModel;<br />

using System.Data;<br />

using System.Drawing;<br />

using System.Linq;<br />

using System.Text;<br />

using System.Windows.Forms;<br />

Таки<strong>е</strong> строчки<br />

находятся в в<strong>е</strong>рхн<strong>е</strong>й<br />

части любого кода.<br />

1^ажаая из них<br />

показыва<strong>е</strong>т, како<strong>е</strong><br />

из .NET Framework<br />

использу<strong>е</strong>т тот<br />

или инои файл .CS.<br />

В принцип<strong>е</strong> б<strong>е</strong>з оп<strong>е</strong>ратора u s in g можно обойтись, <strong>е</strong>сли пользоваться полными им<strong>е</strong>нами.<br />

Если строчка u s in g System .W indows. Forms отсутству<strong>е</strong>т, окно сообщ<strong>е</strong>ний можно создать,<br />

написав S ystem . Windows. Form s. M essageBox. Show(), и компилятор вс<strong>е</strong> равно пойм<strong>е</strong>т,<br />

како<strong>е</strong> пространство им<strong>е</strong>н вы им<strong>е</strong><strong>е</strong>т<strong>е</strong> в виду.<br />

82 глава 2


это вс<strong>е</strong>го лишь код<br />

0 ТТрогроААМЫ н а C # и с п о л ь з у ю т кл а с с ы<br />

Программы на <strong>C#</strong> используют классы. Каждый класс выполня<strong>е</strong>т свою задачу. Когда вы создавали<br />

свою п<strong>е</strong>рвую программу, ИСР добавила класс Forml, отображающий формы.<br />

t r<br />

namespace Contacts<br />

Для программы Contacts, ИСР созда<strong>е</strong>т<br />

одноим<strong>е</strong>нно<strong>е</strong> пространство им<strong>е</strong>н. Им<strong>е</strong>нно в этом<br />

пространств<strong>е</strong> находится вс<strong>е</strong> сод<strong>е</strong>ржимо<strong>е</strong> скобок.<br />

Обращайт<strong>е</strong><br />

внимани<strong>е</strong><br />

на пары<br />

скобок. Ср<strong>е</strong>ди<br />

них могут<br />

попадаться<br />

влож<strong>е</strong>нны<strong>е</strong>.<br />

ргоЬИс partial class Forml<br />

^<br />

{<br />

Form<br />

Класс Form l сод<strong>е</strong>ржит код создания как самой<br />

формы, так и <strong>е</strong><strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния. ИСР<br />

добавля<strong>е</strong>т этот класс при создании про<strong>е</strong>кта<br />

Windows Form Application.<br />

Классы сод<strong>е</strong>ржат м<strong>е</strong>тоды<br />

Для выполн<strong>е</strong>ния различных д<strong>е</strong>йствий классы используют м<strong>е</strong>тод. М<strong>е</strong>тод б<strong>е</strong>р<strong>е</strong>т входны<strong>е</strong><br />

данны<strong>е</strong> и производит н<strong>е</strong>которо<strong>е</strong> д<strong>е</strong>йстви<strong>е</strong>. Данны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>даются при помощи парам<strong>е</strong>тров.<br />

Им<strong>е</strong>нно от них зависит пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода. Слово v o id п<strong>е</strong>р<strong>е</strong>д названи<strong>е</strong>м м<strong>е</strong>тода означа<strong>е</strong>т,<br />

что он н<strong>е</strong> возвраща<strong>е</strong>т никаких парам<strong>е</strong>тров.<br />

piiblic Forml О<br />

{<br />

}<br />

InitializeComponentO;<br />

Зд<strong>е</strong>сь вызыва<strong>е</strong>тся м<strong>е</strong>тод<br />

tnitializeComponent().<br />

Каждый оп<strong>е</strong>ратор выполня<strong>е</strong>т только одно д<strong>е</strong>йстви<strong>е</strong><br />

Строкой M essageBox. Show {) вы добавля<strong>е</strong>т<strong>е</strong> оп<strong>е</strong>ратор. Им<strong>е</strong>нно из оп<strong>е</strong>раторов составл<strong>е</strong>ны<br />

м<strong>е</strong>тоды. При вызов<strong>е</strong> м<strong>е</strong>тода выполня<strong>е</strong>тся сначала п<strong>е</strong>рвый оп<strong>е</strong>ратор, потом сл<strong>е</strong>дующий<br />

и т. д. Достигнув конца списка оп<strong>е</strong>раторов или оп<strong>е</strong>ратора r e t u r n , м<strong>е</strong>тод зав<strong>е</strong>рша<strong>е</strong>т работу.<br />

М<strong>е</strong>тоЭ pictureBoxi-^ChckO<br />

вызыва<strong>е</strong>тся<br />

графич<strong>е</strong>ском фрагм<strong>е</strong>нт<strong>е</strong>.<br />

Этот м<strong>е</strong>тод им<strong>е</strong><strong>е</strong>т<br />

два парам<strong>е</strong>тра:<br />

sender и <strong>е</strong>.<br />

private void pictureBoxlClick(object sender, EventArgs e)<br />

{<br />

}<br />

MessageBox.Show("Contact List 1.0", "About");<br />

Это оп<strong>е</strong>ратор, вызывающий<br />

диалогово<strong>е</strong> окно.<br />

Оп<strong>е</strong>ратор вызыва<strong>е</strong>т м<strong>е</strong>тод Show(),<br />

принадл<strong>е</strong>жащий классу MessageBox в<br />

пространств<strong>е</strong> им<strong>е</strong>н System.Wlndows.Forms.<br />

Оп<strong>е</strong>ратор п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т м<strong>е</strong>тоду Show Q два парам<strong>е</strong>тра:<br />

строку, которая буд<strong>е</strong>т отображаться<br />

в окн<strong>е</strong> диалога и заголовок этого окна.<br />

дальш<strong>е</strong> > 83


<strong>е</strong>щ<strong>е</strong> бол<strong>е</strong><strong>е</strong> подробно<br />

Начало работы программы<br />

При создании нового р<strong>е</strong>ш<strong>е</strong>ния ИСР добавля<strong>е</strong>т файл Program .cs. Найдит<strong>е</strong><br />

<strong>е</strong>го в окн<strong>е</strong> Solution Explorer и дважды щг<strong>е</strong>лкнит<strong>е</strong> на им<strong>е</strong>ни. Внутри<br />

класса Program вы обнаружит<strong>е</strong> м<strong>е</strong>тод Main {). Этот м<strong>е</strong>тод явля<strong>е</strong>тся точкой<br />

входа, то <strong>е</strong>сть им<strong>е</strong>нно отсюда программа начина<strong>е</strong>т работу.<br />

Нй С*<br />

оозможна илолько<br />

одна точка входа<br />

‘^ о м<strong>е</strong>тод MainQ<br />

а<br />

Этот код, автоматич<strong>е</strong>ски созданный<br />

6 упражн<strong>е</strong>нии из пр<strong>е</strong>дыдущ<strong>е</strong>й главы.<br />

бы найд<strong>е</strong>т<strong>е</strong> в файл<strong>е</strong> Program.cs.<br />

using System;<br />

using System.Linq;<br />

using System.Collections.Generic;<br />

using System.Windows.Forms;<br />

О<br />

namespace Contacts<br />

{ о<br />

static class Program<br />

{<br />

/// <br />

/// Точка входа в<br />

III <br />

}<br />

[STAThread]<br />

\Cod находится<br />

6 пространств<strong>е</strong><br />

им<strong>е</strong>н Contacts.<br />

|(о д Лод уВ<strong>е</strong>ЛиЧгад<strong>е</strong>ЛьНьхМ сзи<strong>е</strong>КЛоМ<br />

и бол<strong>е</strong><strong>е</strong> косы<strong>е</strong> ч<strong>е</strong>рты<br />

/ в начал<strong>е</strong> строки обозначают<br />

I / комм<strong>е</strong>нтарии.<br />

прилож<strong>е</strong>ни<strong>е</strong><br />

static void Main О<br />

{ О<br />

Application.EnableVisualStyles();<br />

}<br />

Программа начина<strong>е</strong>т<br />

работу с точка входа.<br />

QApplication.SetCompatibleTextRenderingDefault(false);<br />

Application. Run (new FormlO);^<br />

Этот оп<strong>е</strong>ратор созда<strong>е</strong>т<br />

и отобража<strong>е</strong>т форму<br />

Contacts, а такж<strong>е</strong><br />

зав<strong>е</strong>рша<strong>е</strong>т программу<br />

при закрытии формы.<br />

, ч а с т ь и м <strong>е</strong> н и<br />

1


это вс<strong>е</strong>го лишь код<br />

О<br />

Q<br />

О<br />

Встро<strong>е</strong>нны<strong>е</strong> функции C # и .NET.<br />

Подобны<strong>е</strong> строчки находятся в в<strong>е</strong>рхн<strong>е</strong>й части почти<br />

вс<strong>е</strong>х файлов классов С#. System .W indow s.Form s<br />

это пространство им<strong>е</strong>н. Строка u s in g System .<br />

Windows . Forms да<strong>е</strong>т программ<strong>е</strong> доступ ко вс<strong>е</strong>м объ<strong>е</strong>ктам<br />

этого пространства. В данном случа<strong>е</strong> к визуальным<br />

эл<strong>е</strong>м<strong>е</strong>нтам —кнопкам и формам.<br />

Выбор пространства им<strong>е</strong>н для кода.<br />

ИСР назвала созданно<strong>е</strong> пространство им<strong>е</strong>н<br />

C o n ta c ts (в соотв<strong>е</strong>тствии с им<strong>е</strong>н<strong>е</strong>м про<strong>е</strong>кта).<br />

Им<strong>е</strong>нно этому пространству относится в<strong>е</strong>сь код.<br />

Код принадл<strong>е</strong>жит к конкр<strong>е</strong>тному классу.<br />

В ваш<strong>е</strong>й программ<strong>е</strong> этот класс называ<strong>е</strong>тся<br />

Program. Он сод<strong>е</strong>ржит код запуска программы<br />

и код вызова формы Contacts.<br />

Наш код сод<strong>е</strong>ржит один м<strong>е</strong>тод, состоящий<br />

из н<strong>е</strong>скольких оп<strong>е</strong>раторов.<br />

Внутри любого м<strong>е</strong>тода мож<strong>е</strong>т находиться произвольно<strong>е</strong><br />

колич<strong>е</strong>ство оп<strong>е</strong>раторов. В наш<strong>е</strong>й программ<strong>е</strong><br />

им<strong>е</strong>нно оп<strong>е</strong>раторы вызывают форму<br />

Contacts.<br />

Точка входа.<br />

Каждая программа на <strong>C#</strong> должна им<strong>е</strong>ть один м<strong>е</strong>тод<br />

с названи<strong>е</strong>м Main. Им<strong>е</strong>нно он выполня<strong>е</strong>тся<br />

п<strong>е</strong>рвым. <strong>C#</strong> пров<strong>е</strong>ря<strong>е</strong>т классы на <strong>е</strong>го наличи<strong>е</strong>,<br />

пока н<strong>е</strong> находит строчку s t a t i c v o id Main ().<br />

Посл<strong>е</strong> этого выполня<strong>е</strong>тся п<strong>е</strong>рвый и вс<strong>е</strong> сл<strong>е</strong>дующи<strong>е</strong><br />

за ним оп<strong>е</strong>раторы.<br />

В<br />

Пост<strong>е</strong>п<strong>е</strong>нно вами<br />

программы 5удцт<br />

сод<strong>е</strong>ржать вс<strong>е</strong> дольш<strong>е</strong><br />

пространств им<strong>е</strong>н.<br />

Б<strong>е</strong>з строчки using вам<br />

прид<strong>е</strong>тся в явном вид<strong>е</strong> вводить<br />

Sustem.Windows. Forms при<br />

обращ<strong>е</strong>нии к объ<strong>е</strong>кту из этого<br />

пространства им<strong>е</strong>н.<br />

Пространства им<strong>е</strong>н<br />

позволяют использовать одни<br />

и т<strong>е</strong> ж<strong>е</strong> им<strong>е</strong>на в различных<br />

программах, при условии, что<br />

программы н<strong>е</strong> принадл<strong>е</strong>жат<br />

к одному пространству.<br />

н<strong>е</strong>сколько классоб.<br />

Т<strong>е</strong>хнич<strong>е</strong>ски програм м а<br />

^ мож<strong>е</strong>т им<strong>е</strong>т ь н<strong>е</strong>сколько<br />

\ только указать, кякои из<br />

-V них буд<strong>е</strong>т точкой входа.<br />

Любая программа на <strong>C#</strong><br />

должна им<strong>е</strong>ть <strong>е</strong>динств<strong>е</strong>нный<br />

м<strong>е</strong>тод Main. Он явля<strong>е</strong>тся<br />

точкой входа дая ваш<strong>е</strong>го<br />

кода.<br />

При запуск<strong>е</strong> кода м<strong>е</strong>тод<br />

M ain () выполня<strong>е</strong>тся<br />

ПЕРВЫМ.<br />

дальш<strong>е</strong> > 85


эл<strong>е</strong>гантны<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ния<br />

Р<strong>е</strong>дактировани<strong>е</strong> точки Входа<br />

в программ<strong>е</strong> главно<strong>е</strong> —наличи<strong>е</strong> точки входа. При<br />

этом н<strong>е</strong> им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>, к какому классу принадл<strong>е</strong>жит<br />

сод<strong>е</strong>ржащий <strong>е</strong><strong>е</strong> м<strong>е</strong>тод и каки<strong>е</strong> д<strong>е</strong>йствия<br />

производит. Откройт<strong>е</strong> программу из главы 1<br />

и удалит<strong>е</strong> м<strong>е</strong>тод Main, чтобы создать <strong>е</strong>го заново.<br />

Упражн<strong>е</strong>ни<strong>е</strong>!<br />

В файл<strong>е</strong> P rogram . cs присвойт<strong>е</strong> м<strong>е</strong>тоду Main имя NotM ain и попробуйт<strong>е</strong><br />

построить и запустить программу. Что произойд<strong>е</strong>т?<br />

Яагуцщцт<strong>е</strong>. ч то<br />

и-ромзоияло при<br />

изм<strong>е</strong>н<strong>е</strong>нии им<strong>е</strong>ни<br />

м<strong>е</strong>тода, и ваши<br />

соображ<strong>е</strong>ния<br />

о причинах этого<br />

явл<strong>е</strong>ния.<br />

О<br />

Создадим новую точку входа. Добавьт<strong>е</strong> класс с им<strong>е</strong>н<strong>е</strong>м A n o th e rC la ss .e s. Для этого<br />

щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на им<strong>е</strong>ни файла в окн<strong>е</strong> Solution Explorer и выб<strong>е</strong>рит<strong>е</strong><br />

команду Add»Class... ИСР добавит в программу класс A n o th e rC la ss. Посл<strong>е</strong> этого<br />

код прим<strong>е</strong>т вид:<br />

u s in g System ;<br />

u s in g S y ste m .L in q ;<br />

u s in g S y s t e m .C o l le c t io n s .G e n e r i c ;<br />

u s in g S y s te m .T e x t;<br />

nam espace C o n ta c ts<br />

{<br />

c l a s s A n o th e r C la s s<br />

В файл были добавл<strong>е</strong>ны<br />

ч<strong>е</strong>тыр<strong>е</strong> стандартны<strong>е</strong> строчки<br />

с оп<strong>е</strong>ратором using.<br />

Этот класс тож<strong>е</strong> находится<br />

в пространств<strong>е</strong> им<strong>е</strong>н<br />

Contacts.<br />

}<br />

им<strong>е</strong>ни файла).<br />

основ<strong>е</strong><br />

Q Добавьт<strong>е</strong> в в<strong>е</strong>рхнюю часть строку u s i n g S y s t e m . W in d o w s. F o rm s;<br />

He забудьт<strong>е</strong>, что в конц<strong>е</strong> строки должна стоять точка с запятой!<br />

О<br />

Добавьт<strong>е</strong> этот м<strong>е</strong>тод к классу А поЬ Ь <strong>е</strong>гС Х авз, написав <strong>е</strong>го внутри фигурных скобок:<br />

Класс MessatjeBox<br />

принадл<strong>е</strong>жит<br />

пространству им<strong>е</strong>н<br />

System.Windows.<br />

Forms, поэтому<br />

на шаг<strong>е</strong> # 3 вы<br />

и добавили оп<strong>е</strong>ратор<br />

using. М<strong>е</strong>тод Show О<br />

явля<strong>е</strong>тся частью<br />

класса MessageBox.<br />

c l a s s A n o th e rC la ss<br />

{<br />

public s ta tic void MainO<br />

{<br />

M essageB ox. Show( "Fowl" ) 7<br />

}<br />

86 глава 2


это вс<strong>е</strong>го лишь код<br />

Ч т о )к<strong>е</strong> произошло?<br />

Т<strong>е</strong>п<strong>е</strong>рь вм<strong>е</strong>сто прилож<strong>е</strong>ния Contacts программа вызыва<strong>е</strong>т<br />

вот тако<strong>е</strong> окно диалога. П<strong>е</strong>р<strong>е</strong>опр<strong>е</strong>д<strong>е</strong>лив м<strong>е</strong>тод Main (),<br />

вы указали новую точ1су входа. Поэтому программа п<strong>е</strong>рвым<br />

д<strong>е</strong>лом выполня<strong>е</strong>т оп<strong>е</strong>ратор M essageBox.ShowO .<br />

Данный м<strong>е</strong>тод больш<strong>е</strong> нич<strong>е</strong>го н<strong>е</strong> сод<strong>е</strong>ржит, поэтому<br />

посл<strong>е</strong> щ<strong>е</strong>лчка на кнопк<strong>е</strong> ОК программа зав<strong>е</strong>ршит свою<br />

работу.<br />

о В<strong>е</strong>рнит<strong>е</strong> программу в исходно<strong>е</strong> состояни<strong>е</strong>.<br />

Подсказка: Д о с т а т о ч н о<br />

изм<strong>е</strong>шть^пару строк<br />

в двух файлах.<br />

_ |Jo3bM H в руку карандаш<br />

Опишит<strong>е</strong> назнач<strong>е</strong>ни<strong>е</strong> различных строк кода, как показано<br />

в прим<strong>е</strong>р<strong>е</strong>.<br />

u s in g System ;<br />

u s in g S y stem .L in q ;<br />

u s in g S y ste m .T e x t;<br />

u sIn g S ys tern. W indows. Form s;<br />

Оп<strong>е</strong>ратор. .«SIM<br />

........<br />

nam espace SomeNamespace<br />

{<br />

c l a s s M yClass<br />

p u b lic s t a t i c v o id D oSom eth ln g() {<br />

}<br />

M essageB ox.Show ("Зд<strong>е</strong>сь б у д <strong>е</strong>т сообщ <strong>е</strong>ни<strong>е</strong>");<br />

дальш<strong>е</strong> > 87


вр<strong>е</strong>мя получить отв<strong>е</strong>ты<br />

Какую роль играют фигурны<strong>е</strong><br />

скобки?<br />

О ? Скобки группируют оп<strong>е</strong>раторы<br />

в блоки и используются только попарно.<br />

Открывающ<strong>е</strong>й скобк<strong>е</strong> вс<strong>е</strong>гда должна соотв<strong>е</strong>тствовать<br />

закрывающая.<br />

Для выд<strong>е</strong>л<strong>е</strong>ния пары скобок достаточно<br />

щ<strong>е</strong>лкнуть на любой из них.<br />

Возьми в руку карандаш<br />

Часто<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

B olIpoC bi<br />

3 * Объяснит<strong>е</strong>, пожалуйста, <strong>е</strong>щ<strong>е</strong> раз,<br />

что тако<strong>е</strong> точка входа.<br />

С I Программа состоит из множ<strong>е</strong>ства<br />

оп<strong>е</strong>раторов, но они н<strong>е</strong> могут выполняться<br />

одновр<strong>е</strong>м<strong>е</strong>нно. Оп<strong>е</strong>раторы принадл<strong>е</strong>жат<br />

разным классам. Как ж<strong>е</strong> при запуск<strong>е</strong><br />

программы опр<strong>е</strong>д<strong>е</strong>лить, какой оп<strong>е</strong>ратор<br />

выполнять п<strong>е</strong>рвым?<br />

Компилятор просто н<strong>е</strong> буд<strong>е</strong>т работать при<br />

отсутствии м<strong>е</strong>тода M a in (), который и называ<strong>е</strong>тся<br />

точкой входа. П<strong>е</strong>рвый оп<strong>е</strong>ратор<br />

этого м<strong>е</strong>тода и буд<strong>е</strong>т выполняться самым<br />

п<strong>е</strong>рвым.<br />

Поч<strong>е</strong>му при запуск<strong>е</strong> программы<br />

в окн<strong>е</strong> Error List появля<strong>е</strong>тся сообщ<strong>е</strong>ни<strong>е</strong><br />

об ошибках? Я думал, что подобно<strong>е</strong><br />

возможно только при выполн<strong>е</strong>нии<br />

команды Build Solution.<br />

С I П<strong>е</strong>рво<strong>е</strong>, что происходит при запуск<strong>е</strong><br />

программы на выполн<strong>е</strong>ни<strong>е</strong>, это сохран<strong>е</strong>ни<strong>е</strong><br />

вс<strong>е</strong>х файлов в вид<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ния и попытка<br />

их компиляции. А при компиляции<br />

кода — н<strong>е</strong>важно, запуска<strong>е</strong>т<strong>е</strong> вы при этом<br />

программу или строит<strong>е</strong> <strong>е</strong><strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> — вс<strong>е</strong><br />

им<strong>е</strong>ющи<strong>е</strong>ся ошибки отображаются в окн<strong>е</strong><br />

Error List.<br />

f<br />

В т<strong>е</strong>кст<strong>е</strong> кода ошибки<br />

выд<strong>е</strong>ляются красным<br />

цв<strong>е</strong>том.<br />

Вот правильны<strong>е</strong> варианты отв<strong>е</strong>та на вопрос о строках.<br />

u s in g System ;<br />

u s in g S y stem .L in q ;<br />

u s in g S y ste m .T e x t;<br />

u s in g System .W indow s.Form s;<br />

О п<strong>е</strong>рат ор losing добавля<strong>е</strong>т<br />

в класс<br />

из Э р уги х<br />

прост ранст в иМ<strong>е</strong>и.<br />

nam espace SomeNamespace<br />

{<br />

c l a s s M yClass {<br />

Мы указыва<strong>е</strong>м, к какому<br />

классу принадл<strong>е</strong>жит<br />

этот фрагм<strong>е</strong>нт кода.<br />

p u b lic s t a t i c v o id D oSom eth inglT ”^<br />

M essageB ox.Show ("Зд<strong>е</strong>сь б у д <strong>е</strong>т собщ<strong>е</strong>ни<strong>е</strong>")<br />

Внутри этого<br />

класса находится<br />

м<strong>е</strong>тод DoSometking,<br />

вызывающий объ<strong>е</strong>кт<br />

MessageBox.<br />

Этот оп<strong>е</strong>ратор<br />

вТ<strong>е</strong>т окно с т <strong>е</strong>кст овы м<br />

сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

88 глава 2


это вс<strong>е</strong>го лишь код<br />

Опр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong> соотв<strong>е</strong>тстви<strong>е</strong> описаний и фрагм<strong>е</strong>нтов кода. (Н<strong>е</strong>которы<strong>е</strong><br />

из них вам н<strong>е</strong>знакомы, попробуйт<strong>е</strong> угадать их функцию!)<br />

partial class Forml<br />

this.BackColor = Color.DarkViolet;<br />

Зада<strong>е</strong>т свойства объ<strong>е</strong>кта label.<br />

// Цикл выполня<strong>е</strong>тся три раза<br />

Это вс<strong>е</strong>го лишь комм<strong>е</strong>нтарий, добавл<strong>е</strong>нный<br />

программистом, чтобы<br />

объяснить назнач<strong>е</strong>ни<strong>е</strong> кода т<strong>е</strong>м,<br />

кто буд<strong>е</strong>т читать <strong>е</strong>го программу.<br />

partial class Forml<br />

private void InitializeComponent(<br />

{<br />

Убира<strong>е</strong>т кнопку сворачивания<br />

окна (^S ) окна F o r m l из строки<br />

заголовка.<br />

number_of_pit_stopsLabel.Name<br />

= "nuraber_of_pit_stopsLabel";<br />

number_of_pit_stopsLabel.Size<br />

= new System.Drawing.Size(135, 17)<br />

number_of_pit_stopsLabel.Text<br />

= "Number of pit stops:";<br />

Подсказки сист<strong>е</strong>мы, объясняющи<strong>е</strong><br />

назнач<strong>е</strong>ни<strong>е</strong> различных блоков<br />

кода.<br />

III <br />

III При щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> появля<strong>е</strong>тся<br />

III графич<strong>е</strong>ский фрагм<strong>е</strong>нт Rover<br />

III <br />

М<strong>е</strong>ня<strong>е</strong>т фоновый цв<strong>е</strong>т окна F o rm l.<br />

partial class Forml<br />

this.MaximizeBox = false;<br />

Блок кода, выполня<strong>е</strong>мый при открытии<br />

программой окна F o rm l.<br />

дальш<strong>е</strong> ► 89


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

КТ9 И H W A E A aI t ?<br />

Вот правильны<strong>е</strong> отв<strong>е</strong>ты на вопрос о назнач<strong>е</strong>нии различных блоков<br />

кода. Сравнит<strong>е</strong> со своими вариантами!<br />

partial class Forml<br />

this.BackColor = Color.DarkViolet;<br />

Зада<strong>е</strong>т свойства объ<strong>е</strong>кта label.<br />

// Цикл выполня<strong>е</strong>тся три раза<br />

Это вс<strong>е</strong>го лишь комм<strong>е</strong>нтарий, добавл<strong>е</strong>нный<br />

программистом, чтобы<br />

объяснить назнач<strong>е</strong>ни<strong>е</strong> кода т<strong>е</strong>м,<br />

кто буд<strong>е</strong>т читать <strong>е</strong>го программу.<br />

partial class Forml<br />

{<br />

private void InitializeComponentO<br />

(<br />

Убира<strong>е</strong>т кнопку сворачивания<br />

окна ( ) окна Forml из строки заголовка.<br />

number_of_pit_stopsLabel.Name<br />

= "number_of_pit_stopsLabel";<br />

number_of_pit_stopsLabel.Size<br />

= new System.Drawing.Size (135, 17)<br />

number_of_pit_stopsLabel.Text<br />

= "Number of pit stops:";<br />

■Подсказки сист<strong>е</strong>мы, объясняюш:и<strong>е</strong><br />

назнач<strong>е</strong>ни<strong>е</strong> различных блоков<br />

кода.<br />

III <br />

III При щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> появля<strong>е</strong>тся<br />

III графич<strong>е</strong>ский фрагм<strong>е</strong>нт Rover<br />

III <br />

М<strong>е</strong>ня<strong>е</strong>т фоновый цв<strong>е</strong>т окна Forml.<br />

partial class Forml<br />

{<br />

this.MaximizeBox = false;<br />

Блок кода, выполня<strong>е</strong>мый при открытии<br />

программой окна Forml.<br />

90 глава 2


Классы м огут принадл<strong>е</strong>)кать одному<br />

пространству им<strong>е</strong>н<br />

Рассмотрим два файла с классами из программы<br />

P e t F i l e r 2 (Домашний любим<strong>е</strong>ц) В них сод<strong>е</strong>ржатся<br />

три класса: D og (Собака), C a t (Кошка)<br />

и F i s h (Рыбка). Так как вс<strong>е</strong> они принадл<strong>е</strong>жат<br />

пространству им<strong>е</strong>н P e t F i l e r 2 , оп<strong>е</strong>раторы в<br />

м<strong>е</strong>тод<strong>е</strong> D o g . B a r k () (Собака ла<strong>е</strong>т) могут вызывать<br />

оп<strong>е</strong>раторы C a t . Meow ( ) (Кошка мяука<strong>е</strong>т)<br />

и F i s h . Sw im О (Рыбка плава<strong>е</strong>т). Распр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong><br />

различных им<strong>е</strong>н пространств и классов по<br />

файлам н<strong>е</strong> влия<strong>е</strong>т на д<strong>е</strong>йствия, выполня<strong>е</strong>мы<strong>е</strong>/<br />

посл<strong>е</strong> запуска.<br />

Som eClasses.cs<br />

namespace PetFiler2 {<br />

class Dog {<br />

это вс<strong>е</strong>го лишь код<br />

pviblic void BarkO {<br />

// Зд<strong>е</strong>сь оп<strong>е</strong>раторы<br />

}<br />

class Cat {<br />

M oreClasses.cs<br />

public void MeowO {<br />

Классы из одного пространства<br />

им<strong>е</strong>н Могут «вид<strong>е</strong>ть» друг друга,<br />

даж<strong>е</strong> находясь 8 разных файлах.<br />

А<br />

Д л я пом<strong>е</strong>щ<strong>е</strong>ния класса в разны<strong>е</strong><br />

файлы используйт<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong> слово<br />

partial. Им<strong>е</strong>нно <strong>е</strong>го использу<strong>е</strong>т<br />

ИСР, создавая файлы Forml.cs<br />

и Forml.Pesigner.cs.<br />

дальш<strong>е</strong> ¥ 91


парам<strong>е</strong>тры могут варьироват ься<br />

Ч т о тако<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

Вс<strong>е</strong> программы работают с данными. Данны<strong>е</strong> могут быть пр<strong>е</strong>дставл<strong>е</strong>ны<br />

в вид<strong>е</strong> докум<strong>е</strong>нта, графич<strong>е</strong>ского фрагм<strong>е</strong>нта, вид<strong>е</strong>оигры<br />

или мгнов<strong>е</strong>нного сообщ<strong>е</strong>ния. Для их хран<strong>е</strong>ния программа<br />

использу<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

Объявл<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

О бъявить (declare) п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную, значит, указать программ<strong>е</strong><br />

тип и <strong>е</strong><strong>е</strong> имя. Благодаря указанию типов н<strong>е</strong>возможно скомпилировать<br />

программы в случа<strong>е</strong>, <strong>е</strong>сли вы сд<strong>е</strong>лали ошибку и пыта<strong>е</strong>т<strong>е</strong>сь<br />

сд<strong>е</strong>лать н<strong>е</strong>что, лиш<strong>е</strong>нно<strong>е</strong> смысла, наприм<strong>е</strong>р выч<strong>е</strong>сть Fido<br />

из 48353.<br />

Э1ЛЛ0<br />

Эило<br />

C ^ i n t m a x W e i g h t ; ^ \ \<br />

s t r i n g m e s s a g e<br />

j<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нно.<br />

)уд ы и<strong>е</strong><br />

I<br />

о а о а о р 'о ж н ы !<br />

Зна<strong>е</strong>т<strong>е</strong> ли вы други<strong>е</strong> язы ки<br />

програм м ирования?<br />

Если да, то вам, скор<strong>е</strong><strong>е</strong><br />

вс<strong>е</strong>го, уж<strong>е</strong> изв<strong>е</strong>стна большая<br />

часть этого мат<strong>е</strong>риала. Но<br />

выполнить упражн<strong>е</strong>ния вс<strong>е</strong><br />

равно им<strong>е</strong><strong>е</strong>т смысл, так как<br />

н<strong>е</strong> исключ<strong>е</strong>но, что С# ч<strong>е</strong>м-то<br />

отлича<strong>е</strong>тся от изв<strong>е</strong>стных<br />

вам языков.<br />

b o o l<br />

b o x C h e c k e d r<br />

могут храниться.<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>няю тся<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ннь1Х.<br />

В проц<strong>е</strong>сс<strong>е</strong> работы программы любой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной мож<strong>е</strong>т быть<br />

присво<strong>е</strong>но произвольно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. То <strong>е</strong>сть знач<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

м<strong>е</strong>няются. Это ключ<strong>е</strong>вая ид<strong>е</strong>я любой программы. К прим<strong>е</strong>ру,<br />

<strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной m yHeight было присво<strong>е</strong>но знач<strong>е</strong>ни<strong>е</strong> 63:<br />

i n t m yH eight = 63;<br />

как только имя m y H e ig h t появится в код<strong>е</strong>, <strong>C#</strong> зам<strong>е</strong>нит <strong>е</strong>го знач<strong>е</strong>ни<strong>е</strong>м<br />

63. Пр<strong>е</strong>дставим, что поздн<strong>е</strong><strong>е</strong> <strong>е</strong>му было присво<strong>е</strong>но знач<strong>е</strong>ни<strong>е</strong><br />

12:<br />

m yH eight = 12;<br />

Т<strong>е</strong>п<strong>е</strong>рь <strong>C#</strong> буд<strong>е</strong>т зам<strong>е</strong>нять парам<strong>е</strong>тр m yHeight на число 12, н<strong>е</strong>смотря<br />

на то что имя п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной н<strong>е</strong> изм<strong>е</strong>нилось.<br />

Для работы<br />

с числами, т<strong>е</strong>кстом,<br />

бул<strong>е</strong>выми<br />

знач<strong>е</strong>ниями<br />

и любым другим<br />

видом данных<br />

используйт<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

92 глава 2


это вс<strong>е</strong>го лишь код<br />

Присво<strong>е</strong>ни<strong>е</strong> знач<strong>е</strong>ний<br />

Пом<strong>е</strong>стит<strong>е</strong> в программу эти оп<strong>е</strong>раторы:<br />

int Z ;<br />

M e ssa g eB o x .Show ("Отв<strong>е</strong>т " + z ) ;<br />

При попытк<strong>е</strong> запустить программу, ИСР откаж<strong>е</strong>тся<br />

компилировать код. Компилятор пров<strong>е</strong>рил ваши<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> и обнаружил, что им н<strong>е</strong> присво<strong>е</strong>но никакого<br />

знач<strong>е</strong>ния. Чтобы изб<strong>е</strong>жать подобных ошибок, „<br />

- < Присво<strong>е</strong>нны<strong>е</strong><br />

им<strong>е</strong><strong>е</strong>т смысл комбинировать оп<strong>е</strong>ратор объявл<strong>е</strong>ния<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной с оп<strong>е</strong>ратором присво<strong>е</strong>ния знач<strong>е</strong>ния:<br />

xWeight<br />

message<br />

bxChecked<br />

знач<strong>е</strong>ния.<br />

ß объявл<strong>е</strong>нии п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, как<br />

и раньш<strong>е</strong>, указыва<strong>е</strong>тся <strong>е</strong><strong>е</strong> тип.<br />

Отсутстви<strong>е</strong> у п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

знач<strong>е</strong>ния<br />

явля<strong>е</strong>тся пр<strong>е</strong>пятстви<strong>е</strong>м<br />

для компиляции.<br />

Этой ошибки<br />

л<strong>е</strong>гко изб<strong>е</strong>жать,<br />

объ<strong>е</strong>динив в один<br />

оп<strong>е</strong>ратор объявл<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

и присво<strong>е</strong>ни<strong>е</strong> <strong>е</strong>й<br />

знач<strong>е</strong>ния.<br />

Н<strong>е</strong>которы<strong>е</strong> типы п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

Тип п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т, каки<strong>е</strong> им<strong>е</strong>нно данны<strong>е</strong> в н<strong>е</strong>й можно хранить.<br />

Подробно типы будут рассматриваться в глав<strong>е</strong> 4, а пока запомнит<strong>е</strong><br />

три наибол<strong>е</strong><strong>е</strong> использу<strong>е</strong>мых типа. П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> типа i n t сохраняют<br />

ц<strong>е</strong>лы<strong>е</strong> числа, п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> типа s t r i n g —т<strong>е</strong>кст, а п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

типа b o o l —логич<strong>е</strong>ски<strong>е</strong> знач<strong>е</strong>ния true/false.<br />

в<strong>е</strong>рш <strong>е</strong>нной<br />

^ом<strong>е</strong>нят<strong>е</strong>.<br />

п<strong>е</strong>-р<strong>е</strong>-м<strong>е</strong>н-ный, пррш.<br />

ум<strong>е</strong>ющий м<strong>е</strong>няться или приспосабливаться.<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная скорость др<strong>е</strong>ли позволя<strong>е</strong>т Бобу св<strong>е</strong>рлить<br />

то быстро, то м<strong>е</strong>дл<strong>е</strong>нно, в зависимости от<br />

т<strong>е</strong>кущих задач.<br />

дальш<strong>е</strong> > 93


оп<strong>е</strong>раторы наготов<strong>е</strong><br />

Знакомы<strong>е</strong> мат<strong>е</strong>матич<strong>е</strong>ски<strong>е</strong> симболы<br />

Числа, хранящи<strong>е</strong>ся в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных можно складывать, вычитать,<br />

умножать и д<strong>е</strong>лить. В этом вам помогут о п <strong>е</strong>р а т о р ы<br />

(o p era to rs). Часть из них вам уж<strong>е</strong> знакома. Рассмотрим код,<br />

р<strong>е</strong>шающий н<strong>е</strong>сложную мат<strong>е</strong>матич<strong>е</strong>скую задачку:<br />

Мі?і об-ьябилы п<strong>е</strong>р<strong>е</strong><br />

М б н к у ю n u m b e r<br />

ц<strong>е</strong>лочисл<strong>е</strong>нного<br />

U присбои<br />

ли <strong>е</strong>й знйч<strong>е</strong>нм<strong>е</strong><br />

з а т <strong>е</strong> м .puö^6«A«<br />

m 6 р<strong>е</strong>зулі^тат<strong>е</strong><br />

ч<strong>е</strong>го ока іА,олучилй<br />

зняч<strong>е</strong>нм<strong>е</strong> Я-?-<br />

Оп<strong>е</strong>ратор *=<br />

означа<strong>е</strong>т, что<br />

вы должны ум ножить<br />

т<strong>е</strong>кущ<strong>е</strong><strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

на 3^ в итог<strong>е</strong><br />

получа<strong>е</strong>м 48.<br />

Класс MessageBox<br />

вызыва<strong>е</strong>т окно<br />

с т<strong>е</strong>кстом «hello<br />

again kello».<br />

int number =<br />

nvunber = number<br />

number = 36<br />

number = 12 -<br />

number += 10;<br />

number *= 3;<br />

Д ля програм м иста слово string<br />

почти вс<strong>е</strong>гда означа<strong>е</strong>т «строка<br />

т<strong>е</strong>кста», а сокращ <strong>е</strong>ни<strong>е</strong> int указы ­<br />

ва<strong>е</strong>т на ц<strong>е</strong>ло<strong>е</strong> число.<br />

Тр<strong>е</strong>тий оп<strong>е</strong>ратор присваива<strong>е</strong>т<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной number знач<strong>е</strong>ни<strong>е</strong><br />

36 * 1 S = S40. Сл<strong>е</strong>дующий<br />

оп<strong>е</strong>ратор присваива<strong>е</strong>т ново<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> 12. - (42. / 7) = 6.<br />

О п<strong>е</strong>ратор « : S ^ I m b e r<br />

к знач<strong>е</strong>нию п<strong>е</strong>р<strong>е</strong>м<br />

вы получит<strong>е</strong> %■&>■<br />

г » « “ «<br />

number = 71 / 3;<br />

л Если71 разд<strong>е</strong>лить на 3 получится 23.666666...<br />

\ __ _ МОр<strong>е</strong>зульт ат д<strong>е</strong>л<strong>е</strong>ния ц<strong>е</strong>лых чис<strong>е</strong>л такж<strong>е</strong> долж<strong>е</strong>н<br />

быть ц<strong>е</strong>лым, поэтому 23.666... округля<strong>е</strong>тся до 23.<br />

int count =<br />

count ++;<br />

count --;<br />

String result = "hello";<br />

MessageBox.Show(result);<br />

Пусты<strong>е</strong> кавычки<br />

обозначают строку. result = "the value is:<br />

н<strong>е</strong> сод<strong>е</strong>ржащун:><br />

символов. result =<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> типа<br />

bool принимают<br />

знач<strong>е</strong>ния true или<br />

false. Оп<strong>е</strong>ратор !<br />

обознача<strong>е</strong>т отрицани<strong>е</strong><br />

и м<strong>е</strong>ня<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

с true на false<br />

и обратно.<br />

94 глава 2<br />

Ц<strong>е</strong>лочисл<strong>е</strong>нны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> используются в сч<strong>е</strong>тчик<strong>е</strong><br />

в соч<strong>е</strong>тании с оп<strong>е</strong>раторами +-+ и Инкр<strong>е</strong>м<strong>е</strong>нт ++ув<strong>е</strong>личива<strong>е</strong>т<br />

знач<strong>е</strong>ния на<br />

а д<strong>е</strong>кр<strong>е</strong>м<strong>е</strong>нт — ум<strong>е</strong>ньш а<strong>е</strong>т на 1.<br />

result += " again " + result;<br />

bool yesNo = false;<br />

bool anotherBool = true;<br />

y e ^ o = !anotherBool;<br />

+ count;<br />

О<br />

Оп<strong>е</strong>ратор + в данном<br />

случа<strong>е</strong> со<strong>е</strong>диня<strong>е</strong>т вм<strong>е</strong>ст<strong>е</strong><br />

дв<strong>е</strong> строки. При этом<br />

числа автоматич<strong>е</strong>ски<br />

пр<strong>е</strong>образовываются<br />

к типу string.<br />

Н <strong>е</strong> в о л н у й т <strong>е</strong>сь , <strong>е</strong>сл и в ы н <strong>е</strong> см огл и<br />

за п о м н и ть в сё.<br />

Эта информация буд<strong>е</strong>т часто повторяться<br />

в книг<strong>е</strong>.


это вс<strong>е</strong>го лишь код<br />

Наблюд<strong>е</strong>ни<strong>е</strong> за п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными 6 проц<strong>е</strong>сс<strong>е</strong> отладки<br />

Отладчик позволя<strong>е</strong>т понять, как работа<strong>е</strong>т программа. Рассмотрим код<br />

с пр<strong>е</strong>дыдущ<strong>е</strong>й страницы.<br />

О<br />

Новый про<strong>е</strong>кт Windows Forms Application<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> на форму кнопку и щ<strong>е</strong>лкнит<strong>е</strong> на н<strong>е</strong>й два раза. Вв<strong>е</strong>дит<strong>е</strong> код с пр<strong>е</strong>дыдущ<strong>е</strong>й<br />

страницы.<br />

Forrrd.cs<br />

’^Chepter_2_Code.Formi<br />

»I ‘jg^byttonXsender, Еу<strong>е</strong>пЫг^ ej<br />

■ p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e )<br />

{<br />

I / / H e r e ’ s a g r e a t w a y t o u sif t h e ID E t o s e e how t h i s c o d e ¥ io r k s l<br />

I<br />

U<br />

\ / / F i r s t , c r e a t e a new p r o j e c t i n t h e lO E a d d a b u t t o n . I 4 e x t , d o u b l e - c l i c k o n t h e<br />

! / / b u t t o n 5 0 t h e lO E a d d s a b u t t o n l _ C l i c k s ^ t h o d t o y o u r p ro g ra m *. F i l l i n t h a t<br />

I / / ise th o d w ith a i l o f t h e c o d e , s t a r t i n g w ith " i n t n u m ber = 1 5 ; " .<br />

i //<br />

: / / p u t a b r e a k p o i n t o n t h e f i r s t l i n e b y r i g h t - c i i c k i n g o n i t an d c h o o s i n g<br />

; / / " B r e a k p o i n t » I n s e r t B r e a k p o i n t " . T h e l i n e s h o u ld t u r n r e d ,<br />

//<br />

/ / № e x tj s t a r t d e b u g g i n g y o u r p r o g r a * a . Y o u ' l l s e e i t b r e a k o n t h e l i n e w h e re y o u<br />

/ / i n s e r t e d t h e b r e a k p o i n t . Y o u r p r o g r a m ’ s j u s t p a u s e d t I f y o u c l i c k t h e Run<br />

/ / t o o l b a r b u t t o n ( o r h i t F 5 ) j i t 4 # i il c o n t i n u e . R i g h t - c l i c k o n " n u r e b e r " an d<br />

/ / c h o o s e ''E x p r e s s i o n : ’ n u fs b e r ' » Add i^ a t c h " frcffli t h e ise n u - T h e b o tto r e p a n e l i n<br />

/ / t h e lO E s h o u ld c h a n g e t o t h e W a tc h e s w indow ^ a n d t h e r e s h o u ld b e a l i n e i n t h a t<br />

/ / w in d ot« f o r "fiu fiib e r” . S t e p t h r o u g h t h e p r o g r a is l i n e b y l i n e u s i n g S t e p O v e r ( F I ® )<br />

/ / You c a n s e e t h e v a l u e o f t h e ’’ n u m b er’' v a r i a b l e c h a n g e e s y o u g o !<br />

//<br />

/ / Do t h e sam e f o r t h e c o u n t , r e s u l t , y e s f t o , an d a n o t h e r B o o l v a r i a b l e s .<br />

n u isb er » nufflber -f 1@;<br />

n u m ber = 3 6 * I S ;<br />

n u m ber = 1 2 - ( 4 2 / 7 > ;<br />

n u m ber + = l@ j<br />

n u m ber * = 3 i<br />

n u m ber =71/3;<br />

i n t c o u n t »<br />

c o u n t + + ;<br />

c o u n t - - ;<br />

s t r i n g r e s u l t = " h e l l o ” ;<br />

r e s u l t + * " a g a i n ” + r e s u l t ;<br />

H e s s a g e B o K ,S h o w ( r e s u l t ) ;<br />

< : r<br />

r e s u l t * ” t h e v a l u e i i s j “ + c o u n t ;<br />

r e s u l t =<br />

Достигнув точки останови<br />

программа п р <strong>е</strong> к ^ а щ Т <strong>е</strong> Т ^<br />

w e S m » “<br />

D X<br />

ИСР откро<strong>е</strong>т<br />

новый про<strong>е</strong>кт<br />

с пустой формой<br />

и точкой входа.<br />

Вы мож<strong>е</strong>т<strong>е</strong> дать<br />

<strong>е</strong>му любо<strong>е</strong> имя.<br />

Комм<strong>е</strong>нтарии<br />

выд<strong>е</strong>ляются<br />

з<strong>е</strong>л<strong>е</strong>ным<br />

цв<strong>е</strong>том<br />

и могут<br />

сод<strong>е</strong>ржать<br />

любой т<strong>е</strong>кст,<br />

компилятор<br />

их н<strong>е</strong> зам<strong>е</strong>ча<strong>е</strong>т.<br />

}<br />

lioo%~<br />

b o o l y e s H o = f a l s e ;<br />

b o o l a n o t h e r B o o l =» t r u e ;<br />

y e s fto = t a n o t h e r B o o l ;<br />

О<br />

Вставка точки останова в п<strong>е</strong>рвую строчку кода<br />

Щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на строк<strong>е</strong> ( i n t number = 15;) и выб<strong>е</strong>рит<strong>е</strong> команду Insert<br />

Breakpoint из м<strong>е</strong>ню Breakpoint. (Можно воспользоваться Toggle Breakpoint из м<strong>е</strong>ню Debug или<br />

нажать клавишу F9.) .<br />

------------------- ► Ц<strong>е</strong>р<strong>е</strong>В<strong>е</strong>рниш<strong>е</strong> страницу и проДоЛжим!


пр<strong>е</strong>кратим ошибки!<br />

О<br />

О тладка программы<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Start Debugging (или нажмит<strong>е</strong> клавишу F5) (Можно использовать команду<br />

Start Debugging, м<strong>е</strong>ню Debug.) Программа начн<strong>е</strong>т работу и откро<strong>е</strong>т форму.<br />

П <strong>е</strong> р <strong>е</strong>ход к точк<strong>е</strong> останова<br />

Как только программа дойд<strong>е</strong>т до точки останова, ИСР автоматич<strong>е</strong>ски вызов<strong>е</strong>т р<strong>е</strong>дактор кода<br />

и выд<strong>е</strong>лит нужную строчку ж<strong>е</strong>лтым цв<strong>е</strong>том.<br />

О<br />

in t пияЬ<strong>е</strong>г « I5j<br />

num ber = numiaer + 10j<br />

number = 36 * I S ;<br />

; num ber = 12 - (4 2 / 7 )<br />

: number + = l e j<br />

num ber * = 3;<br />

: num ber = 7 1 / 3j<br />

В проц<strong>е</strong>сс<strong>е</strong> отладки<br />

достаточно нав<strong>е</strong>сти на<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную указат<strong>е</strong>ль<br />

мыши,, чтобы появилось<br />

всплывающ<strong>е</strong><strong>е</strong> окно<br />

со знач<strong>е</strong>ни<strong>е</strong>м этой<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной.<br />

Контрольно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной number<br />

Щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной number и выб<strong>е</strong>рит<strong>е</strong><br />

в появивш<strong>е</strong>мся м<strong>е</strong>ню команду Expression: ‘number’ » Add<br />

Watch. Внизу экрана появится окно Watch:<br />

Watch<br />

1М ат<strong>е</strong> j Velue jType<br />

Ц ••• ядЛ<strong>е</strong>г , :0 ■" ,, /<br />

і<br />

_1<br />

_______________[^iWatchJ<br />

....... ■■r ..........<br />

П x |<br />

О бход кода<br />

Нажмит<strong>е</strong> F10, чтобы обойти эту строку. (Можно такж<strong>е</strong> выбрать в<br />

м<strong>е</strong>ню Debug команду Step Over или щ<strong>е</strong>лкнуть на кнопк<strong>е</strong> Step Over<br />

пан<strong>е</strong>ли инструм<strong>е</strong>нтов Debug.) Выд<strong>е</strong>л<strong>е</strong>нная строка буд<strong>е</strong>т выполн<strong>е</strong>на,<br />

и знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной number стан<strong>е</strong>т равным 15. Т<strong>е</strong>п<strong>е</strong>рь ж<strong>е</strong>лтым<br />

буд<strong>е</strong>т выд<strong>е</strong>л<strong>е</strong>на сл<strong>е</strong>дующая строка кода.<br />

Присво<strong>е</strong>нно<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

знач<strong>е</strong>ни<strong>е</strong> т ут<br />

ж<strong>е</strong> появилось<br />

в окн<strong>е</strong> Watch.<br />

П род олж <strong>е</strong>н и <strong>е</strong> роботы прогроАлмы<br />

Для возвращ<strong>е</strong>ния в обычный р<strong>е</strong>жим выполн<strong>е</strong>ния программы нажмит<strong>е</strong><br />

F5 или выб<strong>е</strong>рит<strong>е</strong> в м<strong>е</strong>ню Debug команду Continue.<br />

I<br />

/<br />

Функция Watch<br />

помога<strong>е</strong>т отсл<strong>е</strong>живать<br />

знач<strong>е</strong>ния<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

на каждом этап<strong>е</strong><br />

выполн<strong>е</strong>ния<br />

кода. Вы оц<strong>е</strong>нит<strong>е</strong><br />

<strong>е</strong><strong>е</strong> удобство<br />

но м<strong>е</strong>р<strong>е</strong> усложн<strong>е</strong>ния<br />

ваших<br />

программ.<br />

96 глава 2


это вс<strong>е</strong>го лишь код<br />

Циклы<br />

в большинств<strong>е</strong> сложных программ одни и т<strong>е</strong> ж<strong>е</strong> д<strong>е</strong>йствия повторяются<br />

больш<strong>е</strong> одного раза. В такой ситуации на помощь приходят<br />

циклы (loops) —они заставляют программу выполнять набор<br />

оп<strong>е</strong>раторов, до т<strong>е</strong>х пор пока указанно<strong>е</strong> вами услови<strong>е</strong> н<strong>е</strong> прим<strong>е</strong>т<br />

знач<strong>е</strong>ниёС^^<strong>е</strong> (или false])).<br />

Вот поч<strong>е</strong>му іл'як бйжны<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> логич<strong>е</strong>ского<br />

типа.<br />

СОБЕТ^<br />

Наличи<strong>е</strong> н<strong>е</strong>парных скобок, явля<strong>е</strong>тся<br />

пр<strong>е</strong>пятстви<strong>е</strong>м к постро<strong>е</strong>нию<br />

программы. К счастью, достаточно<br />

нав<strong>е</strong>сти указат<strong>е</strong>ль мыши на скобку,<br />

и ИСР тут ж<strong>е</strong> выд<strong>е</strong>лит <strong>е</strong><strong>е</strong> «вторую<br />

половину»:<br />

bool test^<br />

w h ile == t r u e )<br />

{<br />

/ / C o n ten ts o f t h e lo o p<br />

8 цикл<strong>е</strong> while оп<strong>е</strong>раторы<br />

внутри фигурных скобок<br />

выполняются до т<strong>е</strong>х<br />

пор. пока услови<strong>е</strong> им<strong>е</strong><strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> true.<br />

Цикл for состоит из тр<strong>е</strong>х оп<strong>е</strong>раторов. П<strong>е</strong>рвый зада<strong>е</strong>т<br />

начало цикла. Тр<strong>е</strong>тий оп<strong>е</strong>ратор цикла буд<strong>е</strong>т выполняться,<br />

пока соблюда<strong>е</strong>тся услови<strong>е</strong>, заданно<strong>е</strong> вторым оп<strong>е</strong>ратором.<br />

for (int i=0;i


приготовились, настроились, кодиру<strong>е</strong>м!<br />

П<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>м к практик<strong>е</strong><br />

Работа программы опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся оп<strong>е</strong>раторами. Но<br />

оп<strong>е</strong>раторы сущ<strong>е</strong>ствуют н<strong>е</strong> в вакуум<strong>е</strong>. Впроч<strong>е</strong>м, прощ<strong>е</strong><br />

вс<strong>е</strong>го это понять на прим<strong>е</strong>р<strong>е</strong>. Создайт<strong>е</strong> про<strong>е</strong>кт<br />

Windows Forms Application.<br />

н<br />

<strong>е</strong>С К оЛ ьК о СоБ<strong>е</strong>хооБ<br />

★ Н<strong>е</strong> забывайт<strong>е</strong>, что в конц<strong>е</strong> оп<strong>е</strong>ратора<br />

должна стоять точка с запятой:<br />

name = " J o e" ;<br />

★ За двумя косыми ч<strong>е</strong>ртами идут<br />

комм<strong>е</strong>нтарии:<br />

/ / э т о т т <strong>е</strong>к ст игнори ру<strong>е</strong>тся<br />

★ Объявляя п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную, укажит<strong>е</strong> <strong>е</strong><strong>е</strong><br />

имя и ти п (типы будут подробно<br />

рассматриваться в глав<strong>е</strong> 4):<br />

i n t w e ig h t;<br />

/ / w e ig h t — ц <strong>е</strong>л о <strong>е</strong> число<br />

★ Код для классов и м<strong>е</strong>тодов заключа<strong>е</strong>тся<br />

в фигурны<strong>е</strong> скобки:<br />

p u b l i c v o id Go О {<br />

/ / зд <strong>е</strong> с ь ваш код<br />

}<br />

★ В большинств<strong>е</strong> случа<strong>е</strong>в колич<strong>е</strong>ство<br />

проб<strong>е</strong>лов н<strong>е</strong> им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ния:<br />

Оп<strong>е</strong>ратор, Выводящий сооби^<strong>е</strong>ни<strong>е</strong><br />

Дважды щ<strong>е</strong>лкнит<strong>е</strong> на п<strong>е</strong>рвой кнопк<strong>е</strong> и добавьт<strong>е</strong><br />

к м<strong>е</strong>тоду b u tto n l_ C lic k () эти оп<strong>е</strong>раторы.<br />

Внимат<strong>е</strong>льно изучит<strong>е</strong> код и р<strong>е</strong>зультат <strong>е</strong>го выполн<strong>е</strong>ния.<br />

i n t j = 1234 ;<br />

это то ж<strong>е</strong> само<strong>е</strong>, что и:<br />

i n t j = 1234;<br />

. э т о п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н а я , in t<br />

м <strong>е</strong> л о <strong>е</strong> и м <strong>е</strong> л о , остальная<br />

часть оп<strong>е</strong>ратора ^<br />

Присваива<strong>е</strong>т п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й<br />

з н а м <strong>е</strong> н и <strong>е</strong> 3 .<br />

n a m e is Q u e n tin<br />

x is 5 1<br />

d is l.5 7 0 7 » 3 2 6 7 9 4 9<br />

I<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

/ / эт о комм<strong>е</strong>нтарий<br />

s t r i n g name = " Q u en tin " ;<br />

i n t X ^ 3 ;<br />

X = X * 17;<br />

d o u b le d = M ath.P I / 2;<br />

M essageB ox.Show ("nam e i s<br />

+ " \n x i s " + X<br />

+ " \n d i s " + d ) ;<br />

О Л <strong>е</strong> к т PI относится<br />

Math из пространства<br />

^м<strong>е</strong>н System, поэтами<br />

должнТ''<br />

usm gsystem .<br />

OK<br />

^ х ~ о<br />

1^осл<strong>е</strong>доват<strong>е</strong>льность,<br />

добавляющая в окно сообщ<strong>е</strong>ния символ<br />

п<strong>е</strong>р<strong>е</strong>носа строки.<br />

98 глава 2


это вс<strong>е</strong>го лишь иод<br />

О п<strong>е</strong>раторы if/else инициируют д<strong>е</strong>йствия при выполн<strong>е</strong>нии или<br />

н<strong>е</strong>выполн<strong>е</strong>нии заданных условий. В большинств<strong>е</strong> случа<strong>е</strong>в р<strong>е</strong>чь<br />

ид<strong>е</strong>т о пров<strong>е</strong>рк<strong>е</strong> рав<strong>е</strong>нства. Для этого использу<strong>е</strong>тся оп<strong>е</strong>ратор ==.<br />

Н<strong>е</strong> путайт<strong>е</strong> <strong>е</strong>го с оп<strong>е</strong>ратором (=), который присваива<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нным<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

if (someValue == 24)<br />

{<br />

Л<br />

о п <strong>е</strong>р ато р -Т<br />

с пров<strong>е</strong>рки условия.<br />

Me ss ag eBo x.S h o w("Знач<strong>е</strong>ни<strong>е</strong> 24 .");<br />

> д л я с р а в н <strong>е</strong> н и я аввх » « S e ®<br />

исш А И и<strong>е</strong>т<strong>е</strong>я о«<strong>е</strong>р«~ор «<br />

з н » « р « в <strong>е</strong> н <strong>е</strong> т 6 « ^<br />

О „<strong>е</strong>ра«ор в ф м аР "»"<br />

. сковах выполня<strong>е</strong>тся<br />

со1ли>д‘ ш и<br />

условия.<br />

Если заданно<strong>е</strong><br />

услови<strong>е</strong> соблюд<strong>е</strong>но,<br />

// Колич<strong>е</strong>ство оп<strong>е</strong>раторов в скобках<br />

// мож<strong>е</strong>т быть произвольным<br />

MessageBox.Show("Знач<strong>е</strong>ни<strong>е</strong> 24.");<br />

Выполня<strong>е</strong>тся т г<br />

п<strong>е</strong>рвый оп<strong>е</strong>ратор, / exse<br />

в противном<br />

случа<strong>е</strong> — второй. — 2^ Me ss ag eBo x.S h o w ("Знач<strong>е</strong>ни<strong>е</strong> отлично от 24.");<br />

f i<br />

р у д ы н <strong>е</strong><br />

I<br />

о с ш о | - 'о ^ jji,<br />

С л<strong>е</strong>дит<strong>е</strong> за колич<strong>е</strong>ством знаков рав<strong>е</strong>нства в оп<strong>е</strong>ратор<strong>е</strong>!<br />

Оп<strong>е</strong>ратор, состоящий из одного знака (=) присваива<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>знач<strong>е</strong>ни<strong>е</strong>,<br />

а из двух знаков (==) — сравнива<strong>е</strong>т дв<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

Эт о оч<strong>е</strong>нь распростран<strong>е</strong>нная ошибка. Если вы видит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong><br />

«н<strong>е</strong>возможно пр<strong>е</strong>образовать тип ‘int’ в тип ЪооГ», скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го, им<strong>е</strong>нно эта<br />

ошибка явля<strong>е</strong>тся <strong>е</strong>го причиной.<br />

дальш<strong>е</strong> > 99


то, что вы мож<strong>е</strong>т<strong>е</strong> сд<strong>е</strong>лать<br />

Проб<strong>е</strong>рЬ условий<br />

Рассмотрим работу условного оп<strong>е</strong>ратора i f /e ls e .<br />

Пров<strong>е</strong>рка при помои^и оп<strong>е</strong>раторов<br />

Вы уж<strong>е</strong> познакомились с оп<strong>е</strong>ратором ==, пров<strong>е</strong>ряющим, равны ли<br />

друг другу дв<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>. Сущ<strong>е</strong>ствуют и други<strong>е</strong> оп<strong>е</strong>раторы сравн<strong>е</strong>ния:<br />

★<br />

★<br />

Оп<strong>е</strong>ратор != в отличи<strong>е</strong> от оп<strong>е</strong>ратора == принима<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

true, <strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> н <strong>е</strong> р авн ы .<br />

Оп<strong>е</strong>раторы > и < выявляют, какая п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная больш<strong>е</strong>.<br />

Оп<strong>е</strong>раторы ==, ! = , > и < называются о п <strong>е</strong>р а т о р а м и ср а в н <strong>е</strong>­<br />

н и я. С их помощью осущ<strong>е</strong>ствля<strong>е</strong>тся п р о в <strong>е</strong> р к а у сл овий.<br />

Оп<strong>е</strong>раторы сравн<strong>е</strong>ния можно комбинировать при помощи<br />

оп<strong>е</strong>ратора && (И) и оп<strong>е</strong>ратора | | (ИЛИ). К прим<strong>е</strong>ру, услови<strong>е</strong><br />

i равно 3 или j м<strong>е</strong>ньш<strong>е</strong> 5 записыва<strong>е</strong>тся как ( i == 3) II<br />

(j < 5).<br />

Задани<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной и пров<strong>е</strong>рка <strong>е</strong><strong>е</strong> знач<strong>е</strong>ния<br />

Ниж<strong>е</strong> вы видит<strong>е</strong> код для второй кнопки. Он сод<strong>е</strong>ржит оп<strong>е</strong>ратор if /<br />

else, пров<strong>е</strong>ряющий, равна ли ц<strong>е</strong>лочисл<strong>е</strong>нная п <strong>е</strong>р <strong>е</strong>м <strong>е</strong> н н а я х д<strong>е</strong>сяти.<br />

Использовани<strong>е</strong><br />

условного оп<strong>е</strong>ра<br />

тора для сравн<strong>е</strong><br />

ния двух чис<strong>е</strong>л<br />

называ<strong>е</strong>тся пров<strong>е</strong>ркой<br />

условия.<br />

Для возвращ<strong>е</strong>ния в р<strong>е</strong>жим<br />

р<strong>е</strong>дактирования кода<br />

остановит<strong>е</strong> отладку<br />

программы. Это можно<br />

сд<strong>е</strong>лать при помощи<br />

команды Stop Debugging из<br />

м<strong>е</strong>ню Debug.<br />

Объявим<br />

!^р<strong>е</strong>м<strong>е</strong>нную<br />

XU присвоим<br />

<strong>е</strong>й знач<strong>е</strong>ни<strong>е</strong> s. }<br />

Зат<strong>е</strong>м пров<strong>е</strong>рим,<br />

равна {<br />

ли она 1о.<br />

p r i v a t e v o id b u t t o n 2 _ C lic k ( o b j e c t s e n d e r , E ven tA rgs e)<br />

{<br />

^ i n t X = 5;<br />

( i f (X == 10)<br />

'I<br />

M essa g eB o x .S h o w (" X m ust b e 1 0 " );<br />

}<br />

e l s e<br />

}<br />

M essa g eB o x .S h o w ( "X i s n ' t 1 0 " );<br />

Это р<strong>е</strong>зультат работы програм м ы . О тр<strong>е</strong>дактируйт<strong>е</strong> код таким<br />

образом, чтобы сообщ <strong>е</strong>ни<strong>е</strong> изм <strong>е</strong>нилось на х m ust be 10.<br />

100 глава 2


это вс<strong>е</strong>го лишь код<br />

Пров<strong>е</strong>рка <strong>е</strong>щ<strong>е</strong> одного условия<br />

Щ<strong>е</strong>лчок на тр<strong>е</strong>ть<strong>е</strong>й кнопк<strong>е</strong> долж<strong>е</strong>н приводить к появл<strong>е</strong>нию<br />

окна. Самостоят<strong>е</strong>льно отр<strong>е</strong>дактируйт<strong>е</strong> код, чтобы в окн<strong>е</strong> появлялся<br />

этот т<strong>е</strong>кст.<br />

В этой строк<strong>е</strong> пров<strong>е</strong>ря<strong>е</strong>тся,<br />

равна ли п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

someValue тр<strong>е</strong>м, и сод<strong>е</strong>ржит<br />

ли п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная пат<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> «Joe».<br />

p r i v a t e v o id b u t t o n 3 _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

i n t som eV alue = 4;<br />

s t r i n g name = "Bobbo J r .";<br />

i f ((so m eV a lu e == 3) && (name == "Joe"))<br />

{<br />

}<br />

M essa g eB o x .S h o w (" x i s 3 and t h e name i s J o e " );<br />

M essa g eB o x .S h o w ( " t h is l i n e ru n s no m a tte r w h a t" );<br />

Добавл<strong>е</strong>ни<strong>е</strong> цикла<br />

Ниж<strong>е</strong> показан код для посл<strong>е</strong>дн<strong>е</strong>й кнопки. Он сод<strong>е</strong>ржит два цикла. Цикл<br />

w h ile , который р<strong>е</strong>ализу<strong>е</strong>т оп<strong>е</strong>раторы в скобках, пока выпоня<strong>е</strong>тся заданно<strong>е</strong><br />

услови<strong>е</strong>. И цикл fo r. Посмотрим, как это работа<strong>е</strong>т.<br />

Цикл работа<strong>е</strong>т,<br />

пока знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

count м<strong>е</strong>ньш<strong>е</strong> 1 0 .<br />

p r i v a t e v o i d b u t t o n 4 _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

i n t c o u n t = о ;<br />

A w hile (c o u n t < 10)<br />

{<br />

c o u n t = c o u n t + 1;<br />

Это услови<strong>е</strong> пров<strong>е</strong>ря<strong>е</strong>тся<br />

п<strong>е</strong>р<strong>е</strong>д началом работы<br />

цикля. Цикл запуска<strong>е</strong>тся<br />

при соблюд<strong>е</strong>нии услобия.<br />

Зд<strong>е</strong>сь п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

использу<strong>е</strong>мой<br />

для подсч<strong>е</strong>та<br />

проходов цикла<br />

присваива<strong>е</strong>тся<br />

’ . ..-л<br />

н а ч а л ь н о <strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. M essa g eB o x .sh o w (" T h e an sw er i s " + c o u n t)<br />

}<br />

Оп<strong>е</strong>ратор, при<br />

каждом проход<strong>е</strong><br />

цикла ув<strong>е</strong>личивающый<br />

знач<strong>е</strong>ни<strong>е</strong> I на х.<br />

П <strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м как щ <strong>е</strong>лкнуть на кнопк<strong>е</strong>, попы тайт<strong>е</strong>сь по виду кода понять,<br />

како<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> буд<strong>е</strong>т в окн<strong>е</strong>. Пров<strong>е</strong>рьт<strong>е</strong> правильность своих вы водов!<br />

дальш<strong>е</strong> ► 101


выш<strong>е</strong> и выш<strong>е</strong> и выш<strong>е</strong> и...<br />

возьми в руку карандаш<br />

Попрактикуйт<strong>е</strong>сь в пров<strong>е</strong>рк<strong>е</strong> условий циклов. Посмотрит<strong>е</strong> на код<br />

и напишит<strong>е</strong> поясн<strong>е</strong>ния к каждой <strong>е</strong>го строк<strong>е</strong>.<br />

i n t r e s u l t = 0 ; / / п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная, в которую б у д <strong>е</strong>т зап и сан р <strong>е</strong>зу л ь т а т<br />

I n t X = 6; I I объявим п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную х и<br />

w h ile (х > 3) {<br />

/ / оп<strong>е</strong>раторы будут выполняться, пока<br />

присвоим знач<strong>е</strong>ни<strong>е</strong> 6<br />

Заполнит<strong>е</strong><br />

остальны<strong>е</strong><br />

строки по<br />

------------ - аналогии.<br />

r e s u l t = r e s u l t + х ; / / прибавим х<br />

X = X<br />

- 1; / / вычт<strong>е</strong>м<br />

}<br />

for (in t z = l ; z < 3 ; 2 = z + l ) {<br />

/ / начн<strong>е</strong>м цикл с .....................................<br />

/ / 191КЛ р а б о т а <strong>е</strong>т пока<br />

//н а каждом э т а п <strong>е</strong> , .................................<br />

r e s u lt = r e s u lt + z; / / ....................<br />

}<br />

/ / Сл<strong>е</strong>дующий оп<strong>е</strong>ратор вызыва<strong>е</strong>т окно диалога с т<strong>е</strong>кстом<br />

/ /<br />

M essageB ox.Show ("Р <strong>е</strong>зультат рав<strong>е</strong>н " + r e s u l t ) ;<br />

Ещ<strong>е</strong> о пров<strong>е</strong>рк<strong>е</strong> условий<br />

п р о в <strong>е</strong> р к а у сл о в и и о с у щ <strong>е</strong> с т в л я <strong>е</strong> м с я п р и п о м о щ и<br />

о п <strong>е</strong> р а т о р о в ср а в н <strong>е</strong>ния:<br />

X < у (м<strong>е</strong>ньш<strong>е</strong> ч<strong>е</strong>м)<br />

X > у (больш<strong>е</strong> ч<strong>е</strong>м)<br />

X == у (равно)<br />

Э т и о п <strong>е</strong> р а т о р ы и с п о л ь з у ю т с я чащ <strong>е</strong> вс<strong>е</strong>го.<br />

102 глава 2


это вс<strong>е</strong>го лишь код<br />

Подождит<strong>е</strong>! А что случится с<br />

циклом, <strong>е</strong>сли я напишу услови<strong>е</strong>,<br />

которо<strong>е</strong> никогда н<strong>е</strong> выполня<strong>е</strong>тся?<br />

Значит, цикл никогда н<strong>е</strong> закончится!<br />

цикдізівозьми<br />

в руку карандаш<br />

Р<strong>е</strong>зультатом каждой пров<strong>е</strong>рки условия явля<strong>е</strong>тся<br />

знач<strong>е</strong>ни<strong>е</strong> t r u e или f a l s e . В п<strong>е</strong>рвом случа<strong>е</strong> цикл<br />

выполня<strong>е</strong>тся <strong>е</strong>щ<strong>е</strong> раз. Рано или поздно вы должны<br />

получить другой р<strong>е</strong>зультат, и тогда цикл закончится.<br />

Вот н<strong>е</strong>сколько циклов. Каки<strong>е</strong> из них являются б<strong>е</strong>скон<strong>е</strong>чными?<br />

Сколько раз выполняются остальны<strong>е</strong> циклы?<br />

Ц икл # 1<br />

i n t c o u n t = 5;<br />

w h ile (co u n t > 0 ) {<br />

c o u n t = c o u n t * 3;<br />

c o u n t = c o u n t * -1 ;<br />

} Сколько раз<br />

буд<strong>е</strong>т выполн<strong>е</strong>н<br />

этот оп<strong>е</strong>ратор?<br />

Ц икл # 2<br />

i n t i = 0;<br />

i n t c o u n t = 2;<br />

w h ile ( i == 0) {<br />

}<br />

c o u n t = c o u n t * 3;<br />

c o u n t = c o u n t * -1<br />

Ц икл # 3<br />

i n t 3 = 2 ;<br />

f o r ( i n t і = 1; і < 100;<br />

{<br />

І = І * 2)<br />

‘И = j - І;<br />

w h ile (j < 25)<br />

{<br />

j = j + 5;<br />

} Сколько раз<br />

буд<strong>е</strong>т выполн<strong>е</strong>н ■<br />

э т о т оп<strong>е</strong>ратор?<br />

Ц икл # 4<br />

w h ile (tr u e ) { i n t і = 1 ;}<br />

Ц и кл # 5<br />

i n t р = 2;<br />

f o r ( i n t q = 2; q < 32;<br />

{<br />

q = q * 2)<br />

w h ile (p < q)<br />

{<br />

P = P * 2;<br />

kq = p - q;<br />

При повтор<strong>е</strong>нии<br />

\ 1^т<strong>е</strong>ратора ^ = а * 2<br />

помнит<strong>е</strong>, что начально<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> ^ равно 2..<br />

\<br />

8 цикл<strong>е</strong> for сначала<br />

выполня<strong>е</strong>тся пров<strong>е</strong>рка<br />

услобия, а потом<br />

ит<strong>е</strong>ратор.<br />

^ Ш Т У Р М<br />

Подумайт<strong>е</strong>, в какой ситуации мож<strong>е</strong>т понадобиться<br />

б<strong>е</strong>скон<strong>е</strong>чный цикл? (Один из вариантов отв<strong>е</strong>та вы<br />

найд<strong>е</strong>т<strong>е</strong> в глав<strong>е</strong> 13...)<br />

дальш<strong>е</strong> ► 103


<strong>е</strong>сли только, но только <strong>е</strong>сли<br />

- 1^ о зь м и в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот, как сл<strong>е</strong>довало закончить строчки комм<strong>е</strong>нтари<strong>е</strong>в к программ<strong>е</strong>,<br />

иллюстрирующ<strong>е</strong>й работу циклов и пров<strong>е</strong>рку условий.<br />

i n t r e s u l t = 0; / / п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная, в которую б у д <strong>е</strong>т зап и сан р <strong>е</strong>зу л ь тат<br />

i n t X = 6; / / объявим п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную х и ..............<br />

w h ile<br />

/ / оп<strong>е</strong>раторы будут выполняться, пока X больш<strong>е</strong> 3<br />

r e s u l t = r e s u l t + х ; / / прибавим х<br />

К п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной result<br />

X = X<br />

- 1; / / вычт<strong>е</strong>м<br />

}<br />

f o r ( i n t 2 =<br />

11 начн<strong>е</strong>м 191КЛ с<br />

/ / цикл р а б о т а <strong>е</strong>т пока<br />

//н а каждом эт а п <strong>е</strong><br />

r e s u l t = r e s u l t + z; / /<br />

i из п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й X<br />

Z + 1) {<br />

Этот цикл выполня<strong>е</strong>тся дважды: сначала при г<br />

равном 1, зат<strong>е</strong>м при г равном а. Как только<br />

Z получит знач<strong>е</strong>ни<strong>е</strong> 3 , услови<strong>е</strong> п<strong>е</strong>р<strong>е</strong>стан<strong>е</strong>т соблюдаться,<br />

и цикл остановится.<br />

обьявл<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной г и присво<strong>е</strong>ния <strong>е</strong>й знач<strong>е</strong>ния 1<br />

Z м<strong>е</strong>ньш<strong>е</strong> 3<br />

знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной z ув<strong>е</strong>личива<strong>е</strong>тся на 1<br />

п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н а я Z п р и б а вля<strong>е</strong>т с я к п <strong>е</strong>р <strong>е</strong> м <strong>е</strong> н н о й result<br />

}<br />

/ / Сл<strong>е</strong>дующий оп<strong>е</strong>ратор вызыва<strong>е</strong>т окно диалога с т<strong>е</strong>кстом<br />

M essageB ox.Show ("Р <strong>е</strong>зультат рав<strong>е</strong>н" + r e s u l t ) ;<br />

Г<br />

в руку карандаш<br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Сравнит<strong>е</strong> свои отв<strong>е</strong>ты на вопрос, сколько раз буд<strong>е</strong>т выполн<strong>е</strong>н<br />

тот или иной цикл с правильными отв<strong>е</strong>тами.<br />

Ц икл # 1<br />

Буд<strong>е</strong>т выполн<strong>е</strong>н один раз.<br />

Ц икл # 2<br />

Б<strong>е</strong>скон<strong>е</strong>чный цикл<br />

Ц икл # 3<br />

Буд<strong>е</strong>т выполн<strong>е</strong>н с<strong>е</strong>мь раз.<br />

Ц икл # 4<br />

Ещ<strong>е</strong> один б<strong>е</strong>скон<strong>е</strong>чный цикл.<br />

Ц икл # 5<br />

Буд<strong>е</strong>т выполн<strong>е</strong>н<br />

вос<strong>е</strong>мь раз.<br />

Попробуйт<strong>е</strong> р<strong>е</strong>шить задачу ном<strong>е</strong>р пять. Это отличная возможность поработать с о т ­<br />

ладчиком! Сд<strong>е</strong>лайт<strong>е</strong> оп<strong>е</strong>ратор с) = р ~ точкой останова и пров<strong>е</strong>рьт<strong>е</strong>, как изм<strong>е</strong>няются<br />

знач<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных р и q с помошрю окна Watches■<br />

104 глава 2


часвдо<br />

З а д а в а <strong>е</strong> м ы <strong>е</strong><br />

БоЦ|эос;ь1<br />

это вс<strong>е</strong>го лишь код<br />

Вс<strong>е</strong>гда ли оп<strong>е</strong>ратор принадл<strong>е</strong>жит к какому-нибудь классу?<br />

Г ! Да. Вс<strong>е</strong> оп<strong>е</strong>раторы принадл<strong>е</strong>жат к опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным кпассам,<br />

точно такж<strong>е</strong> как вс<strong>е</strong> классы, в свою оч<strong>е</strong>р<strong>е</strong>дь, принадл<strong>е</strong>жат пространствам<br />

им<strong>е</strong>н. Когда вы использу<strong>е</strong>т<strong>е</strong> конструктор для задания<br />

свойств объ<strong>е</strong>ктов формы, мож<strong>е</strong>т показаться, что н<strong>е</strong>которы<strong>е</strong> оп<strong>е</strong>раторы<br />

находятся вн<strong>е</strong> классов. Но внимат<strong>е</strong>льно<strong>е</strong> рассмотр<strong>е</strong>ни<strong>е</strong><br />

кода показыва<strong>е</strong>т, что на самом д<strong>е</strong>л<strong>е</strong> это н<strong>е</strong> так.<br />

Сущ<strong>е</strong>ствуют ли пространства им<strong>е</strong>н, которы<strong>е</strong> я н<strong>е</strong> могу<br />

использовать? А как насч<strong>е</strong>т т<strong>е</strong>х, которы<strong>е</strong> я обязан использовать?<br />

Q l Да, н<strong>е</strong>которы<strong>е</strong> пространства им<strong>е</strong>н использовать н<strong>е</strong> р<strong>е</strong>ком<strong>е</strong>нду<strong>е</strong>тся,<br />

наприм<strong>е</strong>р, пространство им<strong>е</strong>н System . Им<strong>е</strong>нно там<br />

находятся S y stem .D a ta , позволяющий работать с таблицами<br />

и базами данных, и S y stem , ю , об<strong>е</strong>сп<strong>е</strong>чивающий работу<br />

с файлами и потоками данных. Но по больш<strong>е</strong>й части вы мож<strong>е</strong>т<strong>е</strong><br />

называть пространства им<strong>е</strong>н, как вам нравится. Или отдать это на<br />

откуп ИСР, которая буд<strong>е</strong>т автоматич<strong>е</strong>ски создавать им<strong>е</strong>на, взяв за<br />

основу имя программы.<br />

Б<br />

! А вс<strong>е</strong>-таки, зач<strong>е</strong>м нужно ключ<strong>е</strong>во<strong>е</strong> слово partial?<br />

( 1 ; Оно позволя<strong>е</strong>т распр<strong>е</strong>д<strong>е</strong>лять код одного класса м<strong>е</strong>жду разными<br />

файлами. При создании формы, ИСР сохраня<strong>е</strong>т р<strong>е</strong>дактиру<strong>е</strong>мый<br />

вами код в файл (к прим<strong>е</strong>ру, F o rm l. cs), а автоматич<strong>е</strong>ски модифициру<strong>е</strong>мый<br />

— в файл (Forml . D e s ig n e r . cs). Но оба они находятся<br />

в одном пространств<strong>е</strong> им<strong>е</strong>н. Достаточно объявить пространство<br />

им<strong>е</strong>н в в<strong>е</strong>рхн<strong>е</strong>й части файла, и <strong>е</strong>му буд<strong>е</strong>т принадл<strong>е</strong>жать вс<strong>е</strong>, что<br />

попада<strong>е</strong>т в фигурны<strong>е</strong> скобки, располож<strong>е</strong>нны<strong>е</strong> ниж<strong>е</strong>. При этом в одном<br />

файл<strong>е</strong> могут находится объ<strong>е</strong>кгы из разных пространств им<strong>е</strong>н<br />

и разных классов. Но об этом мы поговорим в сл<strong>е</strong>дующ<strong>е</strong>й глав<strong>е</strong>.<br />

Что происходит с кодом, который был автоматич<strong>е</strong>ски<br />

создан ИСР, <strong>е</strong>сли воспользоваться командой Undo?<br />

^ ; Попробуйт<strong>е</strong>, и вы сами найд<strong>е</strong>т<strong>е</strong> отв<strong>е</strong>т на этот вопрос! П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong><br />

на форму кнопку и пом<strong>е</strong>няйт<strong>е</strong> <strong>е</strong><strong>е</strong> свойства. А зат<strong>е</strong>м воспользуйт<strong>е</strong>сь<br />

командой отм<strong>е</strong>ны. Вы увидит<strong>е</strong>, что в простых случаях<br />

ИСР просто возвраща<strong>е</strong>т вас в пр<strong>е</strong>дьщущую точку. Но при попытк<strong>е</strong><br />

отм<strong>е</strong>нить вставку в базу данных SQL появится окно с пр<strong>е</strong>дупр<strong>е</strong>жд<strong>е</strong>ни<strong>е</strong>м,<br />

что посл<strong>е</strong> отм<strong>е</strong>ны оп<strong>е</strong>рации вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong> отм<strong>е</strong>нить сво<strong>е</strong><br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> командой Redo.<br />

Насколько внимат<strong>е</strong>льно нужно относится к автоматич<strong>е</strong>ски<br />

создава<strong>е</strong>мому коду?<br />

! Относит<strong>е</strong>сь к н<strong>е</strong>му достаточно внимат<strong>е</strong>льно. Нужно понимать<br />

соотв<strong>е</strong>тстви<strong>е</strong> м<strong>е</strong>жду кодом и вашими д<strong>е</strong>йствиями, чтобы при н<strong>е</strong>обходимости<br />

им<strong>е</strong>ть возможность отр<strong>е</strong>дактировать <strong>е</strong>го вручную.<br />

Впроч<strong>е</strong>м, в подавляющ<strong>е</strong>м большинств<strong>е</strong> случа<strong>е</strong>в вс<strong>е</strong> н<strong>е</strong>обходимы<strong>е</strong><br />

изм<strong>е</strong>н<strong>е</strong>ния можно прод<strong>е</strong>лать с помощью ИСР.<br />

■<br />

КЛЮЧЕВЫЕ<br />

МОМЕНТЫ<br />

Вашу программу заставляют работать оп<strong>е</strong>раторы,<br />

которы<strong>е</strong> вс<strong>е</strong>гда принадл<strong>е</strong>жат к какому-либо<br />

классу. Класс ж<strong>е</strong>, в свою оч<strong>е</strong>р<strong>е</strong>дь, находится<br />

в каком-то пространств<strong>е</strong> им<strong>е</strong>н.<br />

■ В конц<strong>е</strong> оп<strong>е</strong>раторов стоит знак (;).<br />

■<br />

■<br />

■<br />

■<br />

■<br />

■<br />

В отв<strong>е</strong>т на ваши д<strong>е</strong>йствия Visual Studio автоматич<strong>е</strong>ски<br />

добавля<strong>е</strong>т в программу код.<br />

Блоки кода, таки<strong>е</strong> как классы, цикл w h i l e , оп<strong>е</strong>раторы<br />

if/else и многи<strong>е</strong> други<strong>е</strong> виды оп<strong>е</strong>раторов<br />

заключаются в фигурны<strong>е</strong> скобки { }.<br />

Р<strong>е</strong>зультатом пров<strong>е</strong>рки условия явля<strong>е</strong>тся знач<strong>е</strong>ни<strong>е</strong><br />

t r u e или f a l s e . С <strong>е</strong>го помощью опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся,<br />

буд<strong>е</strong>т ли законч<strong>е</strong>н цикл, а такж<strong>е</strong> какой<br />

им<strong>е</strong>нно блок кода буд<strong>е</strong>т р<strong>е</strong>ализован в оп<strong>е</strong>ратор<strong>е</strong><br />

if/else.<br />

Для хран<strong>е</strong>ния данных используются п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

Оп<strong>е</strong>ратор = присваива<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной знач<strong>е</strong>ни<strong>е</strong>,<br />

а оп<strong>е</strong>ратор == сравнива<strong>е</strong>т знач<strong>е</strong>ния двух<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных.<br />

Цикл w h i l e выполня<strong>е</strong>т вс<strong>е</strong> оп<strong>е</strong>раторы в фигурных<br />

скобках, пока р<strong>е</strong>зультатом пров<strong>е</strong>рки условия<br />

явля<strong>е</strong>тся знач<strong>е</strong>ни<strong>е</strong> t r u e .<br />

Как только пров<strong>е</strong>рка условия да<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

f a l s e , цикл w h i l e пр<strong>е</strong>краща<strong>е</strong>т работу, и программа<br />

п<strong>е</strong>р<strong>е</strong>ходит к оп<strong>е</strong>ратору, располож<strong>е</strong>нному<br />

сразу посл<strong>е</strong> цикла.<br />

дальш<strong>е</strong> > 105


ваш код... т<strong>е</strong>п<strong>е</strong>рь в вид<strong>е</strong> магнитов<br />

^ а Г н и ш ы С К о д а м и<br />

Пустыми кавычками обознач<strong>е</strong>на<br />

пустая строка. Это означа<strong>е</strong>т,<br />

что п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная Result <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> сод<strong>е</strong>ржит<br />

т<strong>е</strong>кста.<br />

j<br />

Мы пом<strong>е</strong>стили блоки с фрагм<strong>е</strong>нтами кода на С# на магниты для холодильника. Составьт<strong>е</strong><br />

из них работающую программу, р<strong>е</strong>зультатом которой явля<strong>е</strong>тся окно с сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

Н<strong>е</strong>которы<strong>е</strong> магнитики упали на пол, и они слишком малы, чтобы их поднимать,<br />

поэтому просто впишит<strong>е</strong> н<strong>е</strong>достающий код от руки! (Подсказка: вам понадобится вс<strong>е</strong>го<br />

пара фрагм<strong>е</strong>нтов!)<br />

s tr in g R esu lt =<br />

Этот магнит<br />

упал на пол..<br />

i f (X == 2) {<br />

R esult = R esu lt + " b e<br />

}<br />

--------------<br />

i f (X > 2) {<br />

R esu lt = R esu lt + "a";<br />

><br />

in t X = 3; 1<br />

Р<strong>е</strong>зультат:<br />

M essageBox.Show (Reeult);<br />

О ш Б <strong>е</strong> ш ы н а с. I 3 -<br />

106 глава 2


Вам прид<strong>е</strong>тся выполнить много<br />

подобных упражн<strong>е</strong>ний. О т в<strong>е</strong>ты<br />

можно найти на сл<strong>е</strong>дуюш,<strong>е</strong>й<br />

страниц<strong>е</strong>. Если вы н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, как<br />

р<strong>е</strong>шить задачу, н<strong>е</strong> ст<strong>е</strong>сняйт<strong>е</strong>сь<br />

подсмотр<strong>е</strong>ть.<br />

это вс<strong>е</strong>го лишь код<br />

В проц<strong>е</strong>сс<strong>е</strong> чт<strong>е</strong>ния книги вам пр<strong>е</strong>дстоит создать<br />

много разных прилож<strong>е</strong>ний, и вс<strong>е</strong> их нужно<br />

оуд<strong>е</strong>т кйк~т.0 млдснобйт<strong>е</strong>?, Мь>/ совсту<strong>е</strong>м присвоumt?<br />

этому прилож<strong>е</strong>нию имя «Z Fun with if-else<br />

statem ents» (z Забава с оп<strong>е</strong>раторами if-else ), получ<strong>е</strong>нно<strong>е</strong><br />

в р<strong>е</strong>зультат<strong>е</strong> комбинации ном<strong>е</strong>ра главы<br />

и т<strong>е</strong>кста 8 строк<strong>е</strong> заголовка формы.<br />

а ж н ш <strong>е</strong><br />

Попрактику<strong>е</strong>мся в использовании оп<strong>е</strong>ратора if/else. Смож<strong>е</strong>т<strong>е</strong> создать программу?<br />

Ф орм а, которую нужно получить.<br />

a-J Fun with if/else statements!<br />

Д обавьт<strong>е</strong> ф лажок.<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> флажок с пан<strong>е</strong>ли инструм<strong>е</strong>нтов<br />

на форму и отр<strong>е</strong>дактируйт<strong>е</strong> свойство<br />

T e x t. Аналогичным способом нужно буд<strong>е</strong>т<br />

отр<strong>е</strong>дактировать т<strong>е</strong>кст кнопки и м<strong>е</strong>тки.<br />

Change the color if the<br />

bexisdiecked<br />

Press the<br />

® Бпйй<strong>е</strong> color d ianghg<br />

Это м<strong>е</strong>тка.<br />

В окн<strong>е</strong> Properties пом<strong>е</strong>няйт<strong>е</strong> разм<strong>е</strong>р<br />

шрифта и сд<strong>е</strong>лайт<strong>е</strong> <strong>е</strong>го полужирным.<br />

С помощью свойства B a c k C o lo r сд<strong>е</strong>лайт<strong>е</strong><br />

фон красным. Выб<strong>е</strong>рит<strong>е</strong> вариант<br />

R ed на вкладк<strong>е</strong> web colors.<br />

Если пользоват<strong>е</strong>ль забы л поставить ф лажок, должно<br />

вы водится окно, инф орм ирую щ <strong>е</strong><strong>е</strong> <strong>е</strong>го об этом.<br />

Имя флажка c h e c k B o x l. Если флажок установл<strong>е</strong>н, должно соблюдаться<br />

услови<strong>е</strong>:<br />

c h e c k B o x l. C hecked == tr u e<br />

При установл<strong>е</strong>нном ф лажк<strong>е</strong> щ <strong>е</strong>лчок на кнопк<strong>е</strong> долж<strong>е</strong>н м <strong>е</strong>нять ф оновы й<br />

цв<strong>е</strong>т м<strong>е</strong>тки.<br />

Красный фоновый цв<strong>е</strong>т м<strong>е</strong>тки долж<strong>е</strong>н м<strong>е</strong>няться на синий. И наоборот. Вот оп<strong>е</strong>ратор,<br />

задающий фоновый цв<strong>е</strong>т м<strong>е</strong>тки с им<strong>е</strong>н<strong>е</strong>м l a b e l l :<br />

la b e ll.B a c k C o lo r = C o lo r.R ed ;<br />

(Подсказка: Пров<strong>е</strong>рка условия, явля<strong>е</strong>тся ли фоновый цв<strong>е</strong>т м<strong>е</strong>тки красным, выглядит<br />

практич<strong>е</strong>ски так ж<strong>е</strong>, но с одним мал<strong>е</strong>ньким отличи<strong>е</strong>м!)<br />

дальш<strong>е</strong> * 107


симпатично!<br />

п'ражн<strong>е</strong>ни<strong>е</strong><br />

Построим что-то ярко<strong>е</strong>! Начнит<strong>е</strong> с создания нового про<strong>е</strong>кта Windows Forms Application.<br />

Вот ф орма, которую<br />

нужно получить<br />

П <strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная, э п р и наличии<br />

cm6yew только внy^v^P^*<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ннук>, нужно<br />

ЭвйХ циклов h r '»»«■ “ " “ “ Г <strong>е</strong> « “ Йр<strong>е</strong>м<strong>е</strong>^ная с а * <strong>е</strong> оЙ.»во<br />

Сд<strong>е</strong>лайт<strong>е</strong> цюновый цв<strong>е</strong>т броским!<br />

Пусть р<strong>е</strong>зультатом щ<strong>е</strong>лчка на кнопк<strong>е</strong> стан<strong>е</strong>т циклично<strong>е</strong><br />

изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> фонового цв<strong>е</strong>та! Создайт<strong>е</strong><br />

цикл, в котором знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной с м<strong>е</strong>ня<strong>е</strong>тся<br />

от О до 253. Вот как выглядит код:<br />

t h is .B a c k C o lo r = C o lo r.F ro tn A rg b (c, 255 - с ,<br />

с) ;<br />

A p p l ic a t io n .D o E v e n t s О ; ^<br />

^<br />

п <strong>е</strong>р<strong>е</strong>с^ а н <strong>е</strong>т о Л о в л К м т ак кок<br />

уЭмби м<strong>е</strong>ня ц б <strong>е</strong> то м !<br />

\<br />

М<strong>е</strong>тод РоЕу<strong>е</strong>пЬв () принудит<strong>е</strong>льно<br />

обновля<strong>е</strong>т форму на каждом витк<strong>е</strong><br />

цикла, но это «обходной» путь,<br />

который н<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т использовать<br />

в с<strong>е</strong>рь<strong>е</strong>зных программах.<br />

„ в» MOW-“ зага««»» “<br />

на о д g варианты п т<br />

свои собств<strong>е</strong>нны<strong>е</strong> р<br />

о<br />

Зам <strong>е</strong>длит<strong>е</strong> проц<strong>е</strong>сс<br />

Чтобы цв<strong>е</strong>та м<strong>е</strong>нялись м<strong>е</strong>дл<strong>е</strong>нн<strong>е</strong><strong>е</strong>, посл<strong>е</strong> строки<br />

A p p lic a tio n . D oEvents () напишит<strong>е</strong>:<br />

S y s te m . T h r e a d in g . T h r e a d . S le e p<br />

мм<strong>е</strong>н system .Threading.<br />

108 глава 2


это вс<strong>е</strong>го лишь код<br />

Сглаживани<strong>е</strong> проц<strong>е</strong>сса<br />

Пусть цв<strong>е</strong>товая гамма возвраща<strong>е</strong>тся к изначальному цв<strong>е</strong>ту. Для этого добавьт<strong>е</strong><br />

<strong>е</strong>щ<strong>е</strong> один цикл, в котором п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная с буд<strong>е</strong>т м<strong>е</strong>няться уж<strong>е</strong> от 254<br />

до 0. В фигурны<strong>е</strong> скобки поставьт<strong>е</strong> блок кода из пр<strong>е</strong>дыдущ<strong>е</strong>го цикла.<br />

Сд<strong>е</strong>лайт<strong>е</strong> проц<strong>е</strong>сс н<strong>е</strong>пр<strong>е</strong>рывным<br />

находящийся<br />

Пом<strong>е</strong>стит<strong>е</strong> два цикла внутрь тр<strong>е</strong>ть<strong>е</strong>го, который буд<strong>е</strong>т выполняться б<strong>е</strong>с- внутри другого<br />

кон<strong>е</strong>чно. В итог<strong>е</strong> щ<strong>е</strong>лчок на кнопк<strong>е</strong> буд<strong>е</strong>т приводить к н<strong>е</strong>пр<strong>е</strong>рывному цикла, называ<strong>е</strong>тся<br />

изм<strong>е</strong>н<strong>е</strong>нию фонового цв<strong>е</strong>та. (Подсказка: цикл w h i l e явля<strong>е</strong>тся б<strong>е</strong>скон<strong>е</strong>ч- "-^в^ож<strong>е</strong>нным».<br />

ным, <strong>е</strong>сли пров<strong>е</strong>рка условия да<strong>е</strong>т р<strong>е</strong>зультат ( t r u e ) !)<br />

Ой-<strong>е</strong>-<strong>е</strong>й! Программа н<strong>е</strong> останавлива<strong>е</strong>тся!<br />

Посл<strong>е</strong> запуска этой программы остановить <strong>е</strong><strong>е</strong> работу просто закрыв<br />

окно уж<strong>е</strong> н<strong>е</strong>возможно! Для пр<strong>е</strong>кращ<strong>е</strong>ния <strong>е</strong><strong>е</strong> работы воспользуйт<strong>е</strong>сь,<br />

к прим<strong>е</strong>ру, командой Stop Debugging из м<strong>е</strong>ню Debug.<br />

О<br />

О становит<strong>е</strong> <strong>е</strong><strong>е</strong>!<br />

Сд<strong>е</strong>ла<strong>е</strong>м так, чтобы цикл, добавл<strong>е</strong>нный на пр<strong>е</strong>дыдущ<strong>е</strong>м<br />

шаг<strong>е</strong>, останавливался при закрытии формы. Зам<strong>е</strong>нит<strong>е</strong> п<strong>е</strong>рвую<br />

строчку на:<br />

w h i l e ( V i s i b l e )<br />

пустит<strong>е</strong> программу и щ<strong>е</strong>лкнит<strong>е</strong> на кр<strong>е</strong>стик<strong>е</strong> в правом<br />

в<strong>е</strong>рхн<strong>е</strong>м углу формы. Окно закро<strong>е</strong>тся, и программа остановится.<br />

Пусть и с зад<strong>е</strong>ржкой в н<strong>е</strong>сколько миллис<strong>е</strong>кунд.<br />

Пров<strong>е</strong>рку видимости объ<strong>е</strong>кта можно<br />

н<strong>е</strong> писать в форм<strong>е</strong> — Visible == true.<br />

Достаточно п<strong>е</strong>рвой половины выраж<strong>е</strong>ния.<br />

/<br />

tn e .<br />

Подсказка: && означа<strong>е</strong>т<br />

«И». Им<strong>е</strong>нно этот оп<strong>е</strong>ратор<br />

позволя<strong>е</strong>т со<strong>е</strong>динить<br />

Ш <strong>е</strong>ст<strong>е</strong> н<strong>е</strong>сколько условий.<br />

Р<strong>е</strong>зультат буд<strong>е</strong>т истинным<br />

только при одновр<strong>е</strong>м<strong>е</strong>нном<br />

выполн<strong>е</strong>нии этих<br />

условии.<br />

М ож<strong>е</strong>т<strong>е</strong> ли вы объ яснить эту зад<strong>е</strong>рж ку и п<strong>е</strong>р<strong>е</strong>писать код<br />

таким образом, чтобы возвращ <strong>е</strong>ни<strong>е</strong> в р<strong>е</strong>жим р<strong>е</strong>дактирования<br />

происходило сразу посл<strong>е</strong> закры тия ф ормы ?<br />

!/<br />

дальш<strong>е</strong> у 109


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

<strong>е</strong> ш ш <strong>е</strong><br />

u s in g System ;<br />

Вот как долж<strong>е</strong>н выгляд<strong>е</strong>ть т<strong>е</strong>кст программы, циклично изм<strong>е</strong>няющ<strong>е</strong>й фоновый цв<strong>е</strong>т формы.<br />

u s in g S y s t e m .C o l le c t io n s .G e n e r i c ,■<br />

u s in g System .C om ponentM odel,•<br />

u s in g S y ste m .D a ta ;<br />

u s in g S y stem .D ra w in g ;<br />

u s in g S y ste m .L in q ;<br />

u s in g S y s te m .T e x t;<br />

u s in g System .W in dow s.F orm s;<br />

Mb/ присвоили р<strong>е</strong>ш<strong>е</strong>нию имя<br />

Fun with if Else, поэтому<br />

ИСР назвала пространство<br />

им<strong>е</strong>н таким ооразом.<br />

nam espace F u n _ w ith _ If_ E lse<br />

{<br />

p u b l i c p a r t i a l c l a s s Form l<br />

{<br />

p u b l i c F o r m l0<br />

{<br />

I n it i a l iz e C o m p o n e n t ();<br />

}<br />

: Form<br />

Посл<strong>е</strong> двойного ш,<strong>е</strong>лчка на<br />

кнопк<strong>е</strong> ИСР добавила к форм<strong>е</strong><br />

м<strong>е</strong>тод ЬиШт^сИскП.<br />

Этот м<strong>е</strong>тод запуска<strong>е</strong>тся<br />

при каждом ш,<strong>е</strong>лчк<strong>е</strong> на<br />

кнопк<strong>е</strong>.<br />

Вн<strong>е</strong>шний<br />

оп<strong>е</strong>ратор if<br />

пров<strong>е</strong>ря<strong>е</strong>т,<br />

установл<strong>е</strong>н<br />

ли флажок.<br />

private void buttonl_Click(object sender, EventArgs e)<br />

{<br />

if (checkBoxl.Checked == true)<br />

{<br />

if (labell BackColor == Color.Red)<br />

{<br />

labell.BackColor = Color.Blue;<br />

' }<br />

else<br />

{<br />

labell.BackColor = Color.Red;<br />

}<br />

}<br />

e lse<br />

{<br />

MessageBox.Show("The box is not checked")<br />

}<br />

Внутр<strong>е</strong>нний<br />

оп<strong>е</strong>ратор if<br />

пров<strong>е</strong>ря<strong>е</strong>т<br />

цв<strong>е</strong>т м<strong>е</strong>тки.<br />

Если м<strong>е</strong>тка<br />

красная,<br />

выполня<strong>е</strong>тся<br />

оп<strong>е</strong>ратор,<br />

изм<strong>е</strong>няющий<br />

цв<strong>е</strong>т на синий.<br />

Если м<strong>е</strong>тка<br />

н<strong>е</strong> красная,<br />

оп<strong>е</strong>ратор<br />

изм<strong>е</strong>ня<strong>е</strong>т цв<strong>е</strong>т<br />

на красный.<br />

} Это окно диалога появля<strong>е</strong>тся<br />

при отсутствии флажка.<br />

Скачать код с р<strong>е</strong>ш <strong>е</strong>ниям и вс<strong>е</strong>х упраж н<strong>е</strong>ний из книги<br />

можно зд<strong>е</strong>сь w w w .headfirstlabs.com /books/hfcsharp/<br />

110 глава 2


это вс<strong>е</strong>го лишь код<br />

;н<strong>е</strong>нУ1<strong>е</strong><br />

р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong><br />

Построим что-то ярко<strong>е</strong>!<br />

Иногда в разд<strong>е</strong>л<strong>е</strong> «Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>»<br />

приводится н<strong>е</strong> в<strong>е</strong>сь код программы^<br />

а только т<strong>е</strong> фрагм<strong>е</strong>нты,<br />

которы<strong>е</strong> тр<strong>е</strong>бовалось<br />

отр<strong>е</strong>дактировать.<br />

Добавляя этот м<strong>е</strong>тод, ИСР поставила дополнит<strong>е</strong>льны<strong>е</strong><br />

проб<strong>е</strong>лы п<strong>е</strong>р<strong>е</strong>д фигурными скобками.<br />

Иногда для экономии м<strong>е</strong>ста эти скобки могут<br />

располагаться нй одной строк<strong>е</strong> с оп<strong>е</strong>ратором<br />

— в с * такая форма записи вполн<strong>е</strong> допустима.<br />

1г<br />

Крайн<strong>е</strong> важно, чтобы ваш код могли л<strong>е</strong>гко читать<br />

други<strong>е</strong> пользоват<strong>е</strong>ли. Но мы нам<strong>е</strong>р<strong>е</strong>нно показыва<strong>е</strong>м<br />

вам разны<strong>е</strong> варианты, так как вы должны привыкнуть<br />

читать код, написанный в различном стил<strong>е</strong>.<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n tA rg s e),<br />

/ '" '^ w h i l e ( V i s i b l e ) {<br />

пока открыта<br />

форма.<br />

с = 0; с < 254 № V isib le ; C++)<br />

t h i s .B a c k C o l o r = C o l o r . F ro m A rg b ( с , 255 - с , с ) ;<br />

A p p l i c a t i o n . D o E v e n ts ( ) ; ^ „ г<br />

V Ч Чиклй м<strong>е</strong>няют<br />

System .T hreading.T hread.SleepO );<br />

}<br />

^ в разны<strong>е</strong> стороны.<br />

f o r ( i n t с = 2 5 4 ; С >= О && V i s i b l e ; с--) {<br />

t h i s .B a c k C o l o r = C o l o r . F ro m A rg b (с , 255 - с , с ) ;<br />

^<br />

A p p l i c a t io n .D o E v e n ts О ;<br />

S y s t e m .T h r e a d i n g .T h r e a d .S l e e p (3) ;<br />

О п <strong>е</strong> р а т о р && п о зв о л я <strong>е</strong> т<br />

п ю <strong>е</strong> р В а т ь цикл for, как<br />

J^omko п а р а м <strong>е</strong> т р ViSime<br />

прим<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> false.<br />

^<br />

} Пом нит<strong>е</strong> вопрос, как убрать зад<strong>е</strong>рж ку с возвращ <strong>е</strong>ни<strong>е</strong>м<br />

в р<strong>е</strong>жим р<strong>е</strong>дактирования посл<strong>е</strong> закры тия окна?<br />

Зад<strong>е</strong>ржка возника<strong>е</strong>т из-за н<strong>е</strong>возможности пров<strong>е</strong>рить знач<strong>е</strong>ни<strong>е</strong><br />

парам<strong>е</strong>тра Visible до зав<strong>е</strong>рш<strong>е</strong>ния цикла for. Поэтому<br />

к пров<strong>е</strong>рк<strong>е</strong> условия добавили код && V is ib le .<br />

Любую задачу программирования можно р<strong>е</strong>шить бол<strong>е</strong><strong>е</strong> ч<strong>е</strong>м<br />

одним способом, так что попробуйт<strong>е</strong> написать свой вариант<br />

кода, взяв за основу циклы while вм<strong>е</strong>сто циклов for.<br />

дальш<strong>е</strong> ► 111


это н<strong>е</strong> такой простой р<strong>е</strong>бус, как каж<strong>е</strong>тся<br />

Б б а с с <strong>е</strong> й н <strong>е</strong><br />

Р<strong>е</strong>зультат:<br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна<br />

и пом<strong>е</strong>стит<strong>е</strong> их на пусты<strong>е</strong> строчки.<br />

Каждый фрагм<strong>е</strong>нт можно использовать<br />

один раз. В басс<strong>е</strong>йн<strong>е</strong> <strong>е</strong>сть<br />

и лишни<strong>е</strong> фрагм<strong>е</strong>нты. Нужно<br />

получить программу, которая мож<strong>е</strong>т<br />

быть скомпилирована и запущ<strong>е</strong>на.<br />

Им<strong>е</strong>йт<strong>е</strong> в виду, что задача<br />

н<strong>е</strong> так проста, как каж<strong>е</strong>тся на п<strong>е</strong>рвый<br />

взгляд!<br />

int X = 0;<br />

String Poem<br />

while (<br />

if ( X < 1<br />

}<br />

i f ) {<br />

i f ( X == 1 ) {<br />

Таки<strong>е</strong> задачки иногда будут встр<strong>е</strong>чаться<br />

в книг<strong>е</strong>. Любит<strong>е</strong>ли логич<strong>е</strong>ских загадок<br />

должны их оц<strong>е</strong>нить. Но даж<strong>е</strong> <strong>е</strong>сли вы<br />

н<strong>е</strong> относит<strong>е</strong>сь к их числу, попробуйт<strong>е</strong><br />

найти р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>.<br />

if ( ) {<br />

Каж ды й ф р агм <strong>е</strong>нт<br />

кода м ож но и сп о л ь ­<br />

зо в ать то лько один<br />

раз!<br />

Poem = Poem + “<br />

Poem = Poem + “a<br />

Poem = Poem + “n“;<br />

Poem = Poem + “an“; ^<br />

X > 0<br />

X < 1<br />

X = X<br />

X > 1<br />

X = X<br />

X > 3<br />

X = X<br />

x < 4<br />

X = X<br />

MessageBox.Show(Poem);<br />

Poem = Poem + “noys<br />

Poem = Poem + “oise<br />

Poem = Poem + “ oyster'<br />

Poem = Poem + “annoys”;<br />

Poem = Poem + “noise”;<br />

112 глава 2 QinBem на с. 114


это вс<strong>е</strong>го лишь код<br />

аГниш ь! с КодаМи<br />

Ну что ж, пришло вр<strong>е</strong>мя посмотр<strong>е</strong>ть, как ж<strong>е</strong> правильно<br />

расположить магниты с фрагм<strong>е</strong>нтами кода, упавши<strong>е</strong><br />

на пол с холодильника.


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>буса<br />

<strong>е</strong> Ш <strong>е</strong> н и <strong>е</strong> ]=»<strong>е</strong>^с:а Б б а с с <strong>е</strong> й н <strong>е</strong><br />

Тр<strong>е</strong>бовалось расположить пр<strong>е</strong>дставл<strong>е</strong>нны<strong>е</strong><br />

в басс<strong>е</strong>йн<strong>е</strong> фрагм<strong>е</strong>нты кода на пустых<br />

строчках таким образом, чтобы в итог<strong>е</strong><br />

получилась работающая программа.<br />

i n t X = 0 ;<br />

S t r i n g Poem =<br />

w h i l e ( X < 4 ) {<br />

Poem = Poem + "a";<br />

i f ( X < 1 ) {<br />

Poem = Poem + "<br />

}<br />

Poem = Poem + "n";<br />

i f ( X > 1 ) {<br />

Poem = Poem + ” oyster";<br />

X = X + 2 ;<br />

}<br />

i f ( X = = 1 ) {<br />

Р<strong>е</strong>зультат:<br />

3 noise зппо^fs ап oyster<br />

ОК 1<br />

Poem = Poem + "noys<br />

i f ( X < 1 ) {<br />

}<br />

Poem = Poem + "olse<br />

X = X + 1;<br />

}<br />

MessageBox. Show(Poem);<br />

В и д и т<strong>е</strong> д р у го <strong>е</strong> р <strong>е</strong>ш <strong>е</strong>н и <strong>е</strong>?<br />

П ров<strong>е</strong>рьт<strong>е</strong> <strong>е</strong>го в ИСР<br />

и посм отр ит<strong>е</strong>, как оно<br />

работа<strong>е</strong>т!<br />

Подсказка: Сущ<strong>е</strong>ству<strong>е</strong>т <strong>е</strong>щ<strong>е</strong><br />

одно р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>.<br />

114 глава 2


3 обь<strong>е</strong>кш ы , 310 порядку ст|^ойс:я<br />

%<br />

Каждая програллма р<strong>е</strong>ша<strong>е</strong>т какую-либо пробл<strong>е</strong>му.<br />

П<strong>е</strong>р<strong>е</strong>д написани<strong>е</strong>м программы нужно ч<strong>е</strong>тко сформулировать, какую задачу<br />

она буд<strong>е</strong>т р<strong>е</strong>шать. Им<strong>е</strong>нно поэтому так пол<strong>е</strong>зны объ<strong>е</strong>кты. В<strong>е</strong>дь они позволяют<br />

структурировать код наибол<strong>е</strong><strong>е</strong> удобным образом. Вы ж<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> соср<strong>е</strong>доточиться<br />

на обдумывании пут<strong>е</strong>й р<strong>е</strong>ш<strong>е</strong>ния, так как вам н<strong>е</strong> нужно тратить<br />

вр<strong>е</strong>мя на написани<strong>е</strong> кода. Правильно<strong>е</strong> использовани<strong>е</strong> объ<strong>е</strong>ктов позволя<strong>е</strong>т<br />

получить интуитивно понятный код, который при н<strong>е</strong>обходимости можно<br />

л<strong>е</strong>гко отр<strong>е</strong>дактировать.


майк ищ<strong>е</strong>т работу<br />

Ч т о дума<strong>е</strong>т Майк о сбоих пробл<strong>е</strong>мах<br />

Майк —программист в поисках новой работы. Ему н<strong>е</strong> т<strong>е</strong>рпится показать,<br />

как хорошо он пиш<strong>е</strong>т программы на С#, но сначала <strong>е</strong>му нужно попасть на<br />

соб<strong>е</strong>с<strong>е</strong>довани<strong>е</strong>. А он опаздыва<strong>е</strong>т!<br />

О АЛайк обдумыва<strong>е</strong>т, каким маршрутом лучш <strong>е</strong> по<strong>е</strong>хать.<br />

Ч<strong>е</strong>р<strong>е</strong>з мост на 31-й улиц<strong>е</strong>,<br />

вп<strong>е</strong>р<strong>е</strong>д по Либ<strong>е</strong>рти-ав<strong>е</strong>ню,<br />

а потом ч<strong>е</strong>р<strong>е</strong>з Блумфилд.<br />

Майк выбира<strong>е</strong>м,<br />

маршрут.<br />

О Благодаря радио ДДайк узна<strong>е</strong>т о большой<br />

пробк<strong>е</strong>, и з -з а которой он м ож<strong>е</strong>т опоздать.<br />

каким<br />

ну>кио <strong>е</strong>хаиА!?-<br />

Это Фр<strong>е</strong>нк Лауди с<br />

информаци<strong>е</strong>й о пробках. Из-за тр<strong>е</strong>х<br />

столкнувшихся на Либ<strong>е</strong>рти-ав<strong>е</strong>ню<br />

машин остановилось движ<strong>е</strong>ни<strong>е</strong><br />

вплоть до 32-й улицы.<br />

О М айк придумы ва<strong>е</strong>т, как объ<strong>е</strong>хать пробку<br />

и попасть на соб<strong>е</strong>с<strong>е</strong>довани<strong>е</strong> вовр<strong>е</strong>для.<br />

8 р<strong>е</strong>зультат<strong>е</strong> появля<strong>е</strong>тся<br />

совс<strong>е</strong>м другой<br />

маршрут.<br />

Нич<strong>е</strong>го, я усп<strong>е</strong>ю<br />

вовр<strong>е</strong>мя, <strong>е</strong>сли св<strong>е</strong>рну<br />

на 28-<strong>е</strong> шосс<strong>е</strong>!<br />

О<br />

116 глава 3


объ<strong>е</strong>кты, по порядну стройся!<br />

Пробл<strong>е</strong>ма Майка с точки зр<strong>е</strong>ния набигационной сист<strong>е</strong>мы<br />

Майк использу<strong>е</strong>т навигационную сист<strong>е</strong>му GPS,<br />

которая помога<strong>е</strong>т <strong>е</strong>му в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ниях по городу.<br />

Диаграмма класса<br />

в программ<strong>е</strong> Мййкй.<br />

Вв<strong>е</strong>рху имя класса,<br />

внизу п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ны<br />

м<strong>е</strong>тоды. ^<br />

SetDestination("Fifth Ave & Penn Ave");<br />

string route;<br />

Р<strong>е</strong>зцльтат работы м <strong>е</strong>-<br />

тоЪа GetRouteO - строка<br />

route = GetRoute<br />

с марилрутом.<br />

Навигационная<br />

сист<strong>е</strong>ма г<strong>е</strong>н<strong>е</strong>риру<strong>е</strong>т<br />

маршрут, исходя из<br />

пункта назнач<strong>е</strong>ния.<br />

Navigator<br />

SetCurrentLocationO<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

V<br />

"Take 31st Street Bridge to Liberty Avenue to Bloomfield"<br />

Навигационная сист<strong>е</strong>ма<br />

узна<strong>е</strong>т, каких улиц<br />

сл<strong>е</strong>ду<strong>е</strong>т изб<strong>е</strong>гать. ^<br />

\1/<br />

ModifyRouteToAvoid("Liberty Ave");<br />

string route;<br />

route = GetRoute();<br />

"Take Route 28 to the Highland Park Bridge to Washington Blvd"<br />

^ М<strong>е</strong>тод GetRouteQ прокладыва<strong>е</strong>т<br />

маршрут, исключив улицы, цлииы.<br />

которы<strong>е</strong> Майк хоч<strong>е</strong>т объ<strong>е</strong>хать.<br />

Навигационная сист<strong>е</strong>ма Майка р<strong>е</strong>ша<strong>е</strong>т пробл<strong>е</strong>му<br />

с прокладкой маршрута так ж<strong>е</strong>, как это<br />

сд<strong>е</strong>лал бы он сам.<br />

дальш<strong>е</strong> ► 117


созда<strong>е</strong>м м<strong>е</strong>тоды и р<strong>е</strong>дактиру<strong>е</strong>м маршруты<br />

М<strong>е</strong>тоды прокладки и р<strong>е</strong>дактирования маршрутов<br />

Класс Navigator сод<strong>е</strong>ржит м<strong>е</strong>тоды, которы<strong>е</strong> выполняют вс<strong>е</strong> д<strong>е</strong>йствия. В отличи<strong>е</strong><br />

от уж<strong>е</strong> знакомых вам м<strong>е</strong>тодов button_Click () они р<strong>е</strong>шают другую задачу:<br />

прокладывают маршрут по городу. Им<strong>е</strong>нно поэтому Майк пом<strong>е</strong>стил эти м<strong>е</strong>тоды<br />

в <strong>е</strong>диный класс и присвоил <strong>е</strong>му имя Navigator.<br />

Для опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ния маршрута сначала вызыва<strong>е</strong>тся м<strong>е</strong>тод SetDestination (), указывающий<br />

кон<strong>е</strong>чную точку, зат<strong>е</strong>м прим<strong>е</strong>ня<strong>е</strong>тся м<strong>е</strong>тод GetRoute (), выводящий<br />

маршрут в вид<strong>е</strong> символьной строки. Если маршрут тр<strong>е</strong>бу<strong>е</strong>тся изм<strong>е</strong>нить, на помощь<br />

приходит м<strong>е</strong>тод ModifyRouteToAvoidO , позволяющий изб<strong>е</strong>жать опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных<br />

улиц. Зат<strong>е</strong>м м<strong>е</strong>тод GetRoute {) выводит новый вариант маршрута.<br />

class Navigator {<br />

Мйык выбира<strong>е</strong>т<br />

для м<strong>е</strong>тодов<br />

значимы<strong>е</strong> им<strong>е</strong>на.<br />

public void SetCurrentLocation(string locationName) {<br />

ptiblic void SetDestination (string destinationName) { , } ;<br />

public void ModifyRouteToAvoid(string streetName) { ... };<br />

public (string GetRoute 0 { ... };<br />

вм вровд<strong>е</strong>« 3 „ „ e " L ,<br />

М <strong>е</strong>тоды, возвращающи<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

string route =<br />

GetRoute {);<br />

М<strong>е</strong>тоды состоят из оп<strong>е</strong>раторов. Н<strong>е</strong>которы<strong>е</strong> из них выполняют вс<strong>е</strong> входящи<strong>е</strong><br />

оп<strong>е</strong>раторы и заканчивают работу. Други<strong>е</strong> ж<strong>е</strong> в о зв р а щ а ю т како<strong>е</strong>-то<br />

зн а ч <strong>е</strong> н и <strong>е</strong> . Это знач<strong>е</strong>ни<strong>е</strong> принадл<strong>е</strong>жит к опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нному типу (наприм<strong>е</strong>р,<br />

s t r i n g или in t) .<br />

Оп<strong>е</strong>ратор r e t u r n пр<strong>е</strong>рыва<strong>е</strong>т работу м<strong>е</strong>тода. Если м<strong>е</strong>тод н<strong>е</strong> возвраща<strong>е</strong>т<br />

знач<strong>е</strong>ния, тип возвраща<strong>е</strong>мого знач<strong>е</strong>ния объявля<strong>е</strong>тся как v o id , присутстви<strong>е</strong><br />

этого оп<strong>е</strong>ратора явля<strong>е</strong>тся н<strong>е</strong>обязат<strong>е</strong>льным. Но <strong>е</strong>сли м<strong>е</strong>тод возвра-<br />

Вот прим<strong>е</strong>р м<strong>е</strong>тода,<br />

возвращающ<strong>е</strong>го ^<br />

знач<strong>е</strong>ни<strong>е</strong> типа int.<br />

М<strong>е</strong>тод использу<strong>е</strong>т<br />

два парам<strong>е</strong>тра<br />

для вычисл<strong>е</strong>ния<br />

р<strong>е</strong>зультата,<br />

а зат<strong>е</strong>м при помощи<br />

оп<strong>е</strong>ратора return<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

X вызвавил<strong>е</strong>му <strong>е</strong>го<br />

ща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>, б<strong>е</strong>з оп<strong>е</strong>ратора r e t u r n н<strong>е</strong> обойтись. i / оп<strong>е</strong>ратору<br />

p u b l i c i n t M u ltip ly T w o N u m b ers(in t fir s tN u m b e r , i n t secondNum ber) {<br />

i n t r e s u l t = fir s tN u m b e r * secondN um ber;<br />

r e t u r n r e s u l t ;<br />

Оп<strong>е</strong>ратор вызыва<strong>е</strong>т м<strong>е</strong>тод, п<strong>е</strong>р<strong>е</strong>множающий два числа. Возвраща<strong>е</strong>мо<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> принадл<strong>е</strong>жит к типу int:<br />

i n t m y R esu lt = M u ltip lyT w oN u m b ers(3, 5 );<br />

В м <strong>е</strong> т о Э ь ! м о ж н о<br />

п о д с т а в л я т )^ н<strong>е</strong><br />

' только константы,<br />

но 1А п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ним.<br />

118 глава 3


объ<strong>е</strong>кты, по порядку стройся!<br />

КЛЮЧЕВЫЕ<br />

МОМЕНТЫ<br />

Классы состоят из м<strong>е</strong>тодов, которы<strong>е</strong>, в свою оч<strong>е</strong>р<strong>е</strong>дь, состоят из оп<strong>е</strong>раторов. Осмысл<strong>е</strong>нный выбор м<strong>е</strong>тодов позволя<strong>е</strong>т<br />

получить удобный для работы класс.<br />

Н<strong>е</strong>которы<strong>е</strong> м<strong>е</strong>тоды могут возвращать знач<strong>е</strong>ни<strong>е</strong>. Тип этого знач<strong>е</strong>ния нужно объявлять. Наприм<strong>е</strong>р, м<strong>е</strong>тод, объявл<strong>е</strong>нный<br />

как public int, возвраща<strong>е</strong>т ц<strong>е</strong>ло<strong>е</strong> число. Прим<strong>е</strong>р такого оп<strong>е</strong>ратора: return 37 ;<br />

М<strong>е</strong>тод, возвращающий знач<strong>е</strong>ни<strong>е</strong>, обязан включать в с<strong>е</strong>бя оп<strong>е</strong>ратор return. Если в объявл<strong>е</strong>нии м<strong>е</strong>тода указано<br />

public string, значит, оп<strong>е</strong>ратор return возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> типа string.<br />

Посл<strong>е</strong> оп<strong>е</strong>ратора return программа возвраща<strong>е</strong>т управл<strong>е</strong>ни<strong>е</strong> оп<strong>е</strong>ратору, вызывающ<strong>е</strong>му м<strong>е</strong>тод.<br />

М<strong>е</strong>тод, при объявл<strong>е</strong>нии которого было указано public void, н<strong>е</strong> возвраща<strong>е</strong>т знач<strong>е</strong>ния. Но оп<strong>е</strong>ратор return<br />

мож<strong>е</strong>т использоваться для пр<strong>е</strong>рывания такого м<strong>е</strong>тода: if (f inishedEarly) { return; }.<br />

Построим программу с использовани<strong>е</strong>м классоб<br />

Привяж<strong>е</strong>м форму к классу и сд<strong>е</strong>ла<strong>е</strong>м так, чтобы принадл<strong>е</strong>жащая форм<strong>е</strong><br />

кнопка вызывала м<strong>е</strong>тод этого класса.<br />

ф<br />

ар а ж н <strong>е</strong> н и <strong>е</strong><br />

^ Создайт<strong>е</strong> новый про<strong>е</strong>кт Windows Forms Application. В окн<strong>е</strong> Solution Explorer щ<strong>е</strong>лкнит<strong>е</strong><br />

правой кнопкой мыщи на им<strong>е</strong>ни про<strong>е</strong>кта и выб<strong>е</strong>рит<strong>е</strong> в появивш<strong>е</strong>мся м<strong>е</strong>ню команду<br />

A dd»C lass... Назовит<strong>е</strong> файл Talker.cs, при этом класс автоматич<strong>е</strong>ски получит имя<br />

Talker. В ИСР появится новая вкладка с им<strong>е</strong>н<strong>е</strong>м Talker.cs.<br />

Св<strong>е</strong>рху вставьт<strong>е</strong> строчку using System.Windows .Forms, a зат<strong>е</strong>м вв<strong>е</strong>дит<strong>е</strong> код самого класса:<br />

class Talker {<br />

p u b l i c s t a t i c i n t B l a h B l a h B l a h ( s t r i n g t h in g T o S a y ,<br />

{<br />

О п <strong>е</strong> р а т о р s t r i n g f i n a l S t r i n g =<br />

о5т?я6ля<strong>е</strong>т<br />

кх<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ннуи? f o r ( i n t co u n t = 1; co u n t


знакомство с объ<strong>е</strong>ктами<br />

*<br />

Что )к<strong>е</strong> мы только что построили?<br />

Новый класс сод<strong>е</strong>ржит м<strong>е</strong>тод с им<strong>е</strong>н<strong>е</strong>м B l a h B l a h B l a h {) и двумя парам<strong>е</strong>трами. П<strong>е</strong>рвый парам<strong>е</strong>тр<br />

—строка с произносимым т<strong>е</strong>кстом, а второй —колич<strong>е</strong>ство повтор<strong>е</strong>ний. Этот м<strong>е</strong>тод вызыва<strong>е</strong>т<br />

окно, в котором фраза повторя<strong>е</strong>тся указанно<strong>е</strong> колич<strong>е</strong>ство раз. М<strong>е</strong>тод возвраща<strong>е</strong>т длину<br />

строки. Ему сл<strong>е</strong>ду<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дать строку для парам<strong>е</strong>тра t h i n g T o S a y и число для парам<strong>е</strong>тра<br />

n u m b erO f T im e s . Указанны<strong>е</strong> знач<strong>е</strong>ния вводятся в поля формы, созданны<strong>е</strong> на основ<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния T e x t B o x и N u m ericU p D o w n .<br />

Добавим в про<strong>е</strong>кт форму, работающую с новым классом!<br />

Отр<strong>е</strong>дактируйт<strong>е</strong> свойство<br />

Text таким образом, чт о­<br />

бы в т<strong>е</strong>кстовом пол<strong>е</strong> по<br />

умолчанию появлялся т<strong>е</strong>кст<br />

«Hello!»<br />

Saythis:<br />

# oftimes: 3<br />

Hello!<br />

О<br />

Вот вн<strong>е</strong>шний вид формы.<br />

Дважды щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong>, чтобы добавить к н<strong>е</strong>й код, вызывающий м<strong>е</strong>тод B la h B la h B la h ()/.<br />

Он долж<strong>е</strong>н возвращать ц<strong>е</strong>ло<strong>е</strong> число 1<strong>е</strong>п:<br />

Свойству Minimum<br />


объ<strong>е</strong>кты, по порядку стройся!<br />

ІІд<strong>е</strong>я Майка<br />

Соб<strong>е</strong>с<strong>е</strong>довани<strong>е</strong> прошло зам<strong>е</strong>чат<strong>е</strong>льно!<br />

Но утр<strong>е</strong>нни<strong>е</strong> пробки заставили Майка задуматься<br />

об усов<strong>е</strong>рш<strong>е</strong>нствовании <strong>е</strong>го навигационной<br />

программы.<br />

Вот <strong>е</strong>сли бы сравнить<br />

н<strong>е</strong>сколько маршрутов и выбрать<br />

из них самый быстрый...<br />

Поч<strong>е</strong>му бы н<strong>е</strong> создать три класса Navigator...<br />

Майк м ож <strong>е</strong>т скопировать код класса N a v i g a t o r и вставить <strong>е</strong>го<br />

в други<strong>е</strong> классы. В р<strong>е</strong>зультат<strong>е</strong> программа получит возможность<br />

одновр<strong>е</strong>м<strong>е</strong>нно сохранять три маршрута.<br />

N a v ig a to r<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

N a v ig a to r2<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

Э т о диаграмма классов.<br />

В н<strong>е</strong>й п<strong>е</strong>р<strong>е</strong>числяются<br />

вс<strong>е</strong> 6кодяш,и<strong>е</strong> в класс<br />

м<strong>е</strong>тоды. Это наглядно<strong>е</strong><br />

пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong><br />

выполня<strong>е</strong>мых классом<br />

функций. .<br />

N a v ig a to rs<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

О (<br />

Получа<strong>е</strong>тся, что р<strong>е</strong>дактировать<br />

м<strong>е</strong>тод т<strong>е</strong>п<strong>е</strong>рь прид<strong>е</strong>тся три раза<br />

вм<strong>е</strong>сто одного?<br />

Им<strong>е</strong>нно так! Управл<strong>е</strong>ни<strong>е</strong> тр<strong>е</strong>м я копиями одного кода — н<strong>е</strong>простая зад а­<br />

ча. Но большинство задач, с которыми вам прид<strong>е</strong>тся столкнуться, тр<strong>е</strong>буют н<strong>е</strong>однократного<br />

использования одного эл<strong>е</strong>м<strong>е</strong>нта. В данном случа<strong>е</strong> это один маршрутизатор.<br />

Нужно сд<strong>е</strong>лать так, чтобы р<strong>е</strong>дактировани<strong>е</strong> любого фрагм<strong>е</strong>нта кода<br />

сопровождалось вн<strong>е</strong>с<strong>е</strong>ни<strong>е</strong>м аналогичных изм<strong>е</strong>н<strong>е</strong>ний во вс<strong>е</strong> <strong>е</strong>го копии.<br />

дальш<strong>е</strong> ► 121


про экз<strong>е</strong>мпляры<br />

Объ<strong>е</strong>кты как способ р<strong>е</strong>ш<strong>е</strong>ния пробл<strong>е</strong>мы<br />

Объ<strong>е</strong>ктами (objects) называются инструм<strong>е</strong>нты С#, позволяющи<strong>е</strong><br />

работать с набором одинаковых сущност<strong>е</strong>й. Им<strong>е</strong>нно<br />

благодаря им, один раз написав класс N a v i g a t o r , Майк смож<strong>е</strong>т<br />

использовать <strong>е</strong>го нужно<strong>е</strong> колич<strong>е</strong>ство раз.<br />

N a v ig a to r<br />

3 « « . «<br />

W3 C^WCKOM<br />

дд<strong>е</strong>1ляоЭоб.'<br />

SetCurrentLocationO<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

Д ля создания объ<strong>е</strong>кта достаточно<br />

клю ч<strong>е</strong>вого слова new и им<strong>е</strong>ни класса.<br />

i # ^<br />

' Для сравн<strong>е</strong>ния<br />

тр<strong>е</strong>х марилрутов<br />

Майк воспользу<strong>е</strong>тся<br />

тр<strong>е</strong>мя о6г>актами<br />

Navigator.<br />

Navigator navigatorl = m e v y Navigator () ;<br />

navigatorl.SetDestination("Fifth Ave & Penn Ave");<br />

string route;<br />

route =


объ<strong>е</strong>кты, по порядку стройся!<br />

Возьмит<strong>е</strong> класс и постройт<strong>е</strong> объ<strong>е</strong>кт<br />

Класс можно пр<strong>е</strong>дставить как копию объ<strong>е</strong>кта. Скаж<strong>е</strong>м, для постро<strong>е</strong>ния<br />

пяти одинаковых домов в котт<strong>е</strong>джном пос<strong>е</strong>лк<strong>е</strong> архит<strong>е</strong>ктору<br />

н<strong>е</strong> нужно рисовать пять одинаковых ч<strong>е</strong>рт<strong>е</strong>ж<strong>е</strong>й. Для выполн<strong>е</strong>ния<br />

задачи вполн<strong>е</strong> достаточно одного.<br />

Опр<strong>е</strong>д<strong>е</strong>ляя класс, вы опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<strong>е</strong><br />

и <strong>е</strong>го м<strong>е</strong>тоды, точно такж<strong>е</strong> как<br />

ч<strong>е</strong>рт<strong>е</strong>ж опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т вн<strong>е</strong>шний вид<br />

дома.<br />

'<br />

На основ<strong>е</strong> одного ч<strong>е</strong>рт<strong>е</strong>жа<br />

Можно построить сколько<br />

угодно домов, а из одного<br />

класса можно получить<br />

сколько угодно объ<strong>е</strong>ктов.<br />

Объ<strong>е</strong>кт б<strong>е</strong>р<strong>е</strong>т м<strong>е</strong>тоды из класса<br />

Оп<strong>е</strong>ратор new позволя<strong>е</strong>т создать произвольно<strong>е</strong> колич<strong>е</strong>ство объ<strong>е</strong>ктов<br />

одного класса. При этом вс<strong>е</strong> м<strong>е</strong>тоды исходного класса становятся<br />

частью объ<strong>е</strong>кта.<br />

Д о м<br />

ДатьКровО<br />

ВыраститьЛужайкуО<br />

ДоставитьПочтуО<br />

ПочиститьКанализациюО<br />

ЗаплатитьНалогО<br />

Сд<strong>е</strong>латьР<strong>е</strong>монтО<br />

дальш<strong>е</strong> > 123


объ<strong>е</strong>кты сов<strong>е</strong>рш<strong>е</strong>нствуют ваш код<br />

Экз<strong>е</strong>мпляры<br />

Вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты окна Toolbox являются классами: класс B u t t o n ,<br />

класс T e x t B o x , класс L a b e l и т. п. При п<strong>е</strong>р<strong>е</strong>таскивании<br />

на форму кнопки из окна Toolbox автоматич<strong>е</strong>ски созда<strong>е</strong>тся<br />

экз<strong>е</strong>мпляр класса B u t t o n , которому присваива<strong>е</strong>тся имя<br />

b u t t o n l . П<strong>е</strong>р<strong>е</strong>таскивани<strong>е</strong> второй кнопки приводит к появл<strong>е</strong>нию<br />

второго экз<strong>е</strong>мпляра с им<strong>е</strong>н<strong>е</strong>м b u t t o n 2 . Каждый экз<strong>е</strong>мпляр<br />

им<strong>е</strong><strong>е</strong>т собств<strong>е</strong>нны<strong>е</strong> свойства и м<strong>е</strong>тоды. Но при этом вс<strong>е</strong><br />

кнопки работают одинаково, так как они были созданы из одного<br />

класса.<br />

До: Так выглядим память<br />

компьют<strong>е</strong>ра п<strong>е</strong>р<strong>е</strong>д началом<br />

работы программы.<br />

' ^выполня<strong>е</strong>тся<br />

/ ^


объ<strong>е</strong>кты, по порядку стройся!<br />

Просто<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>!<br />

Майк придумал новую программу сравн<strong>е</strong>ния маршрутов, которая<br />

ищ<strong>е</strong>т кратчайший путь при помощи объ<strong>е</strong>ктов. Вот как<br />

она создавалась.<br />

с и / -- это сокращ<strong>е</strong>ни<strong>е</strong> от<br />

graphical User Interface<br />

{^р^сричсский иии/\срфсис<br />

пользоват<strong>е</strong>ля).<br />

Майк добавил к СТЛ т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong> —Ъ<strong>е</strong>хЬВох!, сод<strong>е</strong>ржащ<strong>е</strong><strong>е</strong> информацию о пункт<strong>е</strong> назнач<strong>е</strong>ния.<br />

Зат<strong>е</strong>м создал пол<strong>е</strong> textB ox2, для ввода названия улицы, которую н<strong>е</strong>льзя включать<br />

в маршрут; и пол<strong>е</strong> Ь<strong>е</strong>хЬВохЗ, сод<strong>е</strong>ржащ<strong>е</strong><strong>е</strong> информацию о <strong>е</strong>щ<strong>е</strong> одной улиц<strong>е</strong>, которую ж<strong>е</strong>лат<strong>е</strong>льно<br />

объ<strong>е</strong>хать.<br />

© О н создал о б ъ <strong>е</strong>к т N a v i g a t o r и указал пункт назнач <strong>е</strong>н ия.<br />

Это экз<strong>е</strong>мпляр<br />

класса Navigator.<br />

N a v ig a to r<br />

SetCurrentLocationO<br />

SetDestinationO<br />

IVIodifyRouteToAvoidO<br />

!\/1odifyRouteTolnclude()<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

s t r i n g d e s t i n a t i o n = t e x t B o x l . T e x t ;<br />

N a v i g a t o r n a v ig a t o r l = n ew N a v i g a t o r () ;<br />

n a v i g a t o r l . S e t D e s t i n a t i o n ( d e s t i n a t i o n ) ;<br />

r o u t e = n a v i g a t o r l . G e t R o u t e () ;<br />

O h добав и л в т о р о й о бъ <strong>е</strong>к т N a v i g a t o r с и м <strong>е</strong>н <strong>е</strong>м n a v i g a t o r 2<br />

и вызвал м <strong>е</strong>то д S e t D e s t i n a t i o n O эт о г о о бъ <strong>е</strong>к та для задан<br />

и я пункта назн ач <strong>е</strong>н и я, п о сл <strong>е</strong> ч <strong>е</strong>го вызвал м <strong>е</strong>то д M o d i f y ­<br />

R o u t e T o A v o id () (Р <strong>е</strong>дакти ровать и зб <strong>е</strong>га <strong>е</strong>м ы <strong>е</strong> улицы ).<br />

Тр<strong>е</strong>тий объ<strong>е</strong>кт N a v i g a t o r называ<strong>е</strong>тся n a v i g a t o r s . Майк указал<br />

пункт назнач<strong>е</strong>ния и вызвал м<strong>е</strong>тод M o d i f y R o u t e T o l n c l u d e O<br />

(Р<strong>е</strong>дактировать включа<strong>е</strong>мы<strong>е</strong> в маршрут улицы)<br />

J<br />

„ „ М string-<br />

vigotorl'<br />

5,6 км<br />

Т<strong>е</strong>п<strong>е</strong>рь Майк мож<strong>е</strong>т вызвать общий для вс<strong>е</strong>х объ<strong>е</strong>ктов м<strong>е</strong>тод<br />

T o t a l D i s t a n c e O (Общ<strong>е</strong><strong>е</strong> расстояни<strong>е</strong>) и опр<strong>е</strong>д<strong>е</strong>лить самый<br />

короткий маршрут. И для этого <strong>е</strong>му понадобился один фрагм<strong>е</strong>нт<br />

кода, а н<strong>е</strong> три!<br />

Создани<strong>е</strong> нового<br />

объ<strong>е</strong>кта на основ<strong>е</strong><br />

класса называ<strong>е</strong>тся<br />

создани<strong>е</strong>м экз<strong>е</strong>мпляра<br />

класса.<br />

дальш<strong>е</strong> У 125


н<strong>е</strong>множко мал<strong>е</strong>ньких с<strong>е</strong>кр<strong>е</strong>тов<br />

Эй, подождит<strong>е</strong>-ка! Данной вами<br />

информации н<strong>е</strong>достаточно для того,<br />

чтобы написать навигационную<br />

программу!<br />

Т<strong>е</strong>ория U практика<br />

Э т о д <strong>е</strong> й с т в и т <strong>е</strong> л ь н о т а к . Программа постро<strong>е</strong>ния маршрутов оч<strong>е</strong>нь<br />

сложна. Но сложны<strong>е</strong> программы работают по тому ж<strong>е</strong> принципу, что<br />

и просты<strong>е</strong>. Навигационную программу Майка мы прив<strong>е</strong>ли только<br />

как прим<strong>е</strong>р использования объ<strong>е</strong>ктов на практик<strong>е</strong>.<br />

Наша книга постро<strong>е</strong>на по сл<strong>е</strong>дуюгц<strong>е</strong>му принципу. Вводится н<strong>е</strong>ко<strong>е</strong> поняти<strong>е</strong>,<br />

для д<strong>е</strong>монстрации которого используются картинки и н<strong>е</strong>больши<strong>е</strong><br />

фрагм<strong>е</strong>нты кода. На данном этап<strong>е</strong> вы должны вс<strong>е</strong>го лишь попять<br />

новую информацию. Проц<strong>е</strong>дура написания рабочих программ буд<strong>е</strong>т<br />

рассматриваться поздн<strong>е</strong><strong>е</strong>.<br />

House mapleDrivellS = n e w House О ;<br />

Знакомясь с новыми понятиями<br />

(наприм<strong>е</strong>р, с объ<strong>е</strong>ктами), внимат<strong>е</strong>льно<br />

смотрит<strong>е</strong> на картинки<br />

и код.<br />

У вас буд<strong>е</strong>т достаточно возможност<strong>е</strong>й прим<strong>е</strong>нить получ<strong>е</strong>нны<strong>е</strong> знания<br />

на практик<strong>е</strong>. Иногда это выполн<strong>е</strong>ни<strong>е</strong> письм<strong>е</strong>нных упражн<strong>е</strong>ний, одно<br />

из которых вы найд<strong>е</strong>т<strong>е</strong> на сл<strong>е</strong>дуюш,<strong>е</strong>й страниц<strong>е</strong>. В других случаях вам<br />

сразу буд<strong>е</strong>т пр<strong>е</strong>длож<strong>е</strong>но написать код. Такая комбинации т<strong>е</strong>ории с<br />

практикой явля<strong>е</strong>тся самым эфф<strong>е</strong>ктивным способом запоминания новой<br />

информации.<br />

Упра)княясь В написании кодов...<br />

...ж<strong>е</strong>лат<strong>е</strong>льно помнить сл<strong>е</strong>дуюш;<strong>е</strong><strong>е</strong>:<br />

★<br />

★<br />

★<br />

Сд<strong>е</strong>лать оп<strong>е</strong>чатку оч<strong>е</strong>нь л<strong>е</strong>гко. При этом даж<strong>е</strong> одна н<strong>е</strong>закрытая<br />

скобка явля<strong>е</strong>тся пр<strong>е</strong>пятстви<strong>е</strong>м к постро<strong>е</strong>нию программы.<br />

Лучш<strong>е</strong> подсмотр<strong>е</strong>ть р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>, ч<strong>е</strong>м долго мучиться. Муч<strong>е</strong>ния отбивают<br />

ж<strong>е</strong>лани<strong>е</strong> учиться.<br />

Код, который вы найд<strong>е</strong>т<strong>е</strong> в этой книг<strong>е</strong>, прот<strong>е</strong>стирован и работа<strong>е</strong>т<br />

в Visual Studio 2010! Но от оп<strong>е</strong>чаток никто н<strong>е</strong> застрахован<br />

(можно п<strong>е</strong>р<strong>е</strong>путать 1 и букву L нижн<strong>е</strong>го р<strong>е</strong>гистра).<br />

Если у вас сложности<br />

с выполн<strong>е</strong>ни<strong>е</strong>м<br />

упражн<strong>е</strong>ния,<br />

можно сразу посмотр<strong>е</strong>ть<br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>.<br />

Его можно даж<strong>е</strong><br />

скачать с сайта<br />

Head first Labs.<br />

126 глава 3


Г<br />

в руку карандаш<br />

объ<strong>е</strong>кты, по порядку стройся!<br />

Попробуйт<strong>е</strong> всл<strong>е</strong>д за Майком написать код для объ<strong>е</strong>ктов<br />

N a v ig a to r И вызова ИХ м<strong>е</strong>тодов.<br />

s t r i n g d e s t i n a t i o n = t e x t B o x l . T e x t ;<br />

s t r i n g r o u t e 2 S t r e e t T o A v o i d = t e x t B o x 2 . T e x t ;<br />

s t r i n g r o u t e 3 S t r e e t T o I n c l u d e = t e x t B o x 3 . T e x t ;<br />

N a v ig a to r n a v i g a t o r l = new N a v i g a t o r () ;<br />

n a v i g a t o r l . S e t D e s t i n a t i o n ( d e s t i n a t i o n ) ;<br />

i n t d i s t a n c e l = n a v i g a t o r l . T o t a l D i s t a n c e {);<br />

Зд<strong>е</strong>сь Майк задавал пункт<br />

назнач<strong>е</strong>ния и улицы,<br />

которых сл<strong>е</strong>ду<strong>е</strong>т изб<strong>е</strong>гать.<br />

А зд<strong>е</strong>сь MW созда<strong>е</strong>м объ<strong>е</strong>кт<br />

n a v i g a to r , указыва<strong>е</strong>м п у н к т<br />

назнач<strong>е</strong>ния и опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>м<br />

расстояни<strong>е</strong>.<br />

. Создайт<strong>е</strong> объ<strong>е</strong>кт navigator2, укажит<strong>е</strong> пункт назнач<strong>е</strong>ния, вызовит<strong>е</strong> м<strong>е</strong>тод ModifyRouteToAvoidO,'^<br />

а зат<strong>е</strong>м воспользуйт<strong>е</strong>сь м<strong>е</strong>тодом TotalDistanceO для вычисл<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной distance2.<br />

Navigator navigator2 =<br />

navigator2.<br />

navigator2.<br />

int distance2 =<br />

^2.CoздaйтeoбъeктnavigatorЗ,yкaжитeпyнктнaзнaчeния,вызoвитeмeтoд^ЯodifyRouteToincludeO,~*<br />

a зат<strong>е</strong>м воспользуйт<strong>е</strong>сь м<strong>е</strong>тодом TotalDistanceO ДЛЯ вычисл<strong>е</strong>ния ц<strong>е</strong>лой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной distances.<br />

L<br />

_<br />

Встро<strong>е</strong>нный в .NET Framework м<strong>е</strong>тод Math.MmQ<br />

сравнива<strong>е</strong>т два числа и возвраща<strong>е</strong>т м<strong>е</strong>ньш<strong>е</strong><strong>е</strong>. Им<strong>е</strong>нно<br />

с <strong>е</strong>го помощью Майк наш<strong>е</strong>л самый короткий путь.<br />

i n t s h o r t e s t D is t a n c e = M a t h .M in ( d is t a n c e l, M a t h .M in ( d is t a n c e s , d i s t a n c e s ) ) ;<br />

дальш<strong>е</strong> > 127


слово static<br />

|Л о зьм и В руку карандаш<br />

п<br />

6Ш6НИ6<br />

Вот как правильно создать объ<strong>е</strong>кты N a v ig a to r и вызвать их<br />

м<strong>е</strong>тоды.<br />

s t r i n g d e s t i n a t i o n = t e x t B o x l . T e x t ;<br />

З д <strong>е</strong> с ь И а й к з а д а в а л<br />

s t r i n g r o u t e 2 S t r e e t T o A v o i d = t e x t B o x 2 . T e x t ;<br />

^ \<br />

н а зн а ч <strong>е</strong> н и я<br />

M у л и ц ы , к о т о р ы х<br />

s t r i n g r o u t e S S t r e e t T o I n c l u d e = t e x t B o x 3 . T e x t ; j с л <strong>е</strong> д у <strong>е</strong> т и з б <strong>е</strong> г а т ь .<br />

N a v ig a to r n a v i g a t o r l = new N a v ig a to r () ; ^ ^ СОзЭа<strong>е</strong>М о б ш к т<br />

n a v i g a t o r l . S e t D e s t i n a t i o n ( d e s t i n a t i o n ) ;<br />

^ a .v ig a to r , у к а з ы в а <strong>е</strong> м п у н к т<br />

i n t d i s t a n c e l = n a v i g a t o r l .T o t a lD is t a n c e 0 ; ^ н а з н а ч <strong>е</strong> н и я и о п р <strong>е</strong> д <strong>е</strong> л я <strong>е</strong> м<br />

р а с с т о я н и <strong>е</strong> .<br />

1. Создайт<strong>е</strong> объ<strong>е</strong>кт navigator2, укажит<strong>е</strong> пункт назнач<strong>е</strong>ния, вызовит<strong>е</strong> м<strong>е</strong>тод ModifyRouteToAvoidO,<br />

а зат<strong>е</strong>м воспользуйт<strong>е</strong>сь м<strong>е</strong>тодом TotalDistanceO Для вычисл<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной distance2.<br />

Navigator navigator2 =<br />

new NaviyatorQ<br />

navigator2.<br />

navigator2.<br />

SetDestination(destination);<br />

ModifyRouteToAvoid(routeZStreetToAvoid);<br />

int distance2 =<br />

navigatorZ.TotalDi$tanceQ;<br />

*~2.CoздaйтeoбъeктnavlgatorЗ,yкaжитeпyнкт назнач<strong>е</strong>ния, вызовит<strong>е</strong>м<strong>е</strong>тод ModifyRouteTolncludeO,"^<br />

a зат<strong>е</strong>м воспользуйт<strong>е</strong>сь м<strong>е</strong>тодом TotalDistanceO для вычисл<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной distances.<br />

navigator3.SetDestination(destination);<br />

navigator5.ModifyRouteTolnc!ude(route3StreetTolnclude);<br />

int distances = navigators.TotalDistanceQ;<br />

Встро<strong>е</strong>нный 6 .NET Framework м<strong>е</strong>тод Matk.MinQ<br />

сравнива<strong>е</strong>т два числа и возвраш,а<strong>е</strong>т м<strong>е</strong>ньш<strong>е</strong><strong>е</strong>.<br />

Им<strong>е</strong>нно с <strong>е</strong>го помощью Майк наш<strong>е</strong>л самый<br />

короткий путь.<br />

i n t s h o r t e s t D is t a n c e = M a t h .M in ( d is t a n c e l, M ath .M in ( d i s t a n c e s , d i s t a n c e s ) )<br />

128 глава 3


объ<strong>е</strong>кты, по порядку стройся!<br />

О<br />

Я написал уж<strong>е</strong> н<strong>е</strong>сколько новых классов, но ни разу<br />

н<strong>е</strong> воспользовался ключ<strong>е</strong>вым словом new! Получа<strong>е</strong>тся,<br />

я могу вызывать м<strong>е</strong>тоды, н<strong>е</strong> создавая объ<strong>е</strong>ктов?<br />

Д а! И им <strong>е</strong>нно поэтому в м<strong>е</strong>тодах использовалось клю ч<strong>е</strong>во<strong>е</strong> слово s t a t i c .<br />

Ещ<strong>е</strong> раз посмотрим на объявл<strong>е</strong>ни<strong>е</strong> класса T alk er:<br />

c l a s s T a lk e r<br />

{<br />

p u b l i c s t a t i c i n t B la h B la h B la h ( s t r in g th in g T o S a y ,<br />

{<br />

s t r i n g f i n a l S t r i n g =<br />

i n t num berOfTim es)<br />

При вызов<strong>е</strong> м<strong>е</strong>тода н<strong>е</strong> создавался новы й экз<strong>е</strong>мпляр T a l k e r . Вы написали только:<br />

T a lk e r .B la h B la h B la h (" H e llo h e l l o h e l l o " , 5 ) ;<br />

Им<strong>е</strong>нно так вызываются с т а т и ч <strong>е</strong> с к и <strong>е</strong> м<strong>е</strong>тоды, с которыми вы работали до сих пор.<br />

Если убрать модификатор s t a t i c из объявл<strong>е</strong>ния м<strong>е</strong>тода B l a h B l a h B l a h (), вызов<br />

м<strong>е</strong>тода окаж<strong>е</strong>тся уж<strong>е</strong> н<strong>е</strong>возмож<strong>е</strong>н б<strong>е</strong>з создания экз<strong>е</strong>мпляра T a l k e r . Впроч<strong>е</strong>м, это<br />

<strong>е</strong>динств<strong>е</strong>нно<strong>е</strong> отличи<strong>е</strong> статич<strong>е</strong>ских м<strong>е</strong>тодов. Вы мож<strong>е</strong>т<strong>е</strong> п<strong>е</strong>р<strong>е</strong>давать им парам<strong>е</strong>тры,<br />

они возвращают знач<strong>е</strong>ния и принадл<strong>е</strong>жат опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным классам.<br />

Модификатором s t a t i c можно отм<strong>е</strong>тить ц<strong>е</strong>лый класс. Вс<strong>е</strong> входящи<strong>е</strong> в этот класс<br />

м<strong>е</strong>тоды такж<strong>е</strong> должны бы ть с т а т и ч <strong>е</strong> с к и м и . Добавив в статич<strong>е</strong>ский класс н<strong>е</strong>статич<strong>е</strong>ский<br />

м<strong>е</strong>тод, вы сд<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> компиляцию н<strong>е</strong>возможной.<br />

Чаап°<br />

'^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Б огц росьі<br />

Слово «статич<strong>е</strong>ский» ассоцииру<strong>е</strong>тся у м<strong>е</strong>ня с в<strong>е</strong>щами,<br />

которы<strong>е</strong> н<strong>е</strong> м<strong>е</strong>няются. Означа<strong>е</strong>т ли это, что н<strong>е</strong>статич<strong>е</strong>ски<strong>е</strong><br />

м<strong>е</strong>тоды могут м<strong>е</strong>няться, а статич<strong>е</strong>ски<strong>е</strong> н<strong>е</strong>т?<br />

0 ; Н<strong>е</strong>т. Единств<strong>е</strong>нным отличи<strong>е</strong>м статич<strong>е</strong>ского м<strong>е</strong>тода от<br />

н<strong>е</strong>статич<strong>е</strong>ского явля<strong>е</strong>тся н<strong>е</strong>возможность создавать <strong>е</strong>го экз<strong>е</strong>мпляры.<br />

Слово «статич<strong>е</strong>ский» в данном случа<strong>е</strong> н<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т<br />

воспринимать слишком буквально.<br />

То <strong>е</strong>сть я н<strong>е</strong> смогу пользоваться классом, н<strong>е</strong> создав<br />

экз<strong>е</strong>мпляр объ<strong>е</strong>кта?<br />

0 ; Создани<strong>е</strong> экз<strong>е</strong>мпляров явля<strong>е</strong>тся обязат<strong>е</strong>льным услови<strong>е</strong>м<br />

для работы с н<strong>е</strong>статич<strong>е</strong>скими классами. Для статич<strong>е</strong>ских<br />

классов это н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся.<br />

Поч<strong>е</strong>му н<strong>е</strong> сд<strong>е</strong>лать статич<strong>е</strong>скими вс<strong>е</strong> м<strong>е</strong>тоды?<br />

0 1 При наличии объ<strong>е</strong>ктов, отсл<strong>е</strong>живающих данны<strong>е</strong>, наприм<strong>е</strong>р,<br />

экз<strong>е</strong>мпляров класса N a v ig a to r , каждый из которых<br />

отсл<strong>е</strong>живал свой маршрут, для работы с этими данными можно<br />

использовать собств<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды экз<strong>е</strong>мпляра. Скаж<strong>е</strong>м,<br />

при вызов<strong>е</strong> м<strong>е</strong>тода M od ifyR ou teT oA void () для экз<strong>е</strong>мпляра<br />

n a v i g a t o r s м<strong>е</strong>нялся только маршрут ном<strong>е</strong>р два.<br />

На маршруты экз<strong>е</strong>мпляров n a v i g a t o r l и n a v ig a t o r s<br />

эта проц<strong>е</strong>дура никак н<strong>е</strong> влияла. Им<strong>е</strong>нно поэтому программа<br />

Майка могла работать с тр<strong>е</strong>мя маршрутами одновр<strong>е</strong>м<strong>е</strong>нно.<br />

• А как им<strong>е</strong>нно экз<strong>е</strong>мпляры отсл<strong>е</strong>живают данны<strong>е</strong>?<br />

О<br />

; П<strong>е</strong>р<strong>е</strong>в<strong>е</strong>рнит<strong>е</strong> страницу и узна<strong>е</strong>т<strong>е</strong>!<br />

дальш<strong>е</strong> * 129


как д<strong>е</strong>ла у объ<strong>е</strong>ктов<br />

Поля<br />

Р<strong>е</strong>дактировани<strong>е</strong> располож<strong>е</strong>нного т<strong>е</strong>кста на кнопк<strong>е</strong> осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

при помощи свойства T e x t . При вн<strong>е</strong>с<strong>е</strong>нии подобных изм<strong>е</strong>н<strong>е</strong>ний<br />

в конструктор добавля<strong>е</strong>тся сл<strong>е</strong>дующий код:<br />

b u t t o n l . T e x t = " Т <strong>е</strong> к с т д л я к н о п к и " ;<br />

Как вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, b u t t o n l —это экз<strong>е</strong>мпляр класса B u tto n .' Код<br />

ж<strong>е</strong> р<strong>е</strong>дактиру<strong>е</strong>т пол<strong>е</strong> этого экз<strong>е</strong>мпляра. На диаграмм<strong>е</strong> классов список<br />

пол<strong>е</strong>й находится св<strong>е</strong>рху, а список м<strong>е</strong>тодов —снизу.<br />

Т<strong>е</strong>хнич<strong>е</strong>ски вы<br />

зада<strong>е</strong>т<strong>е</strong> свойстЯп<br />

Свойс\тва оч<strong>е</strong>нь<br />

покожи на поля^<br />

но об этом мы<br />

поговорим чуть<br />

позж<strong>е</strong>.<br />

Св<strong>е</strong>рху на диаграмм<strong>е</strong><br />

классов находится список<br />

пол<strong>е</strong>й. Экз<strong>е</strong>мпляры<br />

класса используют их<br />

для отсл<strong>е</strong>живания сво<strong>е</strong>го<br />

состояния.<br />

Эта линия<br />

отд<strong>е</strong>ля<strong>е</strong>т поля<br />

от м<strong>е</strong>тодов.<br />

М<strong>е</strong>тод — это то, что объ<strong>е</strong>кт д<strong>е</strong>ла<strong>е</strong>т. Пол<strong>е</strong> — это то, что объ<strong>е</strong>кт зна<strong>е</strong>т^.<br />

в р<strong>е</strong>зультат<strong>е</strong> создания Майком тр<strong>е</strong>х экз<strong>е</strong>мпляров класса N a v i g a t o r <strong>е</strong>го программа создала три<br />

объ<strong>е</strong>кта, каждый из которых отсл<strong>е</strong>жива<strong>е</strong>т свой маршрут. При вызов<strong>е</strong> м<strong>е</strong>тода S e t D e s t i n a t i o n ()<br />

для экз<strong>е</strong>мпляра n a v i g a t o r 2 пункт назнач<strong>е</strong>ния указыва<strong>е</strong>тся только для этого экз<strong>е</strong>мпляра. Он никак<br />

н<strong>е</strong> влия<strong>е</strong>т на экз<strong>е</strong>мпляры n a v i g a t o r l и n a v i g a t o r 3 .<br />

Destination<br />

Route<br />

N a v ig a to r<br />

SetCurrentLocationO<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

Каждый из экз<strong>е</strong>мпляров<br />

Navigator зна<strong>е</strong>т свой пункт<br />

назнач<strong>е</strong>ния и свой маршрут.<br />

Объ<strong>е</strong>кт Navigator позволя<strong>е</strong>т<br />

указывать пункт назнач<strong>е</strong>ния,<br />

р<strong>е</strong>дактировать возможный<br />

маршрут и получать<br />

информацию об этом<br />

маршрут<strong>е</strong>.<br />

Пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>кта опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся <strong>е</strong>го<br />

м<strong>е</strong>тодами, поля используются для отсл<strong>е</strong>живания<br />

<strong>е</strong>го состояния.<br />

130 глава 3


объ<strong>е</strong>кты, по порядку стройся!<br />

Созда<strong>е</strong>м эЬ<strong>е</strong>мкдяры!<br />

Д ля доб а в л <strong>е</strong>н и я п о л <strong>е</strong>й д о ст а т о ч н о объ я вить<br />

п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы <strong>е</strong> вн<strong>е</strong> м <strong>е</strong>тодов. Так, вс<strong>е</strong> экз<strong>е</strong>мпля- c l a s s C lo w n {<br />

M em odL<br />

ры будут им <strong>е</strong>ть св о и к оп и и эт и х п <strong>е</strong>р <strong>е</strong>м <strong>е</strong>н н ы х . s t r i n g Nam e;<br />

I<br />

p u b l i c i n t H e i g h t ;<br />

p u b l i c v o i d T a l k A b o u t Y o u r s e l f () {<br />

M e s s a g e B o x . S h o w ( "My nam e i s "<br />

+ Name + " a n d I 'm "<br />

+ H e i g h t + " i n c h e s t a l l . " ) ;<br />

При создании экз<strong>е</strong>мпляра,<br />

н<strong>е</strong> использиймя ключ<strong>е</strong>во<strong>е</strong><br />

слово static ни в объявл<strong>е</strong>нш<br />

класса, ни в объявл<strong>е</strong>нии<br />

м<strong>е</strong>тода.<br />

^Возьми в руку карандаш<br />

C lo w n o n e C lo w n = n ew C lo w n ( ) ;<br />

o n e C lo w n .N a m e = " B o f f o " ;<br />

Оп<strong>е</strong>ратор *= означа<strong>е</strong>т,, что<br />

парам<strong>е</strong>тр, стояиА,ий справа от<br />

/" оп<strong>е</strong>ратора, нужно умножить<br />

на парам<strong>е</strong>тр, стоящий сл<strong>е</strong>ва.<br />

м/<br />

Клоуны рассказывают о с<strong>е</strong>б<strong>е</strong> при помощи м<strong>е</strong>тода<br />

Та1кАЬои1Уоигзб1^ Они называют имя и рост. Напишит<strong>е</strong>,<br />

каки<strong>е</strong> сообщ<strong>е</strong>ния будут сод<strong>е</strong>ржать всплывающи<strong>е</strong> окна.<br />

o n e C l o w n .H e i g h t = 1 4 ;<br />

o n e C lo w n .T a lk A b o u tY o u r s e lf( ) ;<br />

«М<strong>е</strong>ня зовут , мои рост .дюймов»<br />

C lo w n a n o t h e r C l o w n = n ew C l o w n ( ) ;<br />

a n o t h e r C lo w n .N a m e = " B i f f " ;<br />

a n o t h e r C l o w n .H e i g h t = 1 6 ;<br />

a n o th e r C lo w n .T a lk A b o u t Y o u r s e lf( ) ;<br />

«М<strong>е</strong>ня зовут. , мои рост .дюймов»<br />

C lo w n c lo w n s = n ew C lo w n { ) ;<br />

c lo w n 3 .N a m e = a n o t h e r C lo w n .N a m e ;<br />

c l o w n 3 . H e i g h t = o n e C l o w n .H e i g h t - 3^<br />

c lo w n 3 .T a lk A b o u t Y o u r s e lf () ;<br />

«М<strong>е</strong>ня зовут , мой рост .дюймов»<br />

a n o t h e r C l o w n .H e i g h t *= 2 ;<br />

a n o th e r C lo w n .T a lk A b o u tY o u r s e lf 0 ;<br />

«М<strong>е</strong>ня зовут , мои рост. дюймов»<br />

дальш<strong>е</strong> > 131


складыва<strong>е</strong>м объ<strong>е</strong>кты в кучу<br />

Спасибо за память<br />

Создава<strong>е</strong>мы<strong>е</strong> объ<strong>е</strong>кты находятся в так называ<strong>е</strong>мой куч<strong>е</strong><br />

(heap) — области динамич<strong>е</strong>ской памяти, выд<strong>е</strong>ля<strong>е</strong>мой на<br />

стадии исполн<strong>е</strong>ния программы. Прим<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> оп<strong>е</strong>ратора<br />

new автоматич<strong>е</strong>ски р<strong>е</strong>з<strong>е</strong>рвиру<strong>е</strong>т м<strong>е</strong>сто в памяти под хран<strong>е</strong>ни<strong>е</strong><br />

данных. /<br />

Вот так выглядит куча до<br />

начала работы программы.<br />

Дд, она д<strong>е</strong>йствит<strong>е</strong>льно<br />

пуста.<br />

Внимат<strong>е</strong>льно посмотрим на происходяи^<strong>е</strong><strong>е</strong> зд<strong>е</strong>сь<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

C lo w n o n e C lo w n S ^ ^ e w C lo w n ()<br />

o n e C lo w n .N a m e = " B S tfn -<br />

o n e C l o w n .H e i g h t = 1 4 ;<br />

o n e C lo w n .T a lk A b o u tY o u r s e lf() ;<br />

Вот как нужно было заполнить проб<strong>е</strong>лы в т<strong>е</strong>кст<strong>е</strong>.<br />

Оп<strong>е</strong>раторы jjew создают<br />

экз<strong>е</strong>мпляр?« класса Clown,<br />

р<strong>е</strong>з<strong>е</strong>рвируя участки памяти и<br />

заполняя их данными об объ<strong>е</strong>кт<strong>е</strong><br />

л<br />

«М<strong>е</strong>ня зовут Boffo , мой рост 3-4 дюймов^<br />

C lo w n a n o t h e r C l o w n = ( n e w C lo w n ( ) ;<br />

a n o t h e r C lo w n .N a m e =<br />

" B i f f " T<br />

a n o t h e r C l o w n .H e i g h t = 1 6 ;<br />

a n o th e r C lo w n .T a lk A b o u tY o u r s e lf 0 ;<br />

«М<strong>е</strong>ня зовут Biff , мой рост дюймову<br />

---- .<br />

C lo w n c lo w n 3 = m ew C lo w n ( ) ;<br />

c lo w n B .N a m e = an o B H S F C T o ra .N a m e;<br />

c l o w n 3 . H e i g h t = o n e C l o w n .H e i g h t - 3 ;<br />

c lo w n 3 .T a lk A b o u t Y o u r s e lf ( ) ;<br />

«М<strong>е</strong>ня зовут Biff _мой рост 3-3- дюймов»<br />

a n o t h e r C l o w n .H e i g h t *= 2 ;<br />

a n o th e r C lo w n .T a lk A b o u t Y o u r s e lf( ) ;<br />

«М<strong>е</strong>ня зовут Biff . мой РОСТ S2 дюйма».<br />

Новы<strong>е</strong> объ<strong>е</strong>кты добавляются в кучу — динамич<strong>е</strong>ски рас<br />

пр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>мую память.<br />

132 глава 3


Ч т о происходит 6 памяти программы<br />

объ<strong>е</strong>кты, по порядку стройся!<br />

Это экз<strong>е</strong>мпляр<br />

класса Clown.<br />

Программа созда<strong>е</strong>т новый экз<strong>е</strong>мпляр класса C low n:<br />

C lo w n m y l n s t a n c e = n ew C lo w n ( ) ;<br />

В выраж<strong>е</strong>нии использованы два оп<strong>е</strong>ратора. П<strong>е</strong>рвый<br />

объявля<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную типа C lo w n (C lo w n<br />

m y l n s t a n c e ; ) . Второй созда<strong>е</strong>т новый объ<strong>е</strong>кт и<br />

присваива<strong>е</strong>т <strong>е</strong>го только что созданной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

( m y l n s t a n c e = n e w C lo w n О ; ) . Вот как выглядит<br />

куча посл<strong>е</strong> выполн<strong>е</strong>ния каждого из оп<strong>е</strong>раторов:<br />

C lo w n o n e C lo w n = n ew C lo w n о<br />

o n e C lo w n .N a m e = " B o f f o " ;<br />

o n e C lo w n . H e i g h t = 1 4 ;<br />

vvOA^o<br />

n e C l o w n . T a l k A b o u t Y o u r s e l f ( ) ;<br />

^Ь<strong>е</strong>кт<br />

C lo w n a n o t h e r C l o w n = n ew C lo w n ()<br />

a n o t h e r C lo w n .N a m e = " B i f f " ;<br />

a n o t h e r C l o w n .H e i g h t = 1 6 ;<br />

'•a n o th erC lo w n .T a lk A b o u tY o u rself {)<br />

Оп<strong>е</strong>раторы<br />

создают второй<br />

объ<strong>е</strong>кт и присваивают<br />

<strong>е</strong>му<br />

данны<strong>е</strong>.<br />

о<br />

C lo w n c lo w n 3 = n e w C lo w n 0 ;<br />

c lo w n 3 .N a m e = a n o t h e r C lo w n .N a m e ;<br />

c l o w n 3 . H e i g h t = o n e C l o w n .H e i g h t - 3<br />

- c lo w n s .T a lk A b o u tY o u r s e lf();<br />

a n o t h e r C l o w n . H e i g h t *= 2 ;<br />

■ 'a n o th erC lo w n .T a lk A b o u tY o u rself () ;<br />

Так как команда new н<strong>е</strong><br />

использу<strong>е</strong>тся, новый объ<strong>е</strong>кт<br />

н<strong>е</strong> созда<strong>е</strong>тся. Р<strong>е</strong>дактиру<strong>е</strong>тся<br />

только информация,<br />

которая уж<strong>е</strong> ^<br />

им<strong>е</strong><strong>е</strong>тся о памяти.<br />

дальш<strong>е</strong> > 133


зач<strong>е</strong>м нужны м<strong>е</strong>тоды<br />

Значимы<strong>е</strong> им<strong>е</strong>на<br />

При написании кода м<strong>е</strong>тодов выбира<strong>е</strong>тся структура программы. Вы ищ<strong>е</strong>т<strong>е</strong><br />

отв<strong>е</strong>ты на вопросы: воспользоваться ли одним м<strong>е</strong>тодом или, мож<strong>е</strong>т быть,<br />

разбить <strong>е</strong>го на н<strong>е</strong>сколько? А мож<strong>е</strong>т быть, м<strong>е</strong>тод тут вообщ<strong>е</strong> н<strong>е</strong> нуж<strong>е</strong>н? В р<strong>е</strong>зультат<strong>е</strong><br />

можно получить как интуитивно понятный код, так и н<strong>е</strong>что запутанно<strong>е</strong><br />

и н<strong>е</strong>чита<strong>е</strong>мо<strong>е</strong>.<br />

О П<strong>е</strong>р<strong>е</strong>д вами прим<strong>е</strong>р компактного кода. Это программа, управляющая автоматом по производству<br />

шоколадных батончиков.<br />

tb, т —<br />

ужасны<strong>е</strong> им<strong>е</strong>на!<br />

Вы никогда н<strong>е</strong><br />

догада<strong>е</strong>т<strong>е</strong>сь, ----<br />

зач<strong>е</strong>м нужны эти<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> и<br />

какова функция<br />

класса Т.<br />

іпЬ t = т.сЬкТ<strong>е</strong>тр(<br />

а {t > 160) {<br />

Т tb = п<strong>е</strong>ш<br />

ЬЬ.с1зТгр\/((2<br />

І С 8 . Р ІП () ;<br />

ics.V ent О ;<br />

.т.аігзузсЬкО<br />

ч^сло... но для ц<strong>е</strong>ло<strong>е</strong><br />

ч<strong>е</strong>го?<br />

М<strong>е</strong>тод с1&Тгр\'() им<strong>е</strong><strong>е</strong>т<br />

один П(Хр(ХМС\Л/\.р} но<br />

б жызнм н<strong>е</strong> угада<strong>е</strong>т<strong>е</strong> <strong>е</strong>го<br />

пр<strong>е</strong>дназнач<strong>е</strong>ни<strong>е</strong>.<br />

Вы мож<strong>е</strong>т<strong>е</strong>, взглянув на этот код, понять, какую ф ункцию он вы полня<strong>е</strong>т?<br />

© Оп<strong>е</strong>раторы н<strong>е</strong> дают даж<strong>е</strong> нам<strong>е</strong>ков на пр<strong>е</strong>дназнач<strong>е</strong>ни<strong>е</strong> кода. Зато нужный р<strong>е</strong>зультат получ<strong>е</strong>н<br />

при помощи вс<strong>е</strong>го одного м<strong>е</strong>тода. Но вс<strong>е</strong>гда ли максимальная компактность явля<strong>е</strong>тся<br />

кон<strong>е</strong>чной ц<strong>е</strong>лью? Давайт<strong>е</strong> разобь<strong>е</strong>м код на н<strong>е</strong>сколько м<strong>е</strong>тодов и сд<strong>е</strong>ла<strong>е</strong>м <strong>е</strong>го бол<strong>е</strong><strong>е</strong> простым.<br />

Вы на практик<strong>е</strong> уб<strong>е</strong>дит<strong>е</strong>сь в н<strong>е</strong>обходимости классов и осмысл<strong>е</strong>нных им<strong>е</strong>н. Для начала<br />

нужно понять, какую задачу р<strong>е</strong>ша<strong>е</strong>т данный код.<br />

Управл<strong>е</strong>ни<strong>е</strong> автоматом, производящим батончики<br />

Автоматизированная сист<strong>е</strong>ма пров<strong>е</strong>ря<strong>е</strong>т т<strong>е</strong>мп<strong>е</strong>ратуру<br />

нуги кажды<strong>е</strong> 3 минуты. Если она выш<strong>е</strong> 160 °С, н<strong>е</strong>обходимо<br />

выполнить проц<strong>е</strong>дуру охлажд<strong>е</strong>ния (С1С8).<br />

• З а к р о й т <strong>е</strong> клапан турби ны #2<br />

• З а п о м н и т <strong>е</strong> в о д о й сист<strong>е</strong>м у охл а ж д <strong>е</strong>н и я<br />

• В ы п устит<strong>е</strong> воду<br />

• У б<strong>е</strong>дит<strong>е</strong>сь, ч то в с и ст<strong>е</strong>м <strong>е</strong> отсутству<strong>е</strong>т воздух<br />

134 глава 3


О<br />

объ<strong>е</strong>кты, по порядку стройся!<br />

Инструкция н<strong>е</strong> только помогла опр<strong>е</strong>д<strong>е</strong>лить назнач<strong>е</strong>ни<strong>е</strong> кода, но и показала, как сд<strong>е</strong>лать <strong>е</strong>го<br />

бол<strong>е</strong><strong>е</strong> понятным. Мы узнали, что пров<strong>е</strong>рка условия опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т, н<strong>е</strong> пр<strong>е</strong>выша<strong>е</strong>т ли парам<strong>е</strong>тр<br />

Ъ знач<strong>е</strong>ни<strong>е</strong> 160, в<strong>е</strong>дь в инструкции написано, что при 160 °С нуга становится слишком горяч<strong>е</strong>й.<br />

А буква т оказалась классом, который контролиру<strong>е</strong>т пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> автомата. В класс<br />

входит статич<strong>е</strong>ский м<strong>е</strong>тод пров<strong>е</strong>рки т<strong>е</strong>мп<strong>е</strong>ратуры нуги и работы воздушной сист<strong>е</strong>мы. Выд<strong>е</strong>лим<br />

пров<strong>е</strong>рку т<strong>е</strong>мп<strong>е</strong>ратуры в отд<strong>е</strong>льный м<strong>е</strong>тод и дадим классу и м<strong>е</strong>тоду смысловы<strong>е</strong> им<strong>е</strong>на.<br />

' p u b l T c ^ ' b o o l e a ^ I s N o u g a t T o o H o t {) {<br />

Т и п знач<strong>е</strong>ний, i n t te m p = M a k e r . C h e c k N o u g a t T e m p e r a t u r e { ) ;<br />

возвращ а<strong>е</strong>м ы х (te m p > 1 6 0 ) { ^ Назов<strong>е</strong>м к л а с с M a k e r<br />

^ r e t u „ t.ue,. L<br />

j , , , ^ 3 ^ наг«).<br />

, ^ В о з в р а щ а <strong>е</strong> м ы <strong>е</strong> зн а ч <strong>е</strong> н и я<br />

J<br />

т и п а B o o le a n , э т о t r u e<br />

и л и fa lse.<br />

При пр<strong>е</strong>выш<strong>е</strong>нии р<strong>е</strong>ком<strong>е</strong>нду<strong>е</strong>мой т<strong>е</strong>мп<strong>е</strong>ратуры инструкция тр<strong>е</strong>бу<strong>е</strong>т выполн<strong>е</strong>ния проц<strong>е</strong>дуры<br />

CICS. Создадим <strong>е</strong>щ<strong>е</strong> один м<strong>е</strong>тод и выб<strong>е</strong>р<strong>е</strong>м для класса Т (он управля<strong>е</strong>т турбиной) бол<strong>е</strong><strong>е</strong><br />

значимо<strong>е</strong> имя. П<strong>е</strong>р<strong>е</strong>им<strong>е</strong>ну<strong>е</strong>м такж<strong>е</strong> класс i c s (управляющий изолированной сист<strong>е</strong>мой охлажд<strong>е</strong>ния).<br />

Этот класс сод<strong>е</strong>ржит два статич<strong>е</strong>ских м<strong>е</strong>тода. Один —для заполн<strong>е</strong>ния сист<strong>е</strong>мы<br />

водой (fill), второй —для слива воды (vent):<br />

p u b l i c (y o i d J P o C I C S V e n t P r o c e d u r e () {<br />

/к о д и ф и к а т о р v o id T u r b i n e t u r b i n e C o n t r o l l e r = n ew T u r b i n e () ;<br />

о з н а ч а <strong>е</strong> т , ч т о м <strong>е</strong> т о д t u r b i n e C o n t r o l l e r . C lo se T r ip V a lv e (2 ) ;<br />

Т н а ч <strong>е</strong> н т '^ ^ ^ '^ никакого I s o l a t i o n C o o l i n g S y s t e m . F i l l {) ;<br />

I s o l a t i o n C o o l i n g S y s t e m . V e n t О ;<br />

M a k e r .C h e c k A ir S y s t e m O ;<br />

}<br />

Т<strong>е</strong>п<strong>е</strong>рь, даж<strong>е</strong> <strong>е</strong>сли вы н<strong>е</strong> читали инструкцию и н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что проц<strong>е</strong>дура CICS запуска<strong>е</strong>тся<br />

при слишком высокой т<strong>е</strong>мп<strong>е</strong>ратур<strong>е</strong> нуги, вы вс<strong>е</strong> равно мож<strong>е</strong>т<strong>е</strong> понять, что д<strong>е</strong>ла<strong>е</strong>т код:<br />

i f {I S N o u g a t T o o H o t () == t r u e ) {<br />

}<br />

D o C I C S V e n t P r o c e d u r e ( ) ;<br />

Помнит<strong>е</strong> 0 T O M , зач<strong>е</strong>м вы пиш<strong>е</strong>т<strong>е</strong> код. Это позволит сд<strong>е</strong>лать кон<strong>е</strong>чный<br />

р<strong>е</strong>зультат простым и л<strong>е</strong>гко р<strong>е</strong>дактиру<strong>е</strong>мым. Выбор смысловых<br />

им<strong>е</strong>н упроща<strong>е</strong>т посл<strong>е</strong>дующую расшифровку программы<br />

другими людьми и да<strong>е</strong>т возможность улучшить код!<br />

дальш<strong>е</strong> > 135


классы как они <strong>е</strong>сть<br />

Структура классоб<br />

Поч<strong>е</strong>му ж<strong>е</strong> м<strong>е</strong>тоды сл<strong>е</strong>ду<strong>е</strong>т д<strong>е</strong>лать интуитивно понятными? Потому что каждая<br />

программа р<strong>е</strong>ша<strong>е</strong>т пробл<strong>е</strong>му или им<strong>е</strong><strong>е</strong>т конкр<strong>е</strong>тную ц<strong>е</strong>ль. Ц<strong>е</strong>лью дал<strong>е</strong>ко н<strong>е</strong><br />

вс<strong>е</strong>гда являются с<strong>е</strong>рь<strong>е</strong>зны<strong>е</strong> задачи, иногда программы могут писаться просто для<br />

забавы! Но каково бы н<strong>е</strong> было пр<strong>е</strong>дназнач<strong>е</strong>ни<strong>е</strong> программы, ч<strong>е</strong>м больш<strong>е</strong> код напомина<strong>е</strong>т<br />

о том, какая им<strong>е</strong>нно пробл<strong>е</strong>ма с <strong>е</strong>го помош;ью р<strong>е</strong>ша<strong>е</strong>тся, т<strong>е</strong>м прощ<strong>е</strong> такую<br />

программу писать, читать и р<strong>е</strong>дактировать.<br />

Д и а г р а м м а к л а с с а<br />

Э т о нагл ядно<strong>е</strong> п р <strong>е</strong> д с т а в л <strong>е</strong> н и <strong>е</strong><br />

к л а сса на л и с т <strong>е</strong> дуллаги.<br />

В в <strong>е</strong> т ц п и ш <strong>е</strong> т с я амя к л а сса ,<br />

а п о д н и м вс<strong>е</strong> входящ и<strong>е</strong><br />

в к л а сс м <strong>е</strong> т о д ы !<br />

MethodO<br />

MethodO<br />

MethodO<br />

C la s s N a m e<br />

Прим<strong>е</strong>р постро<strong>е</strong>ния диаграммы<br />

Посмотрит<strong>е</strong> на оп<strong>е</strong>ратор 1 £ из пункта #5 на пр<strong>е</strong>дыдущ<strong>е</strong>й страниц<strong>е</strong>. Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>,<br />

что оп<strong>е</strong>раторы находятся внутри м<strong>е</strong>тодов, а м<strong>е</strong>тоды, в свою оч<strong>е</strong>р<strong>е</strong>дь, внутри классов?<br />

В данном случа<strong>е</strong> оп<strong>е</strong>ратор i f принадл<strong>е</strong>жит м<strong>е</strong>тоду D oM aintenanceT ests {),<br />

который явля<strong>е</strong>тся частью класса С ап с1уС оп Ь го11<strong>е</strong>г. Т<strong>е</strong>п<strong>е</strong>рь разб<strong>е</strong>р<strong>е</strong>мся, как соотносятся<br />

друг с другом код и диаграмма классов.<br />

c l a s s C a n d y C o n t r o l l e r {<br />

p u b l i c v o i d D o M a i n t e n a n c e T e s t s () {<br />

}<br />

i f ( I S N o u g a t T o o H o t () == t r u e ) {<br />

}<br />

D o C I C S V e n t P r o c e d u r e ( ) ;<br />

C a n d y C o n tro lle r<br />

DoMaintenanceTestsO<br />

DoCICSVentProcedureO<br />

IsNougatTooHotO<br />

p u b l i c v o i d D o C I C S V e n t P r o c e d u r e ()<br />

p u b l i c b o o l e a n I S N o u g a t T o o H o t {) . .<br />

136 глава 3


возьми в руку карандаш<br />

объ<strong>е</strong>кты, по порядку стройся!<br />

Код для управл<strong>е</strong>ния машиной по производству шоколадных<br />

батончиков сод<strong>е</strong>ржит <strong>е</strong>щ<strong>е</strong> три класса. Изучит<strong>е</strong> <strong>е</strong>го внимат<strong>е</strong>льно<br />

и заполнит<strong>е</strong> эти диаграммы.<br />

“»І»<br />

Ж "<br />

дд<strong>е</strong>тоЭ.<br />

Программа сод<strong>е</strong>ржит<br />

м ° m Z “<br />

дальш<strong>е</strong> ¥ 137


н<strong>е</strong>сколько сов<strong>е</strong>тов<br />

Выбор структуры класса при помои^и<br />

диаграммы<br />

Д и аграм м ы классов п о зв о л я ю т увид<strong>е</strong>ть п от<strong>е</strong>н ц и ал ьн ы <strong>е</strong> п р о б л <strong>е</strong>м ы <strong>е</strong>щ <strong>е</strong> до<br />

того как вы н а ч н <strong>е</strong>т <strong>е</strong> пи сать код. П р <strong>е</strong>д в а р и т <strong>е</strong>л ь н о <strong>е</strong> обдум ы ван и<strong>е</strong> структуры<br />

классов гарантиру<strong>е</strong>т связь кода с п о ст а в л <strong>е</strong>н н о й п <strong>е</strong> р <strong>е</strong> д вам и п р о б л <strong>е</strong>м о й . О н о<br />

п о зв о л и т и зб <strong>е</strong>ж а т ь работы над н <strong>е</strong>н уж н ы м к одом и получить и н туи ти в н о п о ­<br />

нятную и л<strong>е</strong>гкую в п р и м <strong>е</strong> н <strong>е</strong> н и и программу.<br />

П о с у д о м о й к а<br />

Мыть<strong>е</strong>Тар<strong>е</strong>локО<br />

ДобавкаМылаО<br />

Т<strong>е</strong>мп<strong>е</strong>ратураВодыО<br />

ПарковкаМашины()<br />

Вс<strong>е</strong> м<strong>е</strong>тоды класса<br />

«Посудомойка» должны бы ть<br />

связаны с мы ть<strong>е</strong>м посуды.<br />

с этой проц<strong>е</strong>дурой никак н<strong>е</strong><br />

связан, поэтому <strong>е</strong>го нужно<br />

пом<strong>е</strong>стить в другой класс.<br />

П о с у д о м о й к а<br />

Мыть<strong>е</strong>Тар<strong>е</strong>локО<br />

ДобавкаМылаО<br />

Т<strong>е</strong>мп<strong>е</strong>ратураВодыО<br />

_________________<br />

Возьми в руку карандаш<br />

Turbine<br />

CloseTripValveQ<br />

^0Ш<strong>е</strong>НИ6 должны выгляд<strong>е</strong>ть диаграммы клас- Понять, что Maker —<br />

сов, которы<strong>е</strong> вам было пр<strong>е</strong>длож<strong>е</strong>но зап<strong>е</strong>л- названи<strong>е</strong> класса, л<strong>е</strong>гко<br />

нить на пр<strong>е</strong>дыдущ<strong>е</strong>й страниц<strong>е</strong>.<br />

полож<strong>е</strong>нию 6 им<strong>е</strong>ни<br />

Maker.CheckAirSystemQ.<br />

IsolationCoolingSystem<br />

FillQ<br />

VentQ<br />

M aker<br />

C keckN ougatTem peratureQ<br />

CheckAirSystem Q<br />

138 глава 3


_ і^ о з ь м и в руку карандаш<br />

объ<strong>е</strong>кты, по порядку стройся!<br />

Вс<strong>е</strong> эти классы сод<strong>е</strong>ржат ошибки. Напишит<strong>е</strong>, в ч<strong>е</strong>м, по ваш<strong>е</strong>му<br />

мн<strong>е</strong>нию, они состоят, и как их можно исправить.<br />

К л а с с 2 3<br />

В<strong>е</strong>сБатончикаО<br />

П<strong>е</strong>чатьОб<strong>е</strong>рткиО<br />

П<strong>е</strong>чатьОтч<strong>е</strong>таО<br />

Д<strong>е</strong>ла<strong>е</strong>мО<br />

Этот класс явля<strong>е</strong>тся частью знакомой вам сист<strong>е</strong>мы производства<br />

шоколадных батончиков.<br />

Р а зн о с ч и к П и ц ц ы<br />

ДобавитьПиццуО<br />

ПиццаДоставл<strong>е</strong>наО<br />

Подсч<strong>е</strong>тСуммыО<br />

Вр<strong>е</strong>мяВозвращ<strong>е</strong>нияО<br />

Р азн о счи ц аП и ц ц ы<br />

Эти классы являются частью сист<strong>е</strong>мы уч<strong>е</strong>та доставки пиццы.<br />

ДобавитьПиццуО<br />

ПиццаДоставл<strong>е</strong>наО<br />

Подсч<strong>е</strong>тСуммыО<br />

Вр<strong>е</strong>мяВозвращ<strong>е</strong>нияО<br />

К а с с о в ы й А п п а р а т<br />

ПродажиО<br />

Н<strong>е</strong>тПродажО<br />

ЗакачатьГазО<br />

ВозвратД<strong>е</strong>н<strong>е</strong>гО<br />

Вс<strong>е</strong>гоВКасс<strong>е</strong>О<br />

СписокТранзакцийО<br />

ДобавитьСуммуО<br />

Выч<strong>е</strong>стьСуммуО<br />

Класс КассовыйАппарат явля<strong>е</strong>тся частью программы<br />

автоматизированной сист<strong>е</strong>мы контроля в круглосуточном<br />

магазин<strong>е</strong>.<br />

дальш<strong>е</strong> * 139


создадим класс<br />

Возьми в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как мы скорр<strong>е</strong>ктировали классы . Но это лишь один<br />

способ р<strong>е</strong>ш<strong>е</strong>ния пробл<strong>е</strong>мы. Можно использовать и други<strong>е</strong> способы,<br />

в зависимости от того, как пр<strong>е</strong>дполага<strong>е</strong>тся использовать<br />

класс.<br />

Этот класс явля<strong>е</strong>тся частью знакомой вам сист<strong>е</strong>мы<br />

производства шоколадных батончиков.<br />

Из им<strong>е</strong>ни класса С1а5523.ао() н<strong>е</strong> понятно <strong>е</strong>го назнач<strong>е</strong>ни<strong>е</strong>.<br />

Кром<strong>е</strong> того, мы выбрали бол<strong>е</strong><strong>е</strong> осмысл<strong>е</strong>нно<strong>е</strong> имя для<br />

посл<strong>е</strong>дн<strong>е</strong>го м<strong>е</strong>тода.<br />

V<br />

Д <strong>е</strong> л а <strong>е</strong> м Б а т о н ч и к и<br />

В<strong>е</strong>сБатончикаО<br />

П<strong>е</strong>чатьОб<strong>е</strong>рткиО<br />

П<strong>е</strong>чатьОтч<strong>е</strong>таО<br />

СоздатьБатончикО<br />

Эти классы являются частью сист<strong>е</strong>мы уч<strong>е</strong>та доставки пиццы.<br />

Классы Pe^(Very^5uy и Р<strong>е</strong>Иу<strong>е</strong>гур1'Н выполняли одну<br />

задачу. Им<strong>е</strong><strong>е</strong>т смысл объ<strong>е</strong>динить их друг с другом,<br />

добавив пол<strong>е</strong> для ввода половой принадл<strong>е</strong>жности<br />

работника.<br />

Р а з н о с ч и к П и ц ц ы<br />

Пол<br />

ДобавитьПиццуО<br />

ПиццаДоставл<strong>е</strong>наО<br />

Подсч<strong>е</strong>тСуммыО<br />

Вр<strong>е</strong>мяВозвращ<strong>е</strong>нияО<br />

Пол<strong>е</strong> Пол было добавл<strong>е</strong>но,<br />

чтобы отсл<strong>е</strong>живать<br />

р<strong>е</strong>зультаты работы юнош<strong>е</strong>й<br />

и д<strong>е</strong>вуш<strong>е</strong>к по отд<strong>е</strong>льности.<br />

Класс КассовыйАппарат явля<strong>е</strong>тся частью программы<br />

автоматизированной сист<strong>е</strong>мы контроля круглосуточного<br />

магазина.<br />

был удал<strong>е</strong>н м<strong>е</strong>тод ЗакачатьГаз(), как <strong>е</strong>динств<strong>е</strong>нный,<br />

н<strong>е</strong> им<strong>е</strong>ющий отнош<strong>е</strong>ния к работ<strong>е</strong> кассовых<br />

аппаратов.<br />

К а с с о в ы й А п п а р а !<br />

ПродажиО<br />

Н<strong>е</strong>тПродажО<br />

ВозвратД<strong>е</strong>н<strong>е</strong>гО<br />

Вс<strong>е</strong>гоВКасс<strong>е</strong>О<br />

СписокТранзакцийО<br />

ДобавитьСуммуО<br />

Выч<strong>е</strong>стьСуммуО<br />

140 глава 3


объ<strong>е</strong>кты, по порядку стройся!<br />

p u b lic p a r t i a l c l a s s Forml<br />

(<br />

: Form<br />

p r iv a t e v o id b u t t o n l_ C lic k ( o b j e c t se n d er , E ventA rgs e)<br />

{<br />

S t r in g r e s u l t =<br />

Echo e l = new E ch o ();<br />

i n t X = 0;<br />

w h ile { ) {<br />

r e s u l t = r e s u l t + e l . H e l l o 0<br />

i f ) {<br />

}<br />

e 2 .c o u n t = e 2 .c o u n t + 1;<br />

i f { ________________ ) {<br />

+ "\n";<br />

e 2 .c o u n t = e 2 .c o u n t + e l.c o u n t ;<br />

X = X + 1;<br />

}<br />

M essa g eB o x .S h o w (r esu lt + "Count: " + e 2 .c o u n t ) ;<br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна<br />

и пом<strong>е</strong>стит<strong>е</strong> их на пусты<strong>е</strong><br />

строчки. Фрагм<strong>е</strong>нты можно<br />

использовать н<strong>е</strong>сколько раз.<br />

В басс<strong>е</strong>йн<strong>е</strong> <strong>е</strong>сть и лишни<strong>е</strong><br />

фрагм<strong>е</strong>нты. Получ<strong>е</strong>нная в итог<strong>е</strong><br />

программа должна выводить<br />

окно с показанным ниж<strong>е</strong> т<strong>е</strong>кстом.<br />

Р<strong>е</strong>зультат:<br />

Н<strong>е</strong>Ноооо...<br />

heltoooo...<br />

helloooo...<br />

helloooo,..<br />

C o u n t 10<br />

OK<br />

}<br />

c l a s s {<br />

p u b lic i n t ________<br />

p u b lic s t r i n g ________<br />

}<br />

r e tu r n " h e l l o o o o . .<br />

К аж ды й ф р а г­<br />

м <strong>е</strong>нт м ож но<br />

и сп о л ь зо в ать<br />

н<strong>е</strong>ско л ь ко раз!<br />

= 0 ;<br />

count<br />

ЄІ = ЄІ + 1;<br />

ЄІ = count + 1;<br />

el .count = count + 1;<br />

el count = e1 count + 1;<br />

IS 'т<strong>е</strong>ч*' X < 4<br />

х х < 5 Echo<br />

у X > 0 Tester<br />

<strong>е</strong>2 X > 1 Echo()<br />

count(;<br />

Н<strong>е</strong>ІІо()<br />

<strong>е</strong>2 = <strong>е</strong>1;<br />

Echo <strong>е</strong>2;<br />

Echo <strong>е</strong>2 ■<br />

Echo <strong>е</strong>2 ■<br />

Д о п о л н и т<strong>е</strong>льны й<br />

вопрос!<br />

Как р<strong>е</strong>шить задачу, чтобы<br />

вм<strong>е</strong>сто 10 в посл<strong>е</strong>дн<strong>е</strong>й<br />

строк<strong>е</strong> оказалось 24? Для<br />

этого достаточно зам<strong>е</strong>нить<br />

вс<strong>е</strong>го один оп<strong>е</strong>ратор.<br />

el;<br />

x==3<br />

new Echo(); x == 4<br />

ж®;<br />

ОіюБЄї О на с.<br />

дальш<strong>е</strong> *


работающий класс guys<br />

Помогит<strong>е</strong> парням<br />

<strong>Дж</strong>о и Боб вс<strong>е</strong> вр<strong>е</strong>мя одалживают друг другу д<strong>е</strong>ньги. Напиш<strong>е</strong>м программу отсл<strong>е</strong>живания<br />

истории займов. Для начала нужно понять структуру создава<strong>е</strong>мого класса.<br />

Создадим класс биу и добавим в цю рму два <strong>е</strong>го экз<strong>е</strong>мпляра<br />

П<strong>е</strong>рво<strong>е</strong> пол<strong>е</strong> формы буд<strong>е</strong>т называться j о<strong>е</strong> (для сл<strong>е</strong>ж<strong>е</strong>ния за п<strong>е</strong>рвым<br />

объ<strong>е</strong>ктом), а второ<strong>е</strong> bob (для сл<strong>е</strong>ж<strong>е</strong>ния за вторым объ<strong>е</strong>ктом).<br />

Оп<strong>е</strong>ратор neWj<br />

создающий экз<strong>е</strong>мпляры<br />

запуска<strong>е</strong>тся в мом<strong>е</strong>нт<br />

загрузки формы. На<br />

рисунк<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>н<br />

вид кучи посл<strong>е</strong> этой<br />

оп<strong>е</strong>рации.<br />

’Ь<strong>е</strong>кт<br />

о Сопоставим каждому объ<strong>е</strong>кту биу поля N am e и Cash<br />

Два объ<strong>е</strong>кта соотв<strong>е</strong>тствуют двум парням, у каждого из которых<br />

<strong>е</strong>сть сво<strong>е</strong> имя и н<strong>е</strong>которо<strong>е</strong> колич<strong>е</strong>ство д<strong>е</strong>н<strong>е</strong>г в кош<strong>е</strong>льк<strong>е</strong>.<br />

Name<br />

Cash<br />

G u y<br />

GiveCashO<br />

ReceiveCashO<br />

Os<br />

Итак, наш класс называ<strong>е</strong>тся<br />

Quy (Пар<strong>е</strong>нь).<br />

М<strong>е</strong>тод GiveCaskQ<br />

отв<strong>е</strong>ча<strong>е</strong>т за п<strong>е</strong>р<strong>е</strong>дачу<br />

д<strong>е</strong>н<strong>е</strong>г в долг, а м <strong>е</strong> ­<br />

тод ReceiveCashQ —<br />

за их получ<strong>е</strong>ни<strong>е</strong>. Поля<br />

Name и Cash сод<strong>е</strong>ржат<br />

информацию об им<strong>е</strong>ни<br />

и сумм<strong>е</strong> соотв<strong>е</strong>тств<strong>е</strong>нно.<br />

Пол<strong>е</strong> Name сод<strong>е</strong>ржит .<br />

информацию 00 —р<br />

им<strong>е</strong>ни парня, а пол<strong>е</strong><br />

Cash —- о сумм<strong>е</strong> <strong>е</strong>го<br />

наличности.<br />

О<br />

Ч5і<strong>е</strong>кт&'^<br />

П а р н и даю т д<strong>е</strong>ньги и получаю т и х назад<br />

М<strong>е</strong>тод R eceiveC ash () ув<strong>е</strong>личива<strong>е</strong>т колич<strong>е</strong>ство д<strong>е</strong>н<strong>е</strong>г у объ<strong>е</strong>кта,<br />

а м<strong>е</strong>тод G iveC ash () ум<strong>е</strong>ньша<strong>е</strong>т этот парам<strong>е</strong>тр.<br />

форма<br />

вызыва<strong>е</strong>т м<strong>е</strong>тод ReceмeCash().<br />

\<br />

joe.ReceiveCash(25) ; —I и 'р<br />

Парам<strong>е</strong>тром<br />

м<strong>е</strong>тода ReceiveCash()<br />

явля<strong>е</strong>тся колич<strong>е</strong>ство<br />

получа<strong>е</strong>мых д<strong>е</strong>н<strong>е</strong>г.<br />

Поэтому запись<br />

joe.ReceiveCash(ZS)<br />

означа<strong>е</strong>т, что <strong>Дж</strong>о<br />

получит Я5" долларов.<br />

^Ъ<strong>е</strong>кг<br />

М<strong>е</strong>тод возвраща<strong>е</strong>т сумму, которую<br />

объ<strong>е</strong>кт добавил к полю Cash.<br />

142 глава 3


объ<strong>е</strong>кты, по порядку стройся!<br />

Про<strong>е</strong>кт «Парни»<br />

Создайт<strong>е</strong> про<strong>е</strong>кт Windows Forms Application (в<strong>е</strong>дь нам понадобится<br />

форма). В окн<strong>е</strong> Solution Explorer создайт<strong>е</strong> класс с им<strong>е</strong>н<strong>е</strong>м<br />

Guy. Добавьт<strong>е</strong> в в<strong>е</strong>рхнюю часть файла этого класса строчку u s i n g<br />

S y s t e m . W in d o w s . F o r m s ;, зат<strong>е</strong>м вв<strong>е</strong>дит<strong>е</strong> сл<strong>е</strong>дующий код:<br />

У пі^аж н<strong>е</strong>ни<strong>е</strong><br />

class Guy {<br />

ртіЬІіс string Name;<br />

public int Cash;<br />

public<br />

if<br />

Л<br />

Т р <strong>е</strong> б у <strong>е</strong> м а я с у м м а<br />

Золжнд б ы т ь \<br />

б о л ь ш <strong>е</strong> н у л я .<br />

И н а ч <strong>е</strong> д <strong>е</strong> н ь ги<br />

б у д у т д о б а в л <strong>е</strong> н ы<br />

в к о ш <strong>е</strong> л <strong>е</strong> к , а н<strong>е</strong><br />

в з я т ы о т т у д а .<br />

}<br />

}<br />

int GiveCash(int amount) {<br />

(amount 143


джо говорит: «гд<strong>е</strong> мои д<strong>е</strong>ньги?»<br />

Форма для Взаимод<strong>е</strong>йствия с кодом<br />

Т<strong>е</strong>п<strong>е</strong>рь нам нужна форма, которая буд<strong>е</strong>т работать с экз<strong>е</strong>мплярами<br />

класса Guy. Она должна сод<strong>е</strong>ржать м<strong>е</strong>тки с им<strong>е</strong>нами парн<strong>е</strong>й и колич<strong>е</strong>ством<br />

д<strong>е</strong>н<strong>е</strong>г у каждого их них, а такж<strong>е</strong> кнопки, управляющи<strong>е</strong><br />

проц<strong>е</strong>ссом взятия и возврата д<strong>е</strong>н<strong>е</strong>г.<br />

■ф-<br />

|JoCmJ>oU3Iie<br />

Н ам понадобятся дв<strong>е</strong> кнопки и три м <strong>е</strong>тки<br />

Дв<strong>е</strong> в<strong>е</strong>рхни<strong>е</strong> м<strong>е</strong>тки должны показывать сумму наличности у каждого из парн<strong>е</strong>й. К форм<strong>е</strong><br />

такж<strong>е</strong> нужно добавить пол<strong>е</strong> bank —это <strong>е</strong>щ<strong>е</strong> одна м<strong>е</strong>тка. По оч<strong>е</strong>р<strong>е</strong>ди выд<strong>е</strong>ляйт<strong>е</strong> вс<strong>е</strong><br />

м<strong>е</strong>тки и р<strong>е</strong>дактируйт<strong>е</strong> их свойство «(Name)» в окн<strong>е</strong> Properties. Присвоив м<strong>е</strong>тками им<strong>е</strong>на<br />

joesCashLabel и bobsCashLabel вм<strong>е</strong>сто им<strong>е</strong>н labell и 1аЬ<strong>е</strong>12, вы сд<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> код бол<strong>е</strong><strong>е</strong> читаб<strong>е</strong>льным.<br />

Э тд кнопка<br />

вызыва<strong>е</strong>м, м<strong>е</strong>мод<br />

ReceiveCashQ<br />

объ<strong>е</strong>кта Joe,<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>м<br />

знач<strong>е</strong>ни<strong>е</strong> 1 0<br />

и вычима<strong>е</strong>м<br />

из поля bank<br />

сумму, которую<br />

/получа<strong>е</strong>т <strong>Дж</strong>о.<br />

О П о л я формы<br />

Ц? Fun with ioe and Bob<br />

Joe has $50<br />

Bob has $100<br />

The bank has $100<br />

Qve $10 to<br />

Joe<br />

Receive $5<br />

from Bob<br />

В<strong>е</strong>рхн<strong>е</strong>й м <strong>е</strong>т ­<br />

к<strong>е</strong> присвойт<strong>е</strong> имя<br />

joesCashLabel J ср<strong>е</strong>д-<br />

^ н<strong>е</strong>й — bobsCashLabel,<br />

a нижн<strong>е</strong>й —<br />

bankCashLabel.<br />

Свойство Text пока<br />

можно н<strong>е</strong> р<strong>е</strong>дакти -<br />

ровать.<br />

Эта кнопка вызыва<strong>е</strong>т<br />

м<strong>е</strong>тод QiveCashQ<br />

объ<strong>е</strong>кта Bob,<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> S<br />

и прибавля<strong>е</strong>т <strong>е</strong>го<br />

к полю bank.<br />

Для отсл<strong>е</strong>живания финансового состояния наших г<strong>е</strong>ро<strong>е</strong>в потр<strong>е</strong>буются два поля. Назовит<strong>е</strong><br />

их j о<strong>е</strong> и bob. Зат<strong>е</strong>м добавьт<strong>е</strong> пол<strong>е</strong> с им<strong>е</strong>н<strong>е</strong>м bank для расч<strong>е</strong>та, сколько форма должна взять<br />

у объ<strong>е</strong>ктов, а сколько отдать им. Дважды щ<strong>е</strong>лкнит<strong>е</strong> на тр<strong>е</strong>ть<strong>е</strong>й м<strong>е</strong>тк<strong>е</strong> и добавьт<strong>е</strong> в появившийся<br />

код строки:<br />

nam esp ace Y ou r_P roject_N am e {<br />

p u b l i c p a r t i a l c l a s s Forml : Form {<br />

Поля Joe ------^<br />

и Bob объявл<strong>е</strong>ны<br />

в класс<strong>е</strong><br />

Guy.<br />

Guy joe?<br />

Guy bob ;<br />

in t bank ■ 100;<br />

p u b l i c F o r m l0 {<br />

}<br />

I n it i a l iz e C o m p o n e n t () ;<br />

З н а ч <strong>е</strong> н и <strong>е</strong> п о л я b a n k<br />

т о в о з р а с т а <strong>е</strong> т , т о<br />

И м <strong>е</strong> н ь и л а <strong>е</strong> т с я в з а ­<br />

в и с и м о с т и о т т о г о<br />

^1


О М <strong>е</strong>тод, обновляю щ ий м <strong>е</strong>тки<br />

Д о б а в и м к ф о р м <strong>е</strong> м <strong>е</strong>то д U p d a te F o r m ( ) , ч то б ы м <strong>е</strong>тки вс<strong>е</strong>гда показы вали актуально<strong>е</strong> колич<br />

<strong>е</strong>ств о д<strong>е</strong>н<strong>е</strong>г. Уб<strong>е</strong>дит<strong>е</strong>сь в наличии модификатора v oid , так как д ан н ы й м <strong>е</strong>то д н <strong>е</strong> д о л ж <strong>е</strong>н<br />

возвращ ать зн а ч <strong>е</strong>н и <strong>е</strong>. Д обавьт<strong>е</strong> эти стр о ч к и п о д п р <strong>е</strong>ды дущ ий код:<br />

объ<strong>е</strong>кты, по порядку стройся!<br />

М <strong>е</strong>тки UpdateForm О {<br />

л я ю т с й п р и jo e sC a sh L a b e l .T e x t = jo e.N a m e +<br />

им <strong>е</strong><strong>е</strong>т $" + j o e .C a s h ;<br />

поМОЫА,и п о л <strong>е</strong> й г b o b sC a sh L a b e l. T e x t = b ob . Name + им<strong>е</strong><strong>е</strong>т $" + b o b .C a sh ;<br />

N a m e и C a sh J - i<br />

м <strong>е</strong> т о д а G u y . ( b a n k C a sh L a b el.T ex t = "B банк<strong>е</strong> с<strong>е</strong>й ч а с $" + bank;<br />

Этот м<strong>е</strong>тод<br />

обновля<strong>е</strong>т м <strong>е</strong>т ­<br />

ки, изм<strong>е</strong>няя их<br />

свойство Text.<br />

Код взаимод<strong>е</strong>йствия кнопок с объ<strong>е</strong>ктами<br />

У б<strong>е</strong>дит<strong>е</strong>сь, ч то кн опка назы ва<strong>е</strong>тся b u t t o n l , а кнопка справа - b u t t o n 2 . Д важ ды щ <strong>е</strong>лкнит<strong>е</strong><br />

на к аж дой и з кн опок , ч то б ы добав и ть м <strong>е</strong>то д ы b u t t o n l _ C l i c k {) и b u t t o n 2 _ C l i c k ()<br />

со о тв <strong>е</strong>т ст в <strong>е</strong>н н о , и для к аж дой кн опк и вв<strong>е</strong>ди т<strong>е</strong> код:<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

i f (bank >= 10) { ^ ^ 'Мслцщ на кнопк<strong>е</strong> Give ^ г о to Joe,<br />

bank -= j o e .R e c e i v e C a s h {10) ; / Ф°рма вызыва<strong>е</strong>т м<strong>е</strong>тод ReceiveCaskh<br />

} e l s e {<br />

M essa g eB o x . Show ( "B банк<strong>е</strong> н<strong>е</strong>т д <strong>е</strong> н <strong>е</strong> г ." ) ;<br />

^<br />

Чтобы дать д<strong>е</strong>ньги <strong>Дж</strong>о, в банк<strong>е</strong> должно<br />

} X. быть н<strong>е</strong> м<strong>е</strong>ньил<strong>е</strong> Если их н<strong>е</strong>т,<br />

появля<strong>е</strong>тся окно с сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

p r i v a t e v o id b u t t o n 2_ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

bank += b o b .G iv e C a s h ( 5 ) ;<br />

О<br />

U p dateF orm O ; ^ ^ о п к а Я <strong>е</strong>с<strong>е</strong>лч<strong>е</strong> f r o m ЪоЬ д о б а в л я <strong>е</strong> т<br />

I 6 Ътьш.<br />

Ц 5o6a м<strong>е</strong>тод GiveCashQ<br />

возвраща<strong>е</strong>т О.<br />

Начальный капитал Д ж о $ 5 0 , а Боба — $ 1 0 0<br />

А т<strong>е</strong>п<strong>е</strong>рь самостоят<strong>е</strong>льно укажит<strong>е</strong> начально<strong>е</strong> состояни<strong>е</strong> пол<strong>е</strong>й Cash и Name для<br />

обоих экз<strong>е</strong>мпляров. Код расположит<strong>е</strong> под строкой I n i t i a l i z e C o m p o n e n t ( ) , в<strong>е</strong>дь<br />

проц<strong>е</strong>дура должна выполняться при инициализации формы. Зав<strong>е</strong>ршив работу, уб<strong>е</strong>дит<strong>е</strong>сь,<br />

что щ<strong>е</strong>лчок на л<strong>е</strong>вой кнопк<strong>е</strong> забира<strong>е</strong>т $10 из банка и отда<strong>е</strong>т эту сумму <strong>Дж</strong>о,<br />

а вторая кнопка забира<strong>е</strong>т у Боба $5 и возвраща<strong>е</strong>т их в банк.<br />

p u b l i c F o r m l О { А с> ^ я вьт <strong>е</strong> к о д , с о з д а ю щ и й<br />

I n it ia liz e C o m p o n e n t O ; _________— ^ва э к з <strong>е</strong> м п л я р а и з а д а ю -<br />

ажн<strong>е</strong>ш<strong>е</strong><br />

}<br />

„ з а д а й т <strong>е</strong> н а ,а л ь н ь .<strong>е</strong> з н а ^ <strong>е</strong> н и ^ и Т Г <strong>е</strong> Г л /^ Г<br />

дальш<strong>е</strong> ► 145


объ<strong>е</strong>кты, по порядку стройся!<br />

Бол<strong>е</strong><strong>е</strong> просты<strong>е</strong> способы присво<strong>е</strong>ния начальных знач<strong>е</strong>ний<br />

Практич<strong>е</strong>ски вс<strong>е</strong>гда создани<strong>е</strong> объ<strong>е</strong>ктов сопровожда<strong>е</strong>тся присво<strong>е</strong>ни<strong>е</strong>м<br />

им начальных знач<strong>е</strong>ний. Объ<strong>е</strong>кт G uy н<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> —он б<strong>е</strong>спол<strong>е</strong>з<strong>е</strong>н,<br />

<strong>е</strong>сли н<strong>е</strong> заданы знач<strong>е</strong>ния пол<strong>е</strong>й Name и C a sh . Для р<strong>е</strong>ш<strong>е</strong>ния<br />

этой задачи в <strong>C#</strong> сущ<strong>е</strong>ству<strong>е</strong>т инициализатор объ<strong>е</strong>ктов. В <strong>е</strong>го основ<strong>е</strong><br />

л<strong>е</strong>жит т<strong>е</strong>хнология IntelliSense.<br />

Рассмотрим исходный код, присваивающий полям<br />

объ<strong>е</strong>кта Joe начальны<strong>е</strong> знач<strong>е</strong>ния.<br />

Инициализаторы<br />

о^<strong>е</strong>ктов экономят<br />

ваш<strong>е</strong> вр<strong>е</strong>мя и ув<strong>е</strong>личивают<br />

компактность<br />

и читаб<strong>е</strong>льность<br />

кода.<br />

joe = new Guy О ;<br />

joe.Name = "Joe";<br />

joe.Cash = 50;<br />

О Удалит<strong>е</strong> дв<strong>е</strong> посл<strong>е</strong>дни<strong>е</strong> строки и точку с запятой посл<strong>е</strong> G uy {) и добавьт<strong>е</strong> справа<br />

фигурную скобку,<br />

joe = new Guy о {<br />

О Нажмит<strong>е</strong> проб<strong>е</strong>л. Появится окно со списком пол<strong>е</strong>й, для которых могут быть заданы<br />

начальны<strong>е</strong> парам<strong>е</strong>тры.<br />

joe = new Guy о {<br />

ф Cash<br />

0 Name<br />

int Guy.Cash<br />

Нажмит<strong>е</strong> Tab, чтобы добавить пол<strong>е</strong> C a sh . Зат<strong>е</strong>м присвойт<strong>е</strong> <strong>е</strong>му знач<strong>е</strong>ни<strong>е</strong> 50.<br />

joe = new G u y O { Cash = 50<br />

О Вв<strong>е</strong>дит<strong>е</strong> запятую, и сразу посл<strong>е</strong> нажатия проб<strong>е</strong>ла появится <strong>е</strong>щ<strong>е</strong> одно пол<strong>е</strong>,<br />

joe = new G u y O { Cash = 50,<br />

ф N am e string Guy.Name<br />

Зав<strong>е</strong>ршит<strong>е</strong> работу инициализатора. Итак, вы ум<strong>е</strong>ньшили свой код на дв<strong>е</strong> строчки!<br />

joe = new G u y O { Cash = 50, Name = "Joe" };<br />

Ново<strong>е</strong> объявл<strong>е</strong>ни<strong>е</strong> выполня<strong>е</strong>т my ж <strong>е</strong> ф у н к ­<br />

цию , что и прив<strong>е</strong>д<strong>е</strong>нны<strong>е</strong> вначал<strong>е</strong> три<br />

сТ рочт к о д і Но оно короч<strong>е</strong> и пройд<strong>е</strong> для<br />

чт<strong>е</strong>ния.<br />

дальш<strong>е</strong> > 147


н<strong>е</strong>сколько сов<strong>е</strong>тов<br />

G<br />

- з д а н и <strong>е</strong> u H i n J J u n i u B H o ц о н я щ н ь і х к Л а с с о Б<br />

★ Программа должна р<strong>е</strong>шать какую-то задачу.<br />

Обдумайт<strong>е</strong> пробл<strong>е</strong>му. Отв<strong>е</strong>тьт<strong>е</strong> на вопросы: л<strong>е</strong>гко ли <strong>е</strong><strong>е</strong> под<strong>е</strong>лить на н<strong>е</strong>сколько част<strong>е</strong>й,<br />

и как бы вы объяснили <strong>е</strong><strong>е</strong> другому ч<strong>е</strong>лов<strong>е</strong>ку?<br />

—у --------- ^<br />

Мн<strong>е</strong> нужно сравнить<br />

н<strong>е</strong>сколько маршрутов и<br />

выбрать самый короткий....<br />

★ С какими р<strong>е</strong>альными объ<strong>е</strong>ктами работа<strong>е</strong>т программа?<br />

Программ<strong>е</strong> кормл<strong>е</strong>ния животных в зоопарк<strong>е</strong> нав<strong>е</strong>рняка потр<strong>е</strong>буются классы<br />

для различных видов корма и различных видов животных.<br />

ROAD CLOSED<br />

CHEMIN FERMÉ<br />

І<br />

★ Присваивайт<strong>е</strong> классам и м<strong>е</strong>тодам значимы<strong>е</strong> им<strong>е</strong>на.<br />

Други<strong>е</strong> пользоват<strong>е</strong>ли должны понимать назнач<strong>е</strong>ни<strong>е</strong> классов и м<strong>е</strong>тодов по виду их<br />

им<strong>е</strong>н.<br />

★ Ищит<strong>е</strong> сходство м<strong>е</strong>жду классами.<br />

Классы, выполняющи<strong>е</strong> одинаковы<strong>е</strong> функции, им<strong>е</strong><strong>е</strong>т смысл объ<strong>е</strong>динить. В сист<strong>е</strong>м<strong>е</strong>,<br />

производящ<strong>е</strong>й батончики, мож<strong>е</strong>т быть н<strong>е</strong>сколько турбин, но для закрытия клапана<br />

достаточно одного м<strong>е</strong>тода, в котором ном<strong>е</strong>р турбины буд<strong>е</strong>т использован в кач<strong>е</strong>ств<strong>е</strong><br />

парам<strong>е</strong>тра.<br />

П<strong>е</strong>р<strong>е</strong>крытаяДорога к<br />

Названи<strong>е</strong><br />

Тупик<br />

Длина<br />

Названи<strong>е</strong>Улицы<br />

ПричинаЗакрытия<br />

ПоискОбъ<strong>е</strong>здаО<br />

Расч<strong>е</strong>тЗад<strong>е</strong>ржкиО<br />

О бъ <strong>е</strong>зд<br />

Названи<strong>е</strong><br />

Длина<br />

ПричиныЗакрытия<br />

ПоискОбъ<strong>е</strong>здаО<br />

Расч<strong>е</strong>тЗад<strong>е</strong>ржкиО<br />

148 глава 3


объ<strong>е</strong>кты, по порядку стройся!<br />

к р а ш <strong>е</strong> н и <strong>е</strong><br />

Добавьт<strong>е</strong> кнопки к программ<strong>е</strong> «В<strong>е</strong>с<strong>е</strong>лимся с <strong>Дж</strong>о и Бобом», чтобы заставить парн<strong>е</strong>й<br />

п<strong>е</strong>р<strong>е</strong>давать друг другу д<strong>е</strong>ньги.<br />

О<br />

П рисвойт<strong>е</strong> экз<strong>е</strong>мпляру Bob начальны<strong>е</strong> знач<strong>е</strong>ния при помощ и<br />

ини циал изатора<br />

Вы уж<strong>е</strong> прод<strong>е</strong>лывали эту оп<strong>е</strong>рацию с экз<strong>е</strong>мпляром Joe. Потр<strong>е</strong>нируйт<strong>е</strong>сь<br />

в работ<strong>е</strong> с инициализатором объ<strong>е</strong>ктов <strong>е</strong>щ<strong>е</strong> раз.<br />

Если вы посп<strong>е</strong>шили и уж<strong>е</strong> щ<strong>е</strong>лкнули<br />

Нй кнопк<strong>е</strong>, удалит<strong>е</strong> <strong>е</strong><strong>е</strong>, добавьт<strong>е</strong><br />

заново и присвойт<strong>е</strong> ново<strong>е</strong> имя.<br />

Зат<strong>е</strong>м удалит<strong>е</strong> старый м<strong>е</strong>тоду<br />

button3_Click() и добавьт<strong>е</strong> новый. \<br />

Ещ<strong>е</strong> дв<strong>е</strong> кнопки для срормы \<br />

Пусть при щ<strong>е</strong>лчк<strong>е</strong> на п<strong>е</strong>рвой кнопк<strong>е</strong> <strong>Дж</strong>о отда<strong>е</strong>т Бобу 10 долларов, а !<br />

при щ<strong>е</strong>лчк<strong>е</strong> на второй Боб да<strong>е</strong>т <strong>Дж</strong>о 5 долларов. П<strong>е</strong>р<strong>е</strong>д двойным щ<strong>е</strong>лчком<br />

на кнопк<strong>е</strong> пом<strong>е</strong>няйт<strong>е</strong> <strong>е</strong><strong>е</strong> имя в окн<strong>е</strong> Properties, используя свойство<br />

«(Name)». П<strong>е</strong>рвой кнопк<strong>е</strong> присвойт<strong>е</strong> имя joeGivesToBob, а второй —имя<br />

bobGivesToJoe.<br />

Щ Fun with Joe and Bob<br />

Joe has $50<br />

Эта кнопка заставля<strong>е</strong>т<br />

Ажо отдать й-О долла<br />

ров 5обу, поэтому воспользуйт<strong>е</strong>сь<br />

свойством<br />

«(Name)» в окн<strong>е</strong> Properties,<br />

чтобы присвоить <strong>е</strong>й иМЯ<br />

JoeGivesToBob. \<br />

Bob has $100<br />

ТТтє b a* has $100<br />

Give 510 to<br />

Joe<br />

Joe gives S10<br />

to Bob<br />

Receive S5<br />

from Bob<br />

Bob gives 55<br />

to Joe<br />

Эта кнопка заставля<strong>е</strong>т<br />

Зоба отдать <strong>Дж</strong>о<br />

долларов. Присвойт<strong>е</strong> <strong>е</strong>й<br />

имя oobC^ivesToJoe.<br />

J<br />

О Заставим кнопки работать<br />

Дважды щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> joeG ivesToB ob в конструктор<strong>е</strong>. Форм<strong>е</strong> буд<strong>е</strong>т<br />

добавл<strong>е</strong>н м<strong>е</strong>тод joeG ivesT oB ob_C lick (), который запуска<strong>е</strong>тся при любом<br />

щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong>. Пусть этот м<strong>е</strong>тод заставля<strong>е</strong>т <strong>Дж</strong>о отдавать 10 долларов<br />

Бобу. Якяждьт щ<strong>е</strong>лкнит<strong>е</strong> на второй кнопк<strong>е</strong> и заставьт<strong>е</strong> новый м<strong>е</strong>тод<br />

Ь obG ivesT oJoe_C lick () п<strong>е</strong>р<strong>е</strong>дать 5 долларов от Боба к <strong>Дж</strong>о. Уб<strong>е</strong>дит<strong>е</strong>сь,<br />

что посл<strong>е</strong> п<strong>е</strong>р<strong>е</strong>дачи д<strong>е</strong>н<strong>е</strong>г форма обновля<strong>е</strong>тся.<br />

дальш<strong>е</strong> > 149


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

а ж н ш <strong>е</strong><br />

Вот как стала выгляд<strong>е</strong>ть программа посл<strong>е</strong> того, как к н<strong>е</strong>й добавили кнопки п<strong>е</strong>р<strong>е</strong>дачи д<strong>е</strong>н<strong>е</strong>г<br />

от Боба к <strong>Дж</strong>о и обратно.<br />

у г ш ш г<br />

p u b l i c p a r t i a l c l a s s Forml : Form {<br />

Guy j o e ;<br />

Guy bob;<br />

i n t bank = 100;<br />

Это инициализаторы<br />

одь<strong>е</strong>ктов для двух<br />

экз<strong>е</strong>мпляров класса Quy.<br />

p u b l i c F o r m l0 {<br />

}<br />

I n it i a l iz e C o m p o n e n t O ;<br />

b o b « new G uyO { C ash = 1 0 0 , Name * "Bob" } ;<br />

j o e a new Q uyO { C ash = 5 0 , Name = "Joe" } ;<br />

U pdateForm O ;<br />

Важно<br />

помнить,<br />

кто да<strong>е</strong>т .<br />

д<strong>е</strong>ньги, \ J<br />

а кто их \<br />

получа<strong>е</strong>т, j<br />

V<br />

p u b l i c v o id U pdateForm O<br />

}<br />

j o e s C a s h L a b e l. T e x t =<br />

{<br />

j o e . Name +<br />

b o b sC a sh L a b e l.T e x t = bob.Nam e +<br />

b a n k C a sh L a b el. T ex t = "B банк<strong>е</strong> $'<br />

" им<strong>е</strong><strong>е</strong>т $"<br />

" им <strong>е</strong><strong>е</strong>т $"<br />

+ bank;<br />

+ jo e .C a s h ,<br />

+ b o b .C a sh ,<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

i f (bank >= 10) {<br />

}<br />

bank -= j o e .R e c e i v e C a s h (1 0 );<br />

U p dateF orm ( );<br />

} e l s e {<br />

}<br />

M essageB ox.Show ("B банк<strong>е</strong> н<strong>е</strong>т д <strong>е</strong> н <strong>е</strong> г ." ) ;<br />

p r i v a t e v o i d b u t t o n 2 _ C l i c k ( o b j e c t s e n d e r , E ven tA rgs e) {<br />

bank += b o b .G iv e C a s h (5 );<br />

U pdateForm O ;<br />

}<br />

p r i v a t e v o i d j o e G iv e s T o B o b C l lc k ( o b j e c t s e n d e r , E v e n tA r g s e ) {<br />

b o b . R e c e iv e C a s h (j o e . O iv eC a sh (10));<br />

U pdateF orm ( ) ;<br />

________ _<br />

}<br />

p r i v a t e v o i d b o b G iv e s T o J o e _ C X ic k (o b je c t s e n d e r , E v e n tA r g s e ) {<br />

j o e .R e c e iv e C a s h ( b o b .G iv e C a s h ( 5 ))г<br />

U p d a teF o rm O ;<br />

}<br />

Чтобы заст а­<br />

вить <strong>Дж</strong>о дать<br />

д<strong>е</strong>ньги 5обу, мы<br />

вызыва<strong>е</strong>м м <strong>е</strong> ­<br />

тод GiveCashQ<br />

и п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>м возвраща<strong>е</strong>мо<strong>е</strong><br />

им<br />

знач<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тоду<br />

ReceiveCashQ.<br />

Р<strong>е</strong>зультаты<br />

работы м<strong>е</strong>тода<br />

GiveCashQ используются<br />

в кач<strong>е</strong>ств<strong>е</strong> пара ~<br />

м<strong>е</strong>тра м<strong>е</strong>тода<br />

R.eceiveCashQ.


объ<strong>е</strong>кты, по порядку стройся!<br />

<strong>е</strong> Ш <strong>е</strong> н и <strong>е</strong><br />

® бас:с:<strong>е</strong>^1Н<strong>е</strong><br />

Тр<strong>е</strong>бовалось расположить пр<strong>е</strong>дставл<strong>е</strong>нны<strong>е</strong><br />

в басс<strong>е</strong>йн<strong>е</strong> фрагм<strong>е</strong>нты кода на<br />

пустых строчках таким образом, чтобы<br />

в итог<strong>е</strong> получилась работающая<br />

программа. Вот как это нужно было<br />

сд<strong>е</strong>лать:<br />

p u b lic p a r t i a l c l a s s Forml<br />

{<br />

: Form<br />

p r iv a t e v o id b u t t o n l_ C lic k ( o b j e c t se n d e r , E ventA rgs e)<br />

{<br />

S t r in g r e s u l t =<br />

Echo e l = new E ch o O ;<br />

Echo eZ = new Ecko( );<br />

Вот правильный отв<strong>е</strong>т.<br />

А это отв<strong>е</strong>т на<br />

дополнит<strong>е</strong>льный вопрос!<br />

Еско eZ = <strong>е</strong>1;<br />

int X = 0;<br />

while ( ^ ^ ^ ) {<br />

r e s u l t = r e s u l t + e l . H e l l o 0<br />

ei-.count = ei-.count + Д-;__<br />

if { X == 3 ) {<br />

+ "\n";<br />

e 2 . co u n t = e 2 .c o u n t + 1;<br />

}<br />

i f ) {<br />

<strong>е</strong> 2 . co u n t = <strong>е</strong> 2 . co u n t + e l.c o u n t ;<br />

x = X + 1;<br />

}<br />

MessageBox.Show(result + "Count; " + e2.count)<br />

c l a s s Echo {<br />

p u b lic i n t count = 0 ;<br />

p u b lic s t r i n g HelloQ {<br />

}<br />

r e tu r n " h e l l o o o o .. ." ;<br />

дальш<strong>е</strong> * 151


4 щ ипь! и ссылки<br />

10:00 утра. ^<br />

Куда под<strong>е</strong>вались наши данны<strong>е</strong>?<br />

Б<strong>е</strong>з д а н н ы х п р о гр а л ш ы б <strong>е</strong> с п о л <strong>е</strong> з н ы .<br />

Взяв информацию от пользоват<strong>е</strong>л<strong>е</strong>й, вы производит<strong>е</strong> новую инф орм а­<br />

цию, чтобы в<strong>е</strong>рнуть <strong>е</strong><strong>е</strong> им ж<strong>е</strong>. Практич<strong>е</strong>ски вс<strong>е</strong> в программировании связано<br />

с обработ кой данны х т<strong>е</strong>м или иным способом. В этой глав<strong>е</strong> вы<br />

познакомит<strong>е</strong>сь с использу<strong>е</strong>мыми в С # т ипами данных, узна<strong>е</strong>т<strong>е</strong> м<strong>е</strong>тоды<br />

работы с ними и даж<strong>е</strong> ужасный с<strong>е</strong>кр<strong>е</strong>т объ<strong>е</strong>кт ов (только т-с-с-с... объ<strong>е</strong>кты<br />

— это тож<strong>е</strong> данны<strong>е</strong>).


н<strong>е</strong> мои тип<br />

Tun п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т, каки<strong>е</strong> данны<strong>е</strong> она MO)kenfi сохранять<br />

Колич<strong>е</strong>ство встро<strong>е</strong>нных типов <strong>C#</strong> в<strong>е</strong>лико, и каждый из них хранит свой собств<strong>е</strong>нный вид данных.<br />

С н<strong>е</strong>которыми из них вы уж<strong>е</strong> познакомились и даж<strong>е</strong> поработали. Пришла пора узнать о н<strong>е</strong>изв<strong>е</strong>стных<br />

дос<strong>е</strong>л<strong>е</strong> типах, которы<strong>е</strong> крайн<strong>е</strong> пригодятся вам в будущ<strong>е</strong>м.<br />

Буква<br />

«и»<br />

означа<strong>е</strong>т<br />

«б<strong>е</strong>з<br />

знака».<br />

Наибол<strong>е</strong><strong>е</strong> использу<strong>е</strong>м ы <strong>е</strong> типы<br />

Вряд ли вас удивит тот факт, что типы i n t , s tr i n g , b o o l и d o u b le являются<br />

самыми распростран<strong>е</strong>нными.<br />

★ i n t хранит ц<strong>е</strong>лы<strong>е</strong> числа от -2 147483 648 до 2147483647;<br />

★<br />

★<br />

★<br />

s t r i n g хранит т<strong>е</strong>кст произвольной длины (в том числ<strong>е</strong> и пустую строку<br />

b o o l хранит логич<strong>е</strong>ски<strong>е</strong> знач<strong>е</strong>ния —t r u e или f a ls e ;<br />

d o u b le хранит в<strong>е</strong>щ<strong>е</strong>ств<strong>е</strong>нны<strong>е</strong> числа от ±5.0 •10’^'* до ±1.7 -10“ ®до 16 значащих<br />

цифр. Подобный диапазон выглядит странным и сложным, но на<br />

самом д<strong>е</strong>л<strong>е</strong> вс<strong>е</strong> оч<strong>е</strong>нь просто. Словосоч<strong>е</strong>тани<strong>е</strong> «значащи<strong>е</strong> цифры» указыва<strong>е</strong>т<br />

на точность числа: и 35048 410 000000, и 1743059, и 14.43857,<br />

и 0.00004374155 им<strong>е</strong>ют по с<strong>е</strong>мь значащих цифр. Запись 10-’“ означа<strong>е</strong>т,<br />

что вы мож<strong>е</strong>т<strong>е</strong> хранить любо<strong>е</strong> число н<strong>е</strong> больш<strong>е</strong> 10®”*, при условии что<br />

колич<strong>е</strong>ство значащих цифр н<strong>е</strong> пр<strong>е</strong>выша<strong>е</strong>т 16. С другой стороны диапазона<br />

— позволя<strong>е</strong>т хранить числа н<strong>е</strong> м<strong>е</strong>ньш<strong>е</strong> 10"*^^...но как н<strong>е</strong>сложно<br />

догадаться, опять ж<strong>е</strong> при условии, что колич<strong>е</strong>ство значащих цифр н<strong>е</strong><br />

пр<strong>е</strong>выша<strong>е</strong>т 16.<br />

Ц <strong>е</strong>лочисл<strong>е</strong>нны <strong>е</strong> типы<br />

Когда оп<strong>е</strong>ративная память компьют<strong>е</strong>ра стоила дорого, а проц<strong>е</strong>ссоры работали<br />

м<strong>е</strong>дл<strong>е</strong>нно, использовани<strong>е</strong> н<strong>е</strong>в<strong>е</strong>рного типа данных могло с<strong>е</strong>рь<strong>е</strong>зно зам<strong>е</strong>длить<br />

работу программы. К счастью, вр<strong>е</strong>м<strong>е</strong>на изм<strong>е</strong>нились и т<strong>е</strong>п<strong>е</strong>рь для хран<strong>е</strong>ния ц<strong>е</strong>лых<br />

чис<strong>е</strong>л в большинств<strong>е</strong> случа<strong>е</strong>в достаточно типа in t. Но иногда тр<strong>е</strong>буются<br />

дополнит<strong>е</strong>льны<strong>е</strong> возможности, поэтому в <strong>C#</strong> присутствуют таки<strong>е</strong> типы как;<br />

★<br />

★<br />

★<br />

★<br />

★<br />

★<br />

★<br />

b y te хранит ц<strong>е</strong>лы<strong>е</strong> числа от О до 255;<br />

s b y te хранит ц<strong>е</strong>лы<strong>е</strong> числа от -128 до 127;<br />

s h o r t хранит ц<strong>е</strong>лы<strong>е</strong> числа от -32 768 до 32 767;<br />

u s h o rt хранит ц<strong>е</strong>лы<strong>е</strong> числа от О до 65,535;<br />

u i n t хранит ц<strong>е</strong>лы<strong>е</strong> числа от О до 4 294 967 295;<br />

long хранит ц<strong>е</strong>лы<strong>е</strong> числа в диапазон<strong>е</strong> от минус до плюс 9 триллионов;<br />

u lo n g хранит ц<strong>е</strong>лы<strong>е</strong> числа от О до прим<strong>е</strong>рно 18 триллионов.<br />

^<br />

форма пр<strong>е</strong>дставл<strong>е</strong>ния,<br />

при<br />

которой число<br />

хранится в вид<strong>е</strong><br />

мантиссы и показат<strong>е</strong>ля<br />

ст<strong>е</strong>п<strong>е</strong>ни,<br />

называ<strong>е</strong>тся числом<br />

с плавающ<strong>е</strong>й точкой<br />

(запятой).<br />

Часто вы м<strong>е</strong>ня<strong>е</strong>т<strong>е</strong><br />

(/ т и п п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

Вуква «5» означа<strong>е</strong>т<br />

«со знаком». То <strong>е</strong>сть<br />

число мож<strong>е</strong>т быть<br />

отрицат<strong>е</strong>льным.<br />

Ьыть р<strong>е</strong>ш<strong>е</strong>на и при<br />

помощи «циклыч<strong>е</strong><br />

ского присваивания»<br />

о котором МЫ по<br />

говорим ч<strong>е</strong>р<strong>е</strong>з пару<br />

страниц.<br />

154 глава 4


типы и ссылки<br />

Типы для хран<strong>е</strong>ния оч<strong>е</strong>нь больших и оч<strong>е</strong>нь мал<strong>е</strong>ньких Ч И С б Л<br />

Иногда с<strong>е</strong>ми значащих цифр оказыва<strong>е</strong>тся н<strong>е</strong>достаточно. Быва<strong>е</strong>т так, что 10*® —н<strong>е</strong>достаточно<br />

большо<strong>е</strong> число, а 10"“*^ —н<strong>е</strong>достаточно мало<strong>е</strong>. С такими пробл<strong>е</strong>мами сталкиваются программы финансового<br />

уч<strong>е</strong>та и научных иссл<strong>е</strong>дований, и для них в С# пр<strong>е</strong>дназнач<strong>е</strong>ны дополнит<strong>е</strong>льны<strong>е</strong> типы:<br />

★<br />

f l o a t хранит любо<strong>е</strong> число в диапазон<strong>е</strong> от ±1.5- 10'^'’до±3.4 ■10*® с 7 значащими цифрами;<br />

~^^с'таЫасто* d ecim al хранит любо<strong>е</strong> число в диапазон<strong>е</strong> от ±1.0 • 10'^® до ±7.9 • 10^® с 28-29 значащими<br />

встр<strong>е</strong>ча<strong>е</strong>тся цифрами.<br />

Свойство Value<br />

6 программах у п<br />

« К о н с т й н т й » — это ^ ^ с л о к о -<br />

эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния<br />

numericUpPown<br />

финансового<br />

торо<strong>е</strong> 6t>! вводит<strong>е</strong> в код. В Ьы<br />

уч<strong>е</strong>та.<br />

ЛX----' раж<strong>е</strong>ним «int і - 5;» s — это<br />

^принадл<strong>е</strong>жит<br />

константа.<br />

t/ПМЛІЛЛйН<br />

данных<br />

Константы тож<strong>е</strong> им <strong>е</strong>ю т тип<br />

decimal.<br />

Числа, использу<strong>е</strong>мы<strong>е</strong> в программ<strong>е</strong> на С#, называются константами... и вс<strong>е</strong> они<br />

принадл<strong>е</strong>жат какому-то типу. Попробуйт<strong>е</strong> написать код, присваивающий знач<strong>е</strong>ни<strong>е</strong><br />

1 4 .7 п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной типа in t:<br />

Description<br />

i n t m y in t = 1 4 .7 ;<br />

При компиляции вы увидит<strong>е</strong>:<br />

^ 1<br />

Carmot imptkrtty convert type 'double' to ‘inf. An<br />

explicit conversion Bcists (are you missing # cast?)<br />

ИСР сообща<strong>е</strong>т, что константа 1 4 . 7 принадл<strong>е</strong>жит типу d o iib le . Вставив в кон<strong>е</strong>ц<br />

букву F (1 4 . 7F ), вы пом<strong>е</strong>ня<strong>е</strong>т<strong>е</strong> тип константы на f l o a t . А в форм<strong>е</strong> 1 4 . 7М оно<br />

буд<strong>е</strong>т принадл<strong>е</strong>жать уж<strong>е</strong> типу d e c im al.<br />

«М» означа<strong>е</strong>т «m oney»<br />

(д<strong>е</strong>ньги). Я н<strong>е</strong> шучу!<br />

Ещ <strong>е</strong> н<strong>е</strong>сколько встро<strong>е</strong>нны х типов<br />

Для хран<strong>е</strong>ния <strong>е</strong>диничных символов, наприм<strong>е</strong>р, Q, 7 или $ использу<strong>е</strong>тся<br />

тип c h a r. Константы этого типа вс<strong>е</strong>гда заключаются в одиночны<strong>е</strong> кавычки<br />

(' X', ' 3 '). В кавычки можно заключить и <strong>е</strong>вс-посл<strong>е</strong>доват<strong>е</strong>льность (' \ п ' —<br />

это п<strong>е</strong>р<strong>е</strong>нос строки, ' \ t ' —знак табуляции). Хотя в код<strong>е</strong> эти посл<strong>е</strong>доват<strong>е</strong>льности<br />

фигурируют в вид<strong>е</strong> пары символов, программа хранит их в памяти<br />

в вид<strong>е</strong> одного.<br />

И након<strong>е</strong>ц тип таких данных как o b je c t. Вы уж<strong>е</strong> получали объ<strong>е</strong>кты, создавая<br />

экз<strong>е</strong>мпляры классов. Любой из них мог быть п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной типа оЬj e c t.<br />

О том, как работают объ<strong>е</strong>кты и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>, которы<strong>е</strong> на них ссылаются, мы<br />

<strong>е</strong>щ<strong>е</strong> поговорим в этой глав<strong>е</strong>.<br />

W T V P M<br />

Попытавшись присвоить<br />

константу<br />

типа float п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

типа double<br />

или decimal, вы<br />

увидит<strong>е</strong> окно с подсказкой.<br />

К<br />

"О связи м<strong>е</strong>жду<br />

типами char<br />

и byte вы узна<strong>е</strong>т<strong>е</strong><br />

о глав<strong>е</strong> ■?.<br />

в Windows 7 у Калькулятора сущ<strong>е</strong>ству<strong>е</strong>т и р<strong>е</strong>жим «Программист<br />

», позволяющий использовать бинарны<strong>е</strong> и д<strong>е</strong>сятичны<strong>е</strong><br />

числа одновр<strong>е</strong>м<strong>е</strong>нно!<br />

Встро<strong>е</strong>нный калькулятор Windows можно использовать для п<strong>е</strong>р<strong>е</strong>вода д<strong>е</strong>сятичных чис<strong>е</strong>л в двоичны<strong>е</strong>:<br />

п<strong>е</strong>р<strong>е</strong>йдит<strong>е</strong> в Инж<strong>е</strong>н<strong>е</strong>рный р<strong>е</strong>жим, вв<strong>е</strong>дит<strong>е</strong> число, и установит<strong>е</strong> п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>ль в полож<strong>е</strong>ни<strong>е</strong> Bin. Для<br />

обратного пр<strong>е</strong>образования достаточно в<strong>е</strong>рнуть п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>ль в полож<strong>е</strong>ни<strong>е</strong> Dec. Прод<strong>е</strong>лайт<strong>е</strong> эту оп<strong>е</strong>рацию<br />

с пограничны м и знач<strong>е</strong>ниям и ц<strong>е</strong>лы х ти пов (скаж<strong>е</strong>м, с -32 768 и 255). Вы мож<strong>е</strong>т<strong>е</strong> объяснить,<br />

поч<strong>е</strong>му в <strong>C#</strong> используются им<strong>е</strong>нно таки<strong>е</strong> знач<strong>е</strong>ния?<br />

дальш<strong>е</strong> у 155


взять д<strong>е</strong>ньги на морож<strong>е</strong>но<strong>е</strong><br />

Наглядно<strong>е</strong> пр<strong>е</strong>дстабл<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

Данны<strong>е</strong> занимают м<strong>е</strong>сто в памяти. (Помнит<strong>е</strong> кучу из пр<strong>е</strong>дыдущ<strong>е</strong>й<br />

главы?) Значит, сл<strong>е</strong>ду<strong>е</strong>т учитывать, сколько пространства<br />

тр<strong>е</strong>бу<strong>е</strong>тся под строку или число в программ<strong>е</strong>. Им<strong>е</strong>нно<br />

поэтому мы пользу<strong>е</strong>мся п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными. Они позволяют выд<strong>е</strong>лить<br />

достаточно м<strong>е</strong>ста для хран<strong>е</strong>ния данных.<br />

Пр<strong>е</strong>дставим п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную в вид<strong>е</strong> стакана. В С# используются<br />

разны<strong>е</strong> стаканы для хран<strong>е</strong>ния данных разных типов. Ч<strong>е</strong>м<br />

больш<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная, т<strong>е</strong>м больший стакан <strong>е</strong>й тр<strong>е</strong>бу<strong>е</strong>тся.<br />

Н<strong>е</strong> вс<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> попадают<br />

в кучу. Значимы<strong>е</strong> п^ипы хранят<br />

данны<strong>е</strong> в другой части памяти,<br />

которая называ<strong>е</strong>тся ст<strong>е</strong>ком,<br />

дол<strong>е</strong><strong>е</strong> подробно мы поговорим<br />

о5 этом глав<strong>е</strong> 14.<br />

Tun int<br />

хран<strong>е</strong>ния ц<strong>е</strong> з ^47.<br />

н<strong>е</strong> больил<strong>е</strong> 2. 3-^<br />

Tun short хранит ц<strong>е</strong>лы<strong>е</strong><br />

числа до 32.767.<br />

чис<strong>е</strong>л<br />

long<br />

64<br />

int__ short byte<br />

32 16 8<br />

Tun byte хро-нит<br />

от О до 7-55.<br />

цифры<br />

Колич<strong>е</strong>ство битов, выд<strong>е</strong>ля<strong>е</strong>мо<strong>е</strong> под<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную в мом<strong>е</strong>нт <strong>е</strong><strong>е</strong> обьявл<strong>е</strong>ния.<br />

Числа с д<strong>е</strong>сятичной точкой хранятся по другому. Для большинства<br />

таких чис<strong>е</strong>л подойд<strong>е</strong>т тип f l o a t , занимающий м<strong>е</strong>ньш<strong>е</strong><br />

вс<strong>е</strong>го м<strong>е</strong>ста в памяти. Если вам тр<strong>е</strong>бу<strong>е</strong>тся большая точность,<br />

используйт<strong>е</strong> тип d ouble. А для финансовых прилож<strong>е</strong>ний, в которых<br />

хранится информация о курсах валют, использу<strong>е</strong>тся тип<br />

d ecim al.<br />

Впроч<strong>е</strong>м, р<strong>е</strong>чь н<strong>е</strong> только о цифрах. (Вы ж<strong>е</strong> н<strong>е</strong> налива<strong>е</strong>т<strong>е</strong> горячий<br />

коф<strong>е</strong> в пластиковый стаканчик, а холодный в бумажный.)<br />

Компилятор <strong>C#</strong> ум<strong>е</strong><strong>е</strong>т обрабатывать и н<strong>е</strong>-числ<strong>е</strong>нны<strong>е</strong> типы данных.<br />

Тип c h a r хранит один символ, а тип s t r i n g позволя<strong>е</strong>т<br />

хранить ц<strong>е</strong>лый набор символов. При этом под объ<strong>е</strong>кт s t r i n g<br />

н<strong>е</strong> выд<strong>е</strong>ля<strong>е</strong>тся пр<strong>е</strong>дустановл<strong>е</strong>нно<strong>е</strong> м<strong>е</strong>сто в памяти. Он расширя<strong>е</strong>тся<br />

в зависимости от колич<strong>е</strong>ства пом<strong>е</strong>ща<strong>е</strong>мой в н<strong>е</strong>го информации.<br />

А тип данных b o o l хранит знач<strong>е</strong>ния true и false, с которыми<br />

вы уж<strong>е</strong> сталкивались при работ<strong>е</strong> с оп<strong>е</strong>ратором i f .<br />

156 глава 4<br />

указать.<br />

string<br />

зависит от<br />

разм<strong>е</strong>ра<br />

строки


типы и ссылки<br />

10 литров 6 S -литробой банк<strong>е</strong><br />

Объявив тип п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, вы фактич<strong>е</strong>ски объясня<strong>е</strong>т<strong>е</strong> компилятору,<br />

как <strong>е</strong><strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т воспринимать. Компилятор видит<br />

стаканы, а н<strong>е</strong> то, что в них налито. Поэтому такой код<br />

работать н<strong>е</strong> буд<strong>е</strong>т:<br />

i n t lea g u esU n d erT h eS ea = 2000 0;<br />

s h o r t sm a lle r L e a g u e s = lea g u esU n d erT h eS ea ;<br />

Хотя число 20 ООО попада<strong>е</strong>т в диапазон, заданный для типа<br />

данных s h o r t , п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная l e a g u e s U n d e r T h e S e a была<br />

объявл<strong>е</strong>на как i n t , и компилятор н<strong>е</strong> мож<strong>е</strong>т положить <strong>е</strong><strong>е</strong><br />

в конт<strong>е</strong>йн<strong>е</strong>р s h o r t . Сл<strong>е</strong>доват<strong>е</strong>льно, вам вс<strong>е</strong>гда нужно сл<strong>е</strong>дить<br />

за совпад<strong>е</strong>ни<strong>е</strong>м типов данных.<br />

К о м п и л я т о р « в и д и т » , ч т о вы п ы т а <strong>е</strong> т <strong>е</strong> .<br />

смысл, так как<br />

^зб<strong>е</strong>жать с и т и ^<br />

^%'^опыт а<strong>е</strong>т <strong>е</strong>сТ!^‘'^ /сог^й<br />

^/^<strong>е</strong>ржимо<strong>е</strong><br />

$когЬ . С о д <strong>е</strong> р ж и м о <strong>е</strong> с т а к а н а m t п р и э т о м н<strong>е</strong><br />

и м <strong>е</strong> <strong>е</strong> т зн а ч <strong>е</strong>н и я .<br />

возьми в руку карандаш_ _ _ _ _ _ _ _ _ _<br />

^Возьм1/<br />

V<br />

Обв<strong>е</strong>дит<strong>е</strong> три оп<strong>е</strong>ратора, которы<strong>е</strong> н<strong>е</strong> будут компилироваться из-за<br />

н<strong>е</strong>совпад<strong>е</strong>ния типов данных или из-за того, что им пытаются присвоить<br />

слишком большо<strong>е</strong> или слишком мал<strong>е</strong>нько<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

i n t h o u r s = 2 4 ;<br />

s t r i n g t a u n t = " y o u r m o t h e r " ;<br />

b y t e d a y s = 3 6 5 ;<br />

b o o l i s D o n e = y e s ;<br />

l o n g r a d i u s = 3 ;<br />

s h o r t RPM = 3 3 ;<br />

c h a r i n i t i a l =<br />

'S '<br />

i n t b a l a n c e = 3 4 5 6 6 7 - 5 6 7 ;<br />

s t r i n g m o n th s = " 1 2 " ;<br />

дальш<strong>е</strong> ► 157


прив<strong>е</strong>д<strong>е</strong>ния<br />

Прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> типов<br />

Посмотрим, что произойд<strong>е</strong>т при попытк<strong>е</strong> назначить<br />

знач<strong>е</strong>ни<strong>е</strong> типа d ecim al п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной типа in t.<br />

V<br />

^<br />

у п |^ а ж н <strong>е</strong> н и <strong>е</strong><br />

Создайт<strong>е</strong> новый про<strong>е</strong>кт и добавьт<strong>е</strong> кнопку. Для м<strong>е</strong>тода<br />

C lic k О этой кнопки напишит<strong>е</strong>:<br />

d e c im a l m yD ecim alV alue = 10;<br />

i n t m y ln tV a lu e = m yD ecim alV alue;<br />

M essageB ox.Sh ow ("T h e m y ln tV a lu e i s " + m y ln tV a lu e );<br />

© Попытавшись запустить программу, вы получит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>:<br />

' Q 1 Effor |; ^ О W aFnings v [h^ О M essages<br />

о<br />

О 1<br />

Description<br />

Cannot tmpKcttly convert type 'd ed m af to ’in f. An ecpttcrt conversion ecists (are you nfiissing a cast?)<br />

Устранит<strong>е</strong> ошибку, пр<strong>е</strong>образовав тип d ecim al в i n t. Вн<strong>е</strong>сит<strong>е</strong> во вторую<br />

строку сл<strong>е</strong>дующи<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ния:<br />

ИСР пр<strong>е</strong>дполага<strong>е</strong>т,<br />

что вы забыли осущ<strong>е</strong>ствить<br />

прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

типов (casting).<br />

i n t m y ln tV a lu e = ( in t ) m yD ecim alV alue;<br />

Этот оп<strong>е</strong>ратор д<strong>е</strong>ла<strong>е</strong>т<br />

прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> типа decimal<br />

к типу int.<br />

Ч т о )к<strong>е</strong> произошло?<br />

Компилятор н<strong>е</strong> позволя<strong>е</strong>т присваивать знач<strong>е</strong>ния н<strong>е</strong>совпадающих типов,<br />

даж<strong>е</strong> <strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная попада<strong>е</strong>т в правильный диапазон. Прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

типа —это объясн<strong>е</strong>ни<strong>е</strong> компилятору, что вы зна<strong>е</strong>т<strong>е</strong> о н<strong>е</strong>совпад<strong>е</strong>нйи<br />

типов, но в данном конкр<strong>е</strong>тном случа<strong>е</strong> осознанно осущ<strong>е</strong>ствля<strong>е</strong>т<strong>е</strong> оп<strong>е</strong>рацию<br />

присваивания.<br />

В<strong>е</strong>рнит<strong>е</strong>сь в начало<br />

'пр<strong>е</strong>дыдущ<strong>е</strong>й главы<br />

« посмотрит<strong>е</strong>, как<br />

^ прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> типов<br />

использовалось для<br />

і^<strong>е</strong>р<strong>е</strong>дачи знач<strong>е</strong>ния<br />

^J^'^encUpDown ф орм<strong>е</strong><br />

Talker Tester<br />

а ж н ш <strong>е</strong><br />

s h o r t у = 7 8 0 0 0 ;<br />

Вот оп<strong>е</strong>раторы, которы<strong>е</strong> н<strong>е</strong> будут компилироваться из-за н<strong>е</strong>совпад<strong>е</strong>ния<br />

типов данных или из-за того, что им пытаются присвоить<br />

слишком большо<strong>е</strong> или слишком мал<strong>е</strong>нько<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

Слишком большо<strong>е</strong><br />

число. Тип short<br />

хранит знач<strong>е</strong>ния от<br />

-ЗЯ,767 до 32..,762.<br />

Сb y t e d a y s = 3 6 5 ;<br />

b o o l i s D o n e = y e s<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной типа bool<br />

можно присвоить только<br />

знач<strong>е</strong>ния true или false.<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> т ш а К<br />

хранят числа do % s f<br />

158 глава 4


типы и ссылки<br />

Автоматич<strong>е</strong>ская корр<strong>е</strong>кция слишком<br />

больших знач<strong>е</strong>ний<br />

Вы уж<strong>е</strong> вид<strong>е</strong>ли, что тип d ecim al мож<strong>е</strong>т быть прив<strong>е</strong>д<strong>е</strong>н<br />

к типу i n t. Получа<strong>е</strong>тся, любо<strong>е</strong> число мож<strong>е</strong>т быть прив<strong>е</strong>д<strong>е</strong>но<br />

к любому типу. Но это н<strong>е</strong> означа<strong>е</strong>т сохран<strong>е</strong>ни<strong>е</strong> знач<strong>е</strong>ния.<br />

Прив<strong>е</strong>д<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную типа i n t со знач<strong>е</strong>ни<strong>е</strong>м 365<br />

к типу b y te . Число 365 выходит за границы диапазона<br />

этого типа. Но вм<strong>е</strong>сто сообщ<strong>е</strong>ния об ошибк<strong>е</strong> произойд<strong>е</strong>т<br />

циклич<strong>е</strong>ско<strong>е</strong> присваивани<strong>е</strong>: наприм<strong>е</strong>р, 256 посл<strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ния<br />

к типу b y te пр<strong>е</strong>вратится в О, 257 —в 1, а 365 —<br />

в 109. Как только вы дойд<strong>е</strong>т<strong>е</strong> до 255, произойд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>ход<br />

к нул<strong>е</strong>вому знач<strong>е</strong>нию.<br />

О О<br />

Ещ<strong>е</strong> в глав<strong>е</strong> 2 я начал<br />

комбинировать строки с<br />

цифрами в окнах диалога!<br />

Получа<strong>е</strong>тся, я вс<strong>е</strong> это вр<strong>е</strong>мя<br />

пр<strong>е</strong>образовывал типы данных?<br />

«о Г э ч З Г *<br />

возьми в руку карандаш<br />

О п<strong>е</strong>рация прив<strong>е</strong>д<strong>е</strong>ния работа<strong>е</strong>т<br />

н<strong>е</strong> со вс<strong>е</strong>ми типам и. Создайт<strong>е</strong> новый про<strong>е</strong>кт,<br />

добавьт<strong>е</strong> кнопку, дважды щ<strong>е</strong>лкнит<strong>е</strong> на н<strong>е</strong>й<br />

и вв<strong>е</strong>дит<strong>е</strong> сл<strong>е</strong>дующи<strong>е</strong> строки. Попытайт<strong>е</strong>сь<br />

построить программу. Зач<strong>е</strong>ркнит<strong>е</strong> строки с<br />

ошибками. Это помож<strong>е</strong>т понять, для каких<br />

типов прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> допустимо, а для каких н<strong>е</strong>т.<br />

i n t m y in t = 10;<br />

b y t e m yByte = (b y te )m y in t;<br />

d o u b le m yDouble = (d o u b le )m y B y te ;<br />

Да! Это д <strong>е</strong>лал за вас оп<strong>е</strong>ратор + .<br />

чВы пользовались оп<strong>е</strong>ратором +, который<br />

автоматич<strong>е</strong>ски пр<strong>е</strong>образовывал данны<strong>е</strong>.<br />

Когда вы добавляли число и логич<strong>е</strong>ско<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> к строк<strong>е</strong>, указанно<strong>е</strong> вами<br />

знач<strong>е</strong>ни<strong>е</strong> автоматич<strong>е</strong>ски пр<strong>е</strong>образовывалось<br />

к типу string. Оп<strong>е</strong>раторы + (или *,<br />

/ или -), прим<strong>е</strong>н<strong>е</strong>нны<strong>е</strong> к знач<strong>е</strong>ниям различных<br />

типов, автоматич<strong>е</strong>ски пр<strong>е</strong>образовывают<br />

м<strong>е</strong>ньший тип в больший. Вот<br />

прим<strong>е</strong>р:<br />

i n t m yInt = 36,<br />

Посл<strong>е</strong> числа, кото­ро<strong>е</strong> присваива<strong>е</strong>тся<br />

—'double m y F loat = 1 6 . 4D;<br />

m yF loat = m y in t + m y F lo a t;<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной типа<br />

double, нужно добавлять<br />

р, чтобы Диапазон знач<strong>е</strong>ний типа i n t больш<strong>е</strong> диапазона<br />

знач<strong>е</strong>ний типа f l o a t , оп<strong>е</strong>ратор +<br />

указать ком ­<br />

пилятору на <strong>е</strong>го пр<strong>е</strong>образу<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную m yint к типу<br />

!лринадл<strong>е</strong>жность f l o a t и только потом прибавля<strong>е</strong>т <strong>е</strong><strong>е</strong> к п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

m<br />

к типу float.<br />

yFloat.<br />

b o o l m yBool =<br />

(b o o l)m y D o u b le;<br />

s t r i n g m y S tr in g = " f a ls e " ;<br />

myBool = (b o o l)m y S tr in g ;<br />

m y S tr in g = ( s t r i n g ) m y i n t ;<br />

m y S tr in g = m y in t . T o S t r in g () ;<br />

myBool =<br />

(b o o l)m y B y te;<br />

myByte = (b y te )m y B o o l;<br />

s h o r t m yShort = ( s h o r t ) m y in t ;<br />

c h a r myChar = ' x ' ;<br />

m y S tr in g = (str in g )m y C h a r;<br />

lo n g myLong = (lo n g )m y in t;<br />

d e c im a l m yDecim al =<br />

(decim al)m yL ong;<br />

m y S tr in g = m y S tr in g + m y in t + myByte<br />

+ m yDouble + myChar;<br />

дальш<strong>е</strong> ► 159


настоящ<strong>е</strong><strong>е</strong> пр<strong>е</strong>образовани<strong>е</strong><br />

иногда прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> типов происходит автоматич<strong>е</strong>ски<br />

Есть два случая, когда вам н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся д<strong>е</strong>лать прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

типов. Автоматич<strong>е</strong>ски эта проц<strong>е</strong>дура выполня<strong>е</strong>тся,<br />

во-п<strong>е</strong>рвых, при пров<strong>е</strong>д<strong>е</strong>нии арифм<strong>е</strong>тич<strong>е</strong>ских оп<strong>е</strong>раций:<br />

l o n g 1 = 1 3 9 4 0 1 9 3 0 ;<br />

s h o r t s = 5 1 6 ;<br />

d o u b l e d = 1 ;<br />

d = d / 1 2 3 . 4 5 6 ;<br />

M e s s a g e B o x . S h o w ( "О тв <strong>е</strong>т " d) ;<br />

В л а г о д а р я о п <strong>е</strong> р а т о р у ^<br />

п р о и с х о д и т п р <strong>е</strong> о б р а з о в а н и <strong>е</strong><br />

т и п а d e c im a l к т и п у s tr in g .<br />

П а р а м <strong>е</strong> т р т и п а<br />

s h o r t в ы ч и т а <strong>е</strong> т с я<br />

из п а р а м <strong>е</strong> т р а т и п а<br />

lo n g , а о п <strong>е</strong> р а т о р =<br />

п р <strong>е</strong> о б р а з у <strong>е</strong> т<br />

р <strong>е</strong> з у л ь т а т к т и п у<br />

d o u b le .<br />

Во-вторых, автоматич<strong>е</strong>ско<strong>е</strong> пр<strong>е</strong>образовани<strong>е</strong> происходит<br />

при объ<strong>е</strong>дин<strong>е</strong>нии строк оп<strong>е</strong>ратором Вс<strong>е</strong> числа<br />

при этом пр<strong>е</strong>образуются к типу string. Рассмотрим прим<strong>е</strong>р,<br />

в котором п<strong>е</strong>рвы<strong>е</strong> дв<strong>е</strong> строки кода написаны правильно,<br />

тр<strong>е</strong>тья н<strong>е</strong> мож<strong>е</strong>т быть скомпилирована.<br />

l o n g X = 1 3 9 4 0 1 9 3 0 ;<br />

M e s s a g e B o x .S h o w (" О т в <strong>е</strong>т " + х ) ;<br />

M e s s a g e B o x .S h o w ( х ) ;<br />

Компилятор выда<strong>е</strong>т сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong> в связи с н<strong>е</strong>правильным<br />

аргум<strong>е</strong>нтом (аргум<strong>е</strong>нтом в <strong>C#</strong> называ<strong>е</strong>тся<br />

знач<strong>е</strong>ни<strong>е</strong>, п<strong>е</strong>р<strong>е</strong>дава<strong>е</strong>мо<strong>е</strong> м<strong>е</strong>тоду в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра).<br />

Парам<strong>е</strong>тр м<strong>е</strong>тода M e s s a g e B o x .S h o w O долж<strong>е</strong>н принадл<strong>е</strong>жать<br />

типу s t r i n g , код ж<strong>е</strong> п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

типа l o n g . Впроч<strong>е</strong>м, вы л<strong>е</strong>гко мож<strong>е</strong>т<strong>е</strong> осущ<strong>е</strong>ствить<br />

это пр<strong>е</strong>образовани<strong>е</strong> при помощи м<strong>е</strong>тода T o S t r i n g ().<br />

Этим м<strong>е</strong>тодом обладают вс<strong>е</strong> объ<strong>е</strong>кты. (И вс<strong>е</strong> созданны<strong>е</strong><br />

вами классы им<strong>е</strong>ют м<strong>е</strong>тод T o S t r i n g ( ) , возвращающий<br />

имя класса.) Им<strong>е</strong>нно с <strong>е</strong>го помощью можно пр<strong>е</strong>образовать<br />

X в парам<strong>е</strong>тр м<strong>е</strong>тода M e s s a g e B o x . Show ():<br />

M e s s a g e B o x . S h o w ( x . T o S t r i n g ( ) ) ;<br />

н<strong>е</strong>ни<strong>е</strong>- - - - - - - - - - - - - - - - - - -<br />

)'^<strong>е</strong>ш<strong>е</strong>нк<strong>е</strong><br />

Итак, вы уб <strong>е</strong>д и л ись , что прив<strong>е</strong>д <strong>е</strong>ни<strong>е</strong> возм<br />

ож но д ал <strong>е</strong>ко н<strong>е</strong> д ля вс<strong>е</strong>х ти п о в . Зач<strong>е</strong>ркнуты<strong>е</strong><br />

строки н<strong>е</strong> позволяют осущ<strong>е</strong>ствить<br />

постро<strong>е</strong>ни<strong>е</strong> программы.<br />

i n t m y in t = 10;<br />

b y t e myByte = (b y te )m y in t;<br />

d o u b le myDouble = (d o u b le)m y B y te ;<br />

bqrri—иуВв<strong>е</strong> 1 ■—— —<br />

s t r i n g m y S trin g = " f a l s e " ;<br />

-royBool—=—(Jaooif) my Ot rin g-,-^<br />

mygtrrreg--~~4-&fe*4:ag-)-my»m‘fe-;—^<br />

m y S trin g = m y in t . T o S t r in g ();<br />

-«¥E ucl1—^=—(-b e o l ) myByt«-,-<br />

—(fa^'tTc:') myOoa lf----<br />

s h o r t m yShort = (s h o r t)m y in t;<br />

ch a r myChar = ' x ' ;<br />

jny S t rirag—^—(-at r in g ) m yehag;<br />

lo n g myLong = (lo n g )m y in t;<br />

d e c im a l myDecim al =<br />

(decim al)m yL ong;<br />

m y S trin g = m y S trin g + m y in t + myByte<br />

+ myDouble + myChar;<br />

160 глава 4


типы и ссылки<br />

Аргум<strong>е</strong>нты м<strong>е</strong>тода дол)кньі б ы ть совм<strong>е</strong>стимы с типами парам<strong>е</strong>тров<br />

Попытайт<strong>е</strong>сь вызвать м<strong>е</strong>тод Me s sageB ox. Show ( 12 З ), то <strong>е</strong>сть п<strong>е</strong>р<strong>е</strong>дать ^<br />

м<strong>е</strong>тоду M essageBox.Show () константу (123) вм<strong>е</strong>сто строки. ИСР н<strong>е</strong><br />

позволит построить программу. Появится сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>: «Аргум<strong>е</strong>нт<br />

‘1’: пр<strong>е</strong>образовани<strong>е</strong> из типа i n t в тип s t r i n g н<strong>е</strong>возможно». Иногда<br />

пр<strong>е</strong>образовани<strong>е</strong> происходит автоматич<strong>е</strong>ски, наприм<strong>е</strong>р, <strong>е</strong>сли ожидалось<br />

знач<strong>е</strong>ни<strong>е</strong> типа i n t , а вы п<strong>е</strong>р<strong>е</strong>дали м<strong>е</strong>тоду знач<strong>е</strong>ни<strong>е</strong> типа short, но<br />

в случа<strong>е</strong> с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными типа i n t и s t r i n g это н<strong>е</strong>возможно.<br />

Н<strong>е</strong> только м<strong>е</strong>тод M essageBox.ShowO , вс<strong>е</strong> м<strong>е</strong>тоды, даж<strong>е</strong> написанны<strong>е</strong><br />

вами, будут показывать ошибку компиляции, <strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>дать им парам<strong>е</strong>тр<br />

н<strong>е</strong>правильного типа. Попробуйт<strong>е</strong> использовать на практик<strong>е</strong> этот<br />

сов<strong>е</strong>рш<strong>е</strong>нно правильный м<strong>е</strong>тод:<br />

p u b lic i n t MyMethod (bool yesNo) {<br />

}<br />

i f (yesNo) {<br />

r e t u r n 45;<br />

} e l s e {<br />

r e t u r n 61;<br />

}<br />

^йї?<strong>е</strong>м<strong>е</strong>нная yesNo<br />

- Парам<strong>е</strong>тр ~ это то,<br />

чмо вы опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<strong>е</strong><br />

внутри м<strong>е</strong>тода, а аргум<strong>е</strong>нт<br />

— что в н<strong>е</strong>го<br />

пр<strong>е</strong>да<strong>е</strong>тся. М<strong>е</strong>тод<br />

с парам<strong>е</strong>тром типа int<br />

мож<strong>е</strong>т принять аргум<strong>е</strong>нт<br />

типа byte.<br />

Ошибка означа<strong>е</strong>т,<br />

что вы попытались<br />

вызвать м<strong>е</strong>тод с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными,<br />

тин которых<br />

н<strong>е</strong> совпада<strong>е</strong>т<br />

с <strong>е</strong>го парам<strong>е</strong>трами.<br />

Вс<strong>е</strong> работа<strong>е</strong>т, пока вы п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т<strong>е</strong> м<strong>е</strong>тоду то, что он ожида<strong>е</strong>т получить (логич<strong>е</strong>скую<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную), вызов MyMethod (tru e ) или MyMethod ( f a ls e ) позволя<strong>е</strong>т<br />

л<strong>е</strong>гко скомпилировать код. ^ ^<br />

Но что получится, <strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>дать м<strong>е</strong>тоду число или строку? Вы получит<strong>е</strong><br />

уж<strong>е</strong> знакомо<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>. Попытайт<strong>е</strong>сь п<strong>е</strong>р<strong>е</strong>дать парам<strong>е</strong>тр типа<br />

B oolean, но в кач<strong>е</strong>ств<strong>е</strong> возвраща<strong>е</strong>мого знач<strong>е</strong>ния укажит<strong>е</strong> строку или п<strong>е</strong>р<strong>е</strong>дайт<strong>е</strong><br />

р<strong>е</strong>зультат м<strong>е</strong>тоду M essageBox. Show (). Код п<strong>е</strong>р<strong>е</strong>стан<strong>е</strong>т работать, в<strong>е</strong>дь м<strong>е</strong>тод<br />

возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> типа i n t, а н<strong>е</strong> lo n g или s tr i n g , которо<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся<br />

м<strong>е</strong>тоду M essageBox. Show().<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, парам<strong>е</strong>-<br />

161


таблица зар<strong>е</strong>з<strong>е</strong>рвирована<br />

н<strong>е</strong>ни<strong>е</strong><br />

Вы мож<strong>е</strong>т<strong>е</strong> использовать для им<strong>е</strong>н п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных даж<strong>е</strong><br />

, зар<strong>е</strong>з<strong>е</strong>рвированны<strong>е</strong> слова. Достаточно поставить<br />

у в начал<strong>е</strong> знак<br />

В С# сущ<strong>е</strong>ству<strong>е</strong>т около 77 зар<strong>е</strong>з<strong>е</strong>рвированны х слов. Их н<strong>е</strong>льзя использовать в<br />

кач<strong>е</strong>ств<strong>е</strong> им<strong>е</strong>н п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных. К концу данной книги вы должны познакомиться с ними<br />

вс<strong>е</strong>ми, а пока посмотрит<strong>е</strong> на список слов, с которыми вы уж<strong>е</strong> сталкивались. Напишит<strong>е</strong>,<br />

зач<strong>е</strong>м они нужны.<br />

namespace<br />

£ог<br />

class<br />

p u blic<br />

else<br />

w h i l e<br />

u s i n g<br />

if<br />

п <strong>е</strong> у г<br />

162 глава 4<br />

О ш Б <strong>е</strong>гп ы н а с. 9


типы и ссылки<br />

п^ражн<strong>е</strong>ни<strong>е</strong><br />

О<br />

Дая этой<br />

м<strong>е</strong>тки ис~<br />

пользуйт<strong>е</strong><br />

‘полужирный<br />

шрифт и<br />

к<strong>е</strong>гль 1 2 p t<br />

Создадим калькулятор расходов для д<strong>е</strong>ловой по<strong>е</strong>здки. Вы буд<strong>е</strong>т<strong>е</strong> вводить данны<strong>е</strong> с одом<strong>е</strong>тра<br />

в начал<strong>е</strong> и конц<strong>е</strong> пут<strong>е</strong>ш<strong>е</strong>ствия, а сч<strong>е</strong>тчик вычислять, како<strong>е</strong> расстояни<strong>е</strong> было пройд<strong>е</strong>но и какую<br />

сумму д<strong>е</strong>н<strong>е</strong>г вам в<strong>е</strong>рнут в бухгалт<strong>е</strong>рии, при условии, что за каждую пройд<strong>е</strong>нную милю полага<strong>е</strong>тся<br />

$.39.<br />

Новый про<strong>е</strong>кт W indows.<br />

Вам понадобится вот такая форма:<br />

Mileage Cakulator<br />

ааШпд Mileage<br />

Endng Wteage<br />

Anourt Owed la b e H<br />

Calculate<br />

В<br />

Избавьт<strong>е</strong>сь am<br />

кнопок управл<strong>е</strong>ния<br />

разм<strong>е</strong>ром окна.<br />

О<br />

Зав<strong>е</strong>ршив создани<strong>е</strong> формы, дважды щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> и добавьт<strong>е</strong> код.<br />

П<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нны <strong>е</strong>, которы<strong>е</strong> потр<strong>е</strong>буются для калькулятора.<br />

Пом<strong>е</strong>стит<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> в строчки, объявляющи<strong>е</strong> класс, в в<strong>е</strong>рхн<strong>е</strong>й части кода<br />

F o r m l. Вам потр<strong>е</strong>буются дв<strong>е</strong> ц<strong>е</strong>лочисл<strong>е</strong>нны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> для начальных и<br />

кон<strong>е</strong>чных показаний одом<strong>е</strong>тра. Присвойт<strong>е</strong> им им<strong>е</strong>на s t a r t i n g M i l e a g e и<br />

e n d i n g M i l e a g e . Зат<strong>е</strong>м вам потр<strong>е</strong>буются три н<strong>е</strong>ц<strong>е</strong>лых числа. Выб<strong>е</strong>рит<strong>е</strong> для<br />

них тип d o u b l e и им<strong>е</strong>на m i l e s T r a v e l e d (Пройд<strong>е</strong>но миль), r e i m b u r s e R a t e<br />

(Коэффици<strong>е</strong>нт возм<strong>е</strong>щ<strong>е</strong>ния) и a m o u n tO w e d (Должны д<strong>е</strong>н<strong>е</strong>г). П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

r e i m b u r s e R a t e присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> .39.<br />

Чтобы заставить калькулятор работать.<br />

Добавьт<strong>е</strong> код для м<strong>е</strong>тода b u t t o n l _ C l i c k ():<br />

★<br />

★<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что знач<strong>е</strong>ни<strong>е</strong> поля StartingMileage м<strong>е</strong>ньш<strong>е</strong> знач<strong>е</strong>ния поля<br />

EndingMileage. В противном случа<strong>е</strong> должно выводится окно с т<strong>е</strong>кстом «Начальный<br />

проб<strong>е</strong>г н<strong>е</strong> мож<strong>е</strong>т пр<strong>е</strong>вышать кон<strong>е</strong>чный». Присвойт<strong>е</strong> этому окну имя<br />

«Cannot Calculate» (Н<strong>е</strong>возможно рассчитать).<br />

Вычтит<strong>е</strong> начальный проб<strong>е</strong>г из кон<strong>е</strong>чного и умножьт<strong>е</strong> получ<strong>е</strong>нный р<strong>е</strong>зультат<br />

на тариф;<br />

m i l e s T r a v e l e d = e n d i n g M i l e a g e -= s t a r t i n g M i l e a g e ;<br />

am ou n tO w ed = m i l e s T r a v e l e d *= r e i m b u r s e R a t e ;<br />

l a b e l 4 . T e x t = "$" + a m ou n tO w ed ;<br />

Запуск прогроАлмы.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь в ввод<strong>е</strong> правильных знач<strong>е</strong>ний. Укажит<strong>е</strong> начальный проб<strong>е</strong>г больш<strong>е</strong> кон<strong>е</strong>чного<br />

и уб<strong>е</strong>дит<strong>е</strong>сь в появл<strong>е</strong>нии окна с сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

дальш<strong>е</strong> > 163


что-то пошло н<strong>е</strong> так...<br />

нгнш<br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как выглядит код для п<strong>е</strong>рвой части упражн<strong>е</strong>ния по расч<strong>е</strong>ту<br />

комп<strong>е</strong>нсации.<br />

p u b l i c p a r t i a l c l a s s F o r m l : Form<br />

{<br />

i n t S t a r t i n g M i l e a g e ;<br />

i n t e n d i n g M i l e a g e ;<br />

d o u b l e m i l e s T r a v e l e d ;<br />

d o u b l e r e i m b u r s e R a t e = . 3 9 ;<br />

■^ак как в данном<br />

случа<strong>е</strong> число мож<strong>е</strong>т<br />

пр<strong>е</strong>высить 999 999<br />

типы short или byte н<strong>е</strong><br />

подходят.<br />

d o u b l e am ou n tO w ed ;<br />

p u b l i c F o r m l 0 {<br />

I n i t i a l i z e C o m p o n e n t ( ) ;<br />

}<br />

,<br />

П о м н и т <strong>е</strong> , « ,ц ц я<br />

э л <strong>е</strong> м <strong>е</strong> н т а управл<strong>е</strong>ния<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) { ,,iflA ericU p'PovJn о а м<br />

S t a r t i n g M i l e a g e = ( i n t ) n u m e r i c U p D o w n l .V a lu e ;<br />

нужно п о т н я т ^ > у ^ ^ ^<br />

d L l m a l на m t .<br />

e n d i n g M i l e a g e =<br />

( i n t ) n u m e r i c U p D o w n 2 .V a lu e ; ^<br />

i f ( s t a r t i n g M i l e a g e


типы и ссылки<br />

Ещ<strong>е</strong> одна кнопка<br />

Попыта<strong>е</strong>мся понять, поч<strong>е</strong>му н<strong>е</strong> работа<strong>е</strong>т форма, добавив <strong>е</strong>щ<strong>е</strong> одну кнопку,<br />

которая буд<strong>е</strong>т показывать знач<strong>е</strong>ни<strong>е</strong> поля m ile s T ra v e le d . (Это можно<br />

сд<strong>е</strong>лать при помощи отладчика!)<br />

Satffig Weage<br />

Bid^g Meage<br />

1Ш Э<br />

12354<br />

AmoirrtOwed $532.35<br />

•ВЧТЯГЯЯТТГЯЯТТГЯЧИТЯТКЯРм^!<br />

Calcdate<br />

Если сначала щ<strong>е</strong>лкнуть<br />

на кнопк<strong>е</strong> Calculate, а потол/\<br />

на этой кнопк<strong>е</strong>, должно появиться<br />

окно диалога с иказани<strong>е</strong>м<br />

проб<strong>е</strong>га.<br />

Закончив конструировани<strong>е</strong> формы, дважды щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Display<br />

Miles, чтобы добавить код.<br />

О<br />

Понадобится вс<strong>е</strong>го одна строка<br />

Нам нужно окно, в котором буд<strong>е</strong>т отображаться знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

m ile s T ra v e le d , н<strong>е</strong> так ли? Для этого достаточно одной строки:<br />

p r i v a t e v o i d b u t t o n 2 _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

}<br />

M e s s a g e B o x .S h o w ( m i l e s T r a v e l e d + " m i l e s " , " M ile s T r a v e l e d " ) ;<br />

Запуск програ/имы<br />

Вв<strong>е</strong>дит<strong>е</strong> каки<strong>е</strong>-нибудь знач<strong>е</strong>ния и посмотрит<strong>е</strong>, что<br />

получится. Посл<strong>е</strong> ввода начального и кон<strong>е</strong>чного проб<strong>е</strong>га<br />

щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Calculate. Посл<strong>е</strong> этого щ<strong>е</strong>лчок<br />

на кнопк<strong>е</strong> Display Miles покаж<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> поля<br />

m i l e s T r a v e l e d .<br />

Вот только странно...<br />

При любых вв<strong>е</strong>д<strong>е</strong>нных знач<strong>е</strong>ниях проб<strong>е</strong>г совпада<strong>е</strong>т с суммой возм<strong>е</strong>щ<strong>е</strong>ния. Поч<strong>е</strong>му?<br />

дальш<strong>е</strong> > 165


оп<strong>е</strong>раторы наготов<strong>е</strong><br />

Комбинация с оп<strong>е</strong>ратором =<br />

Обратит<strong>е</strong> внимани<strong>е</strong> на оп<strong>е</strong>ратор, который использовался для вычитания начального<br />

проб<strong>е</strong>га из кон<strong>е</strong>чного (-=). Пробл<strong>е</strong>ма в том, что он н<strong>е</strong> только вычита<strong>е</strong>т,<br />

но и присваива<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной. То ж<strong>е</strong> само<strong>е</strong> происходит в строк<strong>е</strong>,<br />

гд<strong>е</strong> мы умножа<strong>е</strong>м пройд<strong>е</strong>нны<strong>е</strong> мили на тариф возм<strong>е</strong>щ<strong>е</strong>ния. Поэтому нужно<br />

зам<strong>е</strong>нить оп<strong>е</strong>раторы -= и *= на - и *:<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e )<br />

{<br />

S t a r t i n g M i l e a g e = ( i n t ) n u m e r i c U p D o w n l .V a lu e ;<br />

e n d i n g M i l e a g e = ( i n t ) n u m e r ic U p D o w n 2 . V a l u e ;<br />

i f ( s t a r t i n g M i l e a g e


типы и ссылки<br />

Объ<strong>е</strong>кты то)к<strong>е</strong> используют п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

До этого мом<strong>е</strong>нта мы рассматривали объ<strong>е</strong>кты отд<strong>е</strong>льно. На самом<br />

ж<strong>е</strong> д<strong>е</strong>л<strong>е</strong>, это <strong>е</strong>щ<strong>е</strong> один тип данных. Объ<strong>е</strong>кты обрабатываются<br />

аналогично цифрам, строкам и логич<strong>е</strong>ским знач<strong>е</strong>ниям. И точно<br />

такж<strong>е</strong> используют п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>:<br />

Работа с типом int<br />

Работа с объ<strong>е</strong>ктом<br />

( l) Пиш<strong>е</strong>м оп<strong>е</strong>ратор объявл<strong>е</strong>ния типа.<br />

int myint;<br />

(8) Присваива<strong>е</strong>м новой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной знач<strong>е</strong>ни<strong>е</strong>.<br />

myint = 3761;<br />

О<br />

Пиш<strong>е</strong>м оп<strong>е</strong>ратор объявл<strong>е</strong>ния типа.<br />

Dog spot;<br />

объябл<strong>е</strong>ти<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной названи<strong>е</strong><br />

класса использу<strong>е</strong>тся<br />

в кач<strong>е</strong>ств<strong>е</strong> типа.<br />

Присваива<strong>е</strong>м новой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной знач<strong>е</strong>ни<strong>е</strong>:<br />

spot = new Dog();<br />

(З)<br />

Использу<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную в код<strong>е</strong>.<br />

О<br />

Пров<strong>е</strong>ря<strong>е</strong>м одно из пол<strong>е</strong>й объ<strong>е</strong>кта.<br />

while (i < myint) {<br />

while (spot.IsHappy) {<br />

О<br />

- г<br />

___/ Получа<strong>е</strong>тся, что н<strong>е</strong>т разницы \<br />

^ с ч<strong>е</strong>м работать, с объ<strong>е</strong>ктом или с числом. )<br />

В любом случа<strong>е</strong> я работаю с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной. )<br />

Да, объ<strong>е</strong>кты — это вс<strong>е</strong>го лиш ь <strong>е</strong>щ <strong>е</strong> один<br />

тип п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны х.<br />

Если программ<strong>е</strong> нужны ц<strong>е</strong>лы<strong>е</strong> больши<strong>е</strong> числа,<br />

используйт<strong>е</strong> тип long. Для ц<strong>е</strong>лых малых чис<strong>е</strong>л<br />

используйт<strong>е</strong> тип s h o rt. Если вам нужны<br />

знач<strong>е</strong>ния Д а/Н <strong>е</strong>т, используйт<strong>е</strong> тип b o o lean .<br />

А <strong>е</strong>сли вам нужно н<strong>е</strong>что лающ<strong>е</strong><strong>е</strong>, используйт<strong>е</strong><br />

тип Dog. Во вс<strong>е</strong>х случаях вы работа<strong>е</strong>т<strong>е</strong> с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными.<br />

дальш<strong>е</strong> ► 167


получи ссылку<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> ссылочного типа<br />

Для создания нового объ<strong>е</strong>кта вы пиш<strong>е</strong>т<strong>е</strong> n e w G uy ( ). Но этого н<strong>е</strong>достаточно;<br />

в куч<strong>е</strong> появится объ<strong>е</strong>кт G uy, но у вас н<strong>е</strong> буд<strong>е</strong>т к н<strong>е</strong>му доступа. Вам<br />

тр<strong>е</strong>бу<strong>е</strong>тся ссылка на объ<strong>е</strong>кт. Зд<strong>е</strong>сь на помош;ь приходят п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы <strong>е</strong> с с ы ­<br />

л о ч н о г о т и п а —это п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> типа G uy, им<strong>е</strong>юш;и<strong>е</strong> имя, наприм<strong>е</strong>р, j o e .<br />

В итог<strong>е</strong> получа<strong>е</strong>тся, что j o e —это ссылка на только что созданный объ<strong>е</strong>кт<br />

G uy. Им<strong>е</strong>нно она использу<strong>е</strong>тся для доступа к объ<strong>е</strong>кту.<br />

Вс<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> типа object являются ссылочными. Давайт<strong>е</strong> рассмотрим<br />

прим<strong>е</strong>р:<br />

Э т о наэь1ва<strong>е</strong>т ся<br />

создани<strong>е</strong>м экз<strong>е</strong>мпляра<br />

объ<strong>е</strong>кта. \<br />

Это куча до<br />

запуска кода. Там<br />

нич<strong>е</strong>го н<strong>е</strong>т.<br />

p u b l i c p a r t i a l c l a s s F o rm l<br />

{<br />

Guy joe;<br />

Form<br />

p u b l i c F o r m l0<br />

Это п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная {<br />

joe, ссылающаяся I n i t i a l i z e C o m p o n e n t ()<br />

на объ<strong>е</strong>кт йму<<br />

joe = new Guy();<br />

Это ссылочная ^ объ<strong>е</strong>кт,<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная... на который<br />

она ссыла<strong>е</strong>тся.<br />

Создани<strong>е</strong> ссылки подобно<br />

накл<strong>е</strong>ивании) стик<strong>е</strong>ра, вы<br />

пом<strong>е</strong>ча<strong>е</strong>т<strong>е</strong> объ<strong>е</strong>кт, чтобы<br />

получить возможность<br />

ссылаться на н<strong>е</strong>го в дальн<strong>е</strong>йш<strong>е</strong>м.<br />

Вид кучи посл<strong>е</strong> запу<br />

ска кода. Т<strong>е</strong>п<strong>е</strong>рь там<br />

находится объ<strong>е</strong>кт<br />

с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной Joe. хо<br />

торая на н<strong>е</strong>го ссыла<strong>е</strong>тся.<br />

таи н ств<strong>е</strong>н н ы й<br />

к объ<strong>е</strong>кту<br />

Quy - а<strong>е</strong>р<strong>е</strong>з<br />

^^^р<strong>е</strong>м<strong>е</strong>нную Joe<br />

168 глава 4


типы и ссылки<br />

Ссылки подобны марк<strong>е</strong>рам<br />

Подозр<strong>е</strong>ва<strong>е</strong>м, что на ваш<strong>е</strong>й кухн<strong>е</strong> <strong>е</strong>сть отд<strong>е</strong>льны<strong>е</strong> <strong>е</strong>мкости для сахара<br />

и соли. Если пом<strong>е</strong>нять м<strong>е</strong>стами накл<strong>е</strong>йки на них, <strong>е</strong>да буд<strong>е</strong>т н<strong>е</strong>съ<strong>е</strong>добной,<br />

в<strong>е</strong>дь сод<strong>е</strong>ржимо<strong>е</strong> <strong>е</strong>мкост<strong>е</strong>й при этом м<strong>е</strong>стами н<strong>е</strong> пом<strong>е</strong>нялось. Аналогично<br />

д<strong>е</strong>йствуют ссылки. Ярлыки можно пом<strong>е</strong>нять м<strong>е</strong>стами и заставить указывать<br />

на разны<strong>е</strong> в<strong>е</strong>щи, но каки<strong>е</strong> им<strong>е</strong>нно данны<strong>е</strong> и м<strong>е</strong>тоды будут доступны, опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

только сам объ<strong>е</strong>кт, а н<strong>е</strong> ссылка на н<strong>е</strong>го.<br />

Это объ<strong>е</strong>кт типа<br />

^иу. Он ОДИН, но на<br />

н<strong>е</strong>го МНОГО ссылок<br />

М<strong>е</strong>тод b u tto n l Clirîf Ar,<br />

мы Form l сод<strong>е</strong>южи^<br />

Для работы с хранящимися<br />

в памяти<br />

объ<strong>е</strong>ктами используются<br />

ссылки,<br />

которы<strong>е</strong> являются<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ппыми. Тип<br />

этих п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся классом<br />

объ<strong>е</strong>кта, на который<br />

они ссылаю<br />

тся.<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

«папа» явля<strong>е</strong>тся<br />

ссылкой на экз<strong>е</strong>м ­<br />

пляр класса Quy.<br />

^т о ссылочны<strong>е</strong><br />

’л<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>,<br />

указывающи<strong>е</strong> на<br />

ОДИН И ТОТ ЖЕ<br />

ооь<strong>е</strong>кт.<br />

Обращ<strong>е</strong>ни<strong>е</strong> к объ<strong>е</strong>кту никогда н<strong>е</strong> проиходит напрямую. К прим<strong>е</strong>ру, н<strong>е</strong>возможно<br />

записать G u y . G iv e C a s h {), <strong>е</strong>сли G uy принадл<strong>е</strong>жит типу object.<br />

Компилятор н<strong>е</strong> понима<strong>е</strong>т, куда им<strong>е</strong>нно вы обраща<strong>е</strong>т<strong>е</strong>сь, так как в куч<strong>е</strong> мож<strong>е</strong>т<br />

храниться н<strong>е</strong>сколько эк<strong>е</strong>мпляров G uy. Вам нужна ссылочная п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная,<br />

наприм<strong>е</strong>р, j o e , которой буд<strong>е</strong>т присво<strong>е</strong>н конкр<strong>е</strong>тный экз<strong>е</strong>мпляр G uy<br />

j о <strong>е</strong> - n e w Guy().<br />

Различны<strong>е</strong> м<strong>е</strong>тоды м о ­<br />

гут использовать эк-<br />

ссь/лоч-<br />

НЫМ п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы м р а ­<br />

з у м н о п р и с в о и т ь р а з н ы <strong>е</strong><br />

в зависимости от<br />

конт<strong>е</strong>кста.<br />

Т<strong>е</strong>п<strong>е</strong>рь можно вызывать м<strong>е</strong>тоды j о <strong>е</strong> . G iv e C a s h ( ), в<strong>е</strong>дь компилятор «зна<strong>е</strong>т»,<br />

к какому экз<strong>е</strong>мпляру обратиться. Как показано на рисунк<strong>е</strong>, возмож<strong>е</strong>н<br />

набор ссылок на один экз<strong>е</strong>мпляр. Можно написать G uy d a d = j о <strong>е</strong> и вызвать<br />

м<strong>е</strong>тод d a d . G iv e C a s h о (папа.ДайД<strong>е</strong>н<strong>е</strong>г()). Им<strong>е</strong>нно этим сын <strong>Дж</strong>о занима<strong>е</strong>тся<br />

каждый д<strong>е</strong>нь!<br />

дальш<strong>е</strong> ► 169


вот водит<strong>е</strong>ль мусоровоза<br />

При о тсутств и и ссылок объ<strong>е</strong>кт<br />

пр<strong>е</strong>враща<strong>е</strong>тся 6 мусор<br />

Если вс<strong>е</strong> ссылки на объ<strong>е</strong>кт исч<strong>е</strong>зают, программа т<strong>е</strong>ря<strong>е</strong>т к н<strong>е</strong>му<br />

доступ. Т<strong>е</strong>п<strong>е</strong>рь объ<strong>е</strong>кт пр<strong>е</strong>дназнач<strong>е</strong>н для сборки мусора<br />

(garbage collection). <strong>C#</strong> избавля<strong>е</strong>тся ото вс<strong>е</strong>х объ<strong>е</strong>ктов, на которы<strong>е</strong><br />

н<strong>е</strong>т ссылок, освобождая м<strong>е</strong>сто в памяти.<br />

^ Вот код создания объ<strong>е</strong>кта.<br />

Guy j о <strong>е</strong> = new G uy()<br />

{ Name = "Joe", Cash = 50<br />

Объ<strong>е</strong>кт оста<strong>е</strong>тся<br />

в куч<strong>е</strong>, пока на н<strong>е</strong>го<br />

<strong>е</strong>сть хотя бы одна<br />

ссылка. Как только<br />

посл<strong>е</strong>дняя ссылка<br />

исч<strong>е</strong>за<strong>е</strong>т, объ<strong>е</strong>кт<br />

удаля<strong>е</strong>тся.<br />

Оп<strong>е</strong>ратор new созда<strong>е</strong>т<br />

новый объ<strong>е</strong>кт,<br />

a ссылочная п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

Joe указыва<strong>е</strong>т<br />

на н<strong>е</strong>го.<br />

О Бьхл создан второй объ<strong>е</strong>кт.<br />

Guy bob = new GuyO<br />

{ Name = "Bob", Cash = 75 };<br />

о П усть ссы лка на п<strong>е</strong>рвый экз<strong>е</strong>мпляр начн<strong>е</strong>т<br />

указывать на второй.<br />

j о <strong>е</strong> = b o b ;<br />

Ссылок Нй п<strong>е</strong>рвый<br />

экз<strong>е</strong>мпляр<br />

н<strong>е</strong> осталось...<br />

■■■поэтому<br />

Объ<strong>е</strong>кт<br />

удаля<strong>е</strong>тся!<br />

170 глава 4


типы и ссылки<br />

Побочны<strong>е</strong> эфф<strong>е</strong>кты мно)к<strong>е</strong>ств<strong>е</strong>нных ссылок<br />

Обращаться с ссылочными п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нными нужно аккуратно. В большинств<strong>е</strong><br />

случа<strong>е</strong>в каж<strong>е</strong>тся, что вы просто п<strong>е</strong>р<strong>е</strong>направля<strong>е</strong>т<strong>е</strong> ссылку на<br />

другой объ<strong>е</strong>кт. Но при этом можно н<strong>е</strong>чаянно удалить вс<strong>е</strong> ссылки на<br />

другой объ<strong>е</strong>кт. И дал<strong>е</strong>ко н<strong>е</strong> вс<strong>е</strong>гда это буд<strong>е</strong>т тот р<strong>е</strong>зультат, который<br />

вам нуж<strong>е</strong>н. Рассмотрим прим<strong>е</strong>р:<br />

D og r o v e r = n ew D o g ( ) ;<br />

r o v e r . B r e e d = " G r e y h o u n d " ;<br />

О бъ<strong>е</strong>ктов:<br />

© D og f i d o = n ew D o g O ;<br />

f i d o . B r e e d = " B e a g l e " ;<br />

D og s p o t = r o v e r ;<br />

О бъ<strong>е</strong>ктов:<br />

Ссы лок: 5<br />

^<br />

Fido — это <strong>е</strong>щ<strong>е</strong> один<br />

объ<strong>е</strong>кт Dog. При этом<br />

Spot — это вс<strong>е</strong>го лииль<br />

дополнит<strong>е</strong>льная ссылка<br />

на п<strong>е</strong>рвый объ<strong>е</strong>кт.<br />

D og l u c k y = n ew D o g ( ) ;<br />

l u c k y . B r e e d = " D a c h sh u n d " ;<br />

f i d o = r o v e r ;<br />

Lucky — это тр<strong>е</strong>тий<br />

объ<strong>е</strong>кт. A Fido т<strong>е</strong>п<strong>е</strong>рь<br />

ссыла<strong>е</strong>тся на Object *%.<br />

На object н<strong>е</strong><br />

оста<strong>е</strong>тся ссылок. Он<br />

удаля<strong>е</strong>тся.<br />

Бах!<br />

/ Л \<br />

дальш<strong>е</strong> ► 171


так много м<strong>е</strong>ток<br />

їозьми в руку карандаш<br />

Т<strong>е</strong>п<strong>е</strong>рь ваша оч<strong>е</strong>р<strong>е</strong>дь. Вот длинный код, разбитый на блоки.<br />

Укажит<strong>е</strong>, сколько объ<strong>е</strong>ктов и сколько ссылок на них им<strong>е</strong><strong>е</strong>тся на<br />

каждой стадии. Справа нарисуйт<strong>е</strong> объ<strong>е</strong>кты в куч<strong>е</strong> и их м<strong>е</strong>тки.<br />

D og r o v e r = n ew D o g ( ) ;<br />

r o v e r . B r e e d = " G r e y h o u n d " ;<br />

D og r i n T i n T i n = n e w D o g ( ) ;<br />

D og f i d o = n ew D o g ( ) ;<br />

D og q u e n t i n = f i d o ;<br />

О бъ <strong>е</strong>ктов:.<br />

Ссылок:<br />

© D o g s p o t = n ew D o g { ) ;<br />

s p o t . B r e e d = " D a c h s h u n d " ;<br />

s p o t = r o v e r ;<br />

О бъ <strong>е</strong>ктов:______<br />

Ссы лок:_____<br />

О<br />

D<br />

o g l u c k y = n ew D o g { ) ;<br />

l u c k y . B r e e d = " B e a g le " ;<br />

D o g C h a r l i e = f i d o ;<br />

f i d o = r o v e r ;<br />

О бъ <strong>е</strong>ктов:______<br />

Ссы лок:_____<br />

^ r i n T i n T i n = l u c k y ;<br />

D og l a v e r n e = n ew D o g O ;<br />

l a v e r n e . B r e e d = " p u g " ;<br />

О бъ <strong>е</strong>ктов:______<br />

Ссы лок:_____<br />

О<br />

C h a r l i e = l a v e r n e ;<br />

l u c k y = r i n T i n T i n ;<br />

О бъ <strong>е</strong>ктов:______<br />

Ссы лок:_____<br />

172 глава 4


типы и ссылки<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

Напишит<strong>е</strong> программу для класса e le p h a n t (слон). Получит<strong>е</strong> два экз<strong>е</strong>мпляра<br />

e le p h a n t и пом<strong>е</strong>няйт<strong>е</strong> указывающи<strong>е</strong> на них ссылки таким образом, чтобы<br />

ни один из экз<strong>е</strong>мпляров н<strong>е</strong> был уничтож<strong>е</strong>н.<br />

Начнит<strong>е</strong> с про<strong>е</strong>кта Windows Application.<br />

Форма должна выгляд<strong>е</strong>ть так;<br />

т а к о <strong>е</strong> окно.<br />

А т г р а м м а д л я<br />

S S e . t e , - " -<br />

с<br />

E le p h a n t<br />

Name<br />

EarSize<br />

WhoAmIO<br />

у б <strong>е</strong> д и т <strong>е</strong> с ь , ч т о в т <strong>е</strong> к с т <strong>е</strong><br />

с о д <strong>е</strong> р ж и т с я и н ф о р м а ц и я<br />

о р а з м <strong>е</strong> р <strong>е</strong> у х а , а с т р о к <strong>е</strong><br />

з а г о л о в к а ф и г у р и р у <strong>е</strong> т<br />

и м я с л о н а .<br />

о<br />

Класс Elephant<br />

Согласно диаграмм<strong>е</strong> классов E le p h a n t вам потр<strong>е</strong>бу<strong>е</strong>тся пол<strong>е</strong> типа i n t с названи<strong>е</strong>м E a rS iz e<br />

и пол<strong>е</strong> типа S tr in g с названи<strong>е</strong>м Name. (Уб<strong>е</strong>дит<strong>е</strong>сь в наличии модификатора public.) Добавьт<strong>е</strong><br />

м<strong>е</strong>тод WhoAmI (), вызывающий окно с информаци<strong>е</strong>й о разм<strong>е</strong>р<strong>е</strong> уха и им<strong>е</strong>ни слона.<br />

Ещ<strong>е</strong> два экз<strong>е</strong>мпляра Elephant и ссылки на них<br />

Добавьт<strong>е</strong> к классу Forml два поля E le p h a n t (сразу под объявл<strong>е</strong>ни<strong>е</strong>м класса) с им<strong>е</strong>нами Lloyd<br />

и L ucinda. Присвойт<strong>е</strong> им сл<strong>е</strong>дующи<strong>е</strong> начальны<strong>е</strong> знач<strong>е</strong>ния;<br />

l u c in d a = new E le p h a n t О { Name = "L ucinda", E a r S iz e = 33 };<br />

l l o y d = new E le p h a n t 0 { Name = "L loyd", E a r S iz e = 40 };<br />

Кнопки Lloyd и Lucinda<br />

Кнопка Lloyd должна вызывать м<strong>е</strong>тод 1 lo y d . WhoAmI<br />

WhoAmI{).<br />

, a кнопка Lucinda —м<strong>е</strong>тод l u c i n d a .<br />

Кнопка п<strong>е</strong>р<strong>е</strong>клю ч<strong>е</strong>ния<br />

Это самая сложная часть. Кнопка Swap должна пом<strong>е</strong>нять м<strong>е</strong>стами дв<strong>е</strong> ссылки. То <strong>е</strong>сть щ<strong>е</strong>лчок<br />

на н<strong>е</strong>й заставля<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> L loyd и L ucinda ссылаться на други<strong>е</strong> объ<strong>е</strong>кты и вызва<strong>е</strong>т<br />

окно с сообщ<strong>е</strong>ни<strong>е</strong>м «Objects swapped» (Зам<strong>е</strong>на объ<strong>е</strong>ктов). Посл<strong>е</strong> щ<strong>е</strong>лчка на кнопк<strong>е</strong> Swap<br />

щ<strong>е</strong>лчок на кнопк<strong>е</strong> Lloyd долж<strong>е</strong>н вызывать окно Lucinda и наоборот. Повторный щ<strong>е</strong>лчок на<br />

кнопк<strong>е</strong> Swap долж<strong>е</strong>н возвращать вс<strong>е</strong> обратно.<br />

Как только на объ<strong>е</strong>кт н<strong>е</strong> оста<strong>е</strong>тся ни одной ссы лки, он удаля<strong>е</strong>тся. Что ж<strong>е</strong> д<strong>е</strong>л ать?<br />

Пр<strong>е</strong>дставьт<strong>е</strong>, что вы р<strong>е</strong>ш или п<strong>е</strong>р<strong>е</strong>лить пиво в стакан, которы й в данны й мом<strong>е</strong>нт<br />

наполн<strong>е</strong>н водой. Чтобы сд<strong>е</strong>лать это вам потр<strong>е</strong>бу<strong>е</strong>тся <strong>е</strong>щ <strong>е</strong> один, пустой стакан...


Возьми 8 руку карандаш<br />

“^<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как выглядит куча с объ<strong>е</strong>ктами и ссылками на них.<br />

©<br />

©<br />

D og r o v e r = n ew D o g ( ) ;<br />

r o v e r . B r e e d = " G r e y h o u n d " ;<br />

D og r i n T i n T i n = n ew D o g ( ) ;<br />

D og f i d o = n ew D o g ( ) ;<br />

D og q u e n t i n = f i d o ;<br />

y /<br />

D o g s p o t = n ew D o g ( ) ; ^<br />

s p o t . B r e e d = " D a c h s h u n d " ;<br />

s p o t = r o v e r ;<br />

D og l u c k y = n ew D o g ( ) ;<br />

l u c k y . B r e e d = " B e a g le " ;<br />

D og C h a r l i e = f i d o ; . ,,<br />

(^здан новый объ<strong>е</strong>кт<br />

^од со ссылкой Spot. В<br />

р<strong>е</strong>зультат<strong>е</strong> оп<strong>е</strong>рации<br />

Spot = Rover объ<strong>е</strong>кт<br />

исч<strong>е</strong>за<strong>е</strong>т.<br />

Создан новый объ<strong>е</strong>кт<br />

Dog, но посл<strong>е</strong> Fido=Rover<br />

^ пр<strong>е</strong>дыдущий объ<strong>е</strong>кт на<br />

/ который ссылался Fido<br />

исч<strong>е</strong>за<strong>е</strong>т<br />

^ ^<br />

f l d o = r o v e r ;<br />

Charlie, как и Fido, стал<br />

указывать на object<br />

О бъ <strong>е</strong>ктов: 4<br />

*3. Зат<strong>е</strong>м Fido начал<br />

ссылаться на object ^й-.<br />

Ссы лок: 7<br />

Исч<strong>е</strong>зла<br />

посл<strong>е</strong>дняя<br />

ссылка на ^<br />

r i n T i n T i n = l u c k y ;<br />

объ<strong>е</strong>кт<br />

Dog<br />

D og l a v e r n e = n ew D o g ()<br />

l a v e r n e . B r e e d = " p u g " ;<br />

О бъ <strong>е</strong>ктов:.<br />

Ссы лок:<br />

^<br />

C h a r l i e = l a v e r n e ;<br />

l u c k y = r i n T i n T i n ;<br />

4<br />

Ссылка Rin Tin Tin<br />

т <strong>е</strong> п ^ ь указыва<strong>е</strong>т<br />

на объ<strong>е</strong>кт Lucky,<br />

поэтому пр<strong>е</strong>дыдущий<br />

объ<strong>е</strong>кт был удал<strong>е</strong>н.<br />

% d o f<br />

174<br />

О бъ <strong>е</strong>ктов: 4<br />

Ссы лок: 8<br />

глава 4<br />

\<br />

Происходит п<strong>е</strong>р<strong>е</strong>направл<strong>е</strong>ни<strong>е</strong><br />

ссылок, но новы<strong>е</strong> объ<strong>е</strong>кты н<strong>е</strong> создаются.<br />

Посл<strong>е</strong>дний оп<strong>е</strong>ратор н<strong>е</strong><br />

д<strong>е</strong>ла<strong>е</strong>т нич<strong>е</strong>го, так как об<strong>е</strong> ссылки<br />

и так указывали на один и тот<br />

ж<strong>е</strong> объ<strong>е</strong>кт.


типы и ссылки<br />

пражн<strong>е</strong>ни<strong>е</strong><br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Посмотрим, как ж<strong>е</strong> пом<strong>е</strong>нять м<strong>е</strong>жду собой ссылки на два экз<strong>е</strong>мпляра,<br />

чтобы ни один из них при этом н<strong>е</strong> оказался удал<strong>е</strong>нным.<br />

u s in g System .W in dow s.F orm s;<br />

c l a s s E lep h a n t {<br />

p u b lic i n t E a r S iz e ;<br />

p u b l i c s t r i n g Name;<br />

p u b l i c v o i d WhoAmI0 {<br />

M essageB ox.Show ("M y e a r s a r e<br />

Name + " says...") ;<br />

+ E a r S iz e + " in c h e s t a l l . '<br />

Э т о о п р <strong>е</strong> д <strong>е</strong> л <strong>е</strong> н и <strong>е</strong><br />

к л а с с а B ie p h a n t<br />

He з а б у д ь т <strong>е</strong> _<br />

строчку<br />

System-Wtn-ftOV/spormSi»><br />

и<strong>е</strong> о п <strong>е</strong> р а т о р<br />

M e ss a g e B o x н<strong>е</strong> o y<br />

д <strong>е</strong> т p a S o m a m t? -<br />

p u b l i c p a r t i a l c l a s s Forml ; Form {<br />

E le p h a n t lu c in d a ;<br />

E le p h a n t l lo y d ;<br />

p u b l i c F o r m l0<br />

Это код класса<br />

Form l из файла<br />

Formi.cs.<br />

С с ы л к а H o ld e r<br />

нуж на для т о г о<br />

ц т о б ы о б ш к т L io y d<br />

н <strong>е</strong> и с ч <strong>е</strong> з , п о с л <strong>е</strong> т о г о<br />

как с с ы л к а б у д <strong>е</strong> т<br />

п <strong>е</strong> р <strong>е</strong> н а п р а в л <strong>е</strong> н а н а<br />

о б ъ <strong>е</strong> к т Lucinda.<br />

Типы данных string<br />

и array от личаются<br />

от вс<strong>е</strong>х остальных<br />

отсутстви<strong>е</strong>м фиксированной<br />

длины.<br />

}<br />

I n it ia liz e C o m p o n e n t O ;<br />

lu c in d a = new E le p h a n t ()<br />

{ Name = "L ucinda", E a r S iz e = 3 3 };<br />

l l o y d = new E le p h a n t 0<br />

{ Name = "L loyd", E a r S iz e = 4 0 };<br />

p r i v a t e v o id b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

llo y d .W h o A m I( );<br />

}<br />

p r i v a t e v o i d b u t t o n 2 _ C lic k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

lu cin d a.W h oA m I( );<br />

}<br />

p r i v a t e v o id b u t t o n 3 _ C lic k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

}<br />

- E le p h a n t h o ld e r ; О п <strong>е</strong> р а т о р new н<strong>е</strong> и с п о л ь з у <strong>е</strong> т с я ,<br />

S S r = ^ u c ? n d ; ; ^ ^ т а к к а к н а м н<strong>е</strong> н у ж <strong>е</strong> н <strong>е</strong> щ <strong>е</strong> оЗын<br />

lu c in d a = h o ld e r ; э к з <strong>е</strong> м п л я р E le p h a n t.<br />

M essa g eB o x . Show ( "Obj e c t s sw apped");<br />

Как вы счита<strong>е</strong>т<strong>е</strong>, поч<strong>е</strong>му к классу Elephant н<strong>е</strong> был добавл<strong>е</strong>н м<strong>е</strong>тод Swap()?


д<strong>е</strong>ржи ссылку<br />

Дб<strong>е</strong> ссылки это Д В А способа р<strong>е</strong>дактировать данны<strong>е</strong> объ<strong>е</strong>кта<br />

Наличи<strong>е</strong> множ<strong>е</strong>ств<strong>е</strong>нных ссылок на объ<strong>е</strong>кт созда<strong>е</strong>т<br />

опасность н<strong>е</strong>пр<strong>е</strong>днам<strong>е</strong>р<strong>е</strong>нного р<strong>е</strong>дактирования. Другими<br />

словами, одна ссылка мож<strong>е</strong>т <strong>е</strong>н<strong>е</strong>сти изм<strong>е</strong>н<strong>е</strong>ния<br />

в объ<strong>е</strong>кт, в то вр<strong>е</strong>мя как другая рассчитана на использовани<strong>е</strong><br />

старой в<strong>е</strong>рсии этого объ<strong>е</strong>кта. Посмотрит<strong>е</strong><br />

сами:<br />

V<br />

^<br />

О<br />

Добавим форм<strong>е</strong> <strong>е</strong>щ<strong>е</strong> одну кнопку.<br />

© Добавим к кнопк<strong>е</strong> код. А т<strong>е</strong>п<strong>е</strong>рь подумайт<strong>е</strong>, что<br />

произойд<strong>е</strong>т посл<strong>е</strong> щ<strong>е</strong>лчка на этой кнопк<strong>е</strong>?<br />

Этот оп<strong>е</strong>ратор<br />

прцсбаива<strong>е</strong>т<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной-^<br />

EarSize знач<strong>е</strong>ни<strong>е</strong><br />

43Д 1 тому<br />

объ<strong>е</strong>кту, на который<br />

покаж<strong>е</strong>т<br />

ссылка lloyd.<br />

p r i v a t e v o id b u t t o n 4 _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

l l o y d = lu c in d a ; ■—<br />

. l lo y d .E a r S i z e = 4321;<br />

lloyd .W h oA m I{)<br />

И <strong>е</strong>тоЗ WboAmiO<br />

в ы з ы в а <strong>е</strong> т <strong>е</strong> ^<br />

объ<strong>е</strong>кта<br />

С Но lloyd указыва<strong>е</strong>т<br />

ж<strong>е</strong>, куда и lucinda.<br />

Посл<strong>е</strong> запуска кода<br />

1^<strong>е</strong>а<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> lloyd<br />

и lucinda будут<br />

ссылаться на ОЛИН<br />

объ<strong>е</strong>кт Elephant.<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong>, чтобы пров<strong>е</strong>рить свои догадки. Смотрит<strong>е</strong>, это окно<br />

Lucinda. При том что вы вызывали м<strong>е</strong>тод WhoAmI () для Ллойда.<br />

^1<strong>е</strong>р)г\0!Г^<br />

Окно Аизсинды...<br />

Lucinda says...<br />

Но это знач<strong>е</strong>ни<strong>е</strong><br />


типы и ссылки<br />

Особый случай: массиВы<br />

Для сл<strong>е</strong>ж<strong>е</strong>ния за набором данных одного типа, наприм<strong>е</strong>р, списка<br />

высот или группы собак используются м а с с и в ы (array). Этот<br />

т<strong>е</strong>рмин обознача<strong>е</strong>т г р у п п у п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы х , которая обрабатыва<strong>е</strong>тся<br />

как <strong>е</strong>диный объ<strong>е</strong>кт. Вы получа<strong>е</strong>т<strong>е</strong> возможность хранить<br />

и р<strong>е</strong>дактировать больши<strong>е</strong> наборы данных. Массивы объявляются<br />

аналогично другим п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нным. Нужно указать имя массива<br />

и <strong>е</strong>го тип:<br />

Для об-ьявл<strong>е</strong>ния мяссибя<br />

нужно указать <strong>е</strong>го тип,<br />

поставив сл<strong>е</strong>дом ква<br />

дратны<strong>е</strong> скобки.<br />

Новый массив С03-,<br />

да<strong>е</strong>тся командой<br />

new, как и любой<br />

другой объ<strong>е</strong>кт.<br />

bool [] туАггау;<br />

туАггау = new bool<br />

— -<br />

туАггау[4] = true<br />

Ка)кдЬ1й эл<strong>е</strong>м<strong>е</strong>нт waccuBa — э то вс<strong>е</strong>го лишь п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

Пр<strong>е</strong>жд<strong>е</strong> вс<strong>е</strong>го вы должны о б ъ я в и т ь с с ы л о ч н у ю п <strong>е</strong> р <strong>е</strong> ­<br />

м <strong>е</strong> н н у ю для массива. Зат<strong>е</strong>м при помощи оп<strong>е</strong>ратора new<br />

с о з д а <strong>е</strong> т с я о б ъ <strong>е</strong> к т с указани<strong>е</strong>м разм<strong>е</strong>ра. Вс<strong>е</strong> готово для п о ­<br />

м <strong>е</strong> щ <strong>е</strong> н и я э л <strong>е</strong> м <strong>е</strong> н т о в в массив. Вот прим<strong>е</strong>р кода создания<br />

массива и вид кучи. П<strong>е</strong>рвый эл<strong>е</strong>м<strong>е</strong>нт массива вс<strong>е</strong>гда им<strong>е</strong><strong>е</strong>т<br />

нул<strong>е</strong>вой и н д <strong>е</strong> к с .<br />

знач<strong>е</strong>ний:<br />

Ьоо1[]<br />

new<br />

состоит из<br />

1 5 эл<strong>е</strong>м<strong>е</strong>нтов.<br />

Нум<strong>е</strong>рация эл<strong>е</strong>м<strong>е</strong>нтов массива нйим<br />

на<strong>е</strong>тся с О. Эта строка присваива<strong>е</strong>т<br />

пятому эл<strong>е</strong>м<strong>е</strong>нту массива знач<strong>е</strong>ни<strong>е</strong><br />

в памяти массив<br />

вс<strong>е</strong>гда хранится одним<br />

бAOKOMJ сколько<br />

бы п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

в н<strong>е</strong>м ни было.<br />

Тип эл<strong>е</strong>м<strong>е</strong>нтов<br />

Мйссибя<br />

Вы ссыла<strong>е</strong>т<strong>е</strong>сь<br />

на j<br />

эл<strong>е</strong>м<strong>е</strong>нты <<br />

массива по<br />

инд<strong>е</strong>ксу<br />

heights;<br />

ИМЯ<br />

heights = new int [7];<br />

[0] = 68<br />

[1] = 70<br />

[2] 63<br />

[3] = 60<br />

[4] 58<br />

[5] = 72<br />

[б] = 74<br />

^QCOA^<br />

^М а с с и в — это <strong>е</strong>диный объ<strong>е</strong>кт,<br />

хотя и состоящий из<br />

с<strong>е</strong>ми обычных п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных.<br />

дальш<strong>е</strong> ► 177


выбира<strong>е</strong>м объ<strong>е</strong>кт из оч<strong>е</strong>р<strong>е</strong>ди<br />

Массиб мо)к<strong>е</strong>т со сто я ть из ссылочных п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

Массив мож<strong>е</strong>т сод<strong>е</strong>ржать н<strong>е</strong> только числа или строки, но и ссылки<br />

на объ<strong>е</strong>кты. Словом, только от вас зависит, п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> какого типа<br />

вы хотит<strong>е</strong> таким образом организовать. Можно создать как массив<br />

ц<strong>е</strong>лых чис<strong>е</strong>л, так и массив объ<strong>е</strong>ктов типа Duck.<br />

Рассмотрим код создания массива из 7 п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных типа D og. Строка<br />

инициализации созда<strong>е</strong>т только ссылочны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>. За н<strong>е</strong>й<br />

сл<strong>е</strong>дуют дв<strong>е</strong> строки new D og {), то <strong>е</strong>сть создаются два экз<strong>е</strong>мпляра<br />

класса Dog.<br />

( 7<br />

\<br />

Dog[] dogs = new Dog [7];<br />

Jk— '<br />

dogs [5] = new DogO;<br />

f dogs[0] = new DogO ;<br />

экз<strong>е</strong>мпляры<br />

(). которы<strong>е</strong> пом<strong>е</strong>щаются<br />

в нул<strong>е</strong>вой Тпя~<br />

эл<strong>е</strong>л1<strong>е</strong>нть/ массива.<br />

Эта строка<br />

объявля<strong>е</strong>т<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>,<br />

в которых буд<strong>е</strong>т<br />

храниться<br />

массив ссылок<br />

объ<strong>е</strong>кты Род.<br />

Число в квадратных<br />

скобках называ<strong>е</strong>тся<br />

инд<strong>е</strong>ксом<br />

( index) и использу<strong>е</strong>тся<br />

для обращ<strong>е</strong>ния<br />

к эл<strong>е</strong>м<strong>е</strong>нтам<br />

массива. Инд<strong>е</strong>кс<br />

п<strong>е</strong>рвого эл<strong>е</strong>м<strong>е</strong>нта<br />

вс<strong>е</strong>гда рав<strong>е</strong>н нулю.<br />

П<strong>е</strong>рвая строка кода<br />

созда<strong>е</strong>т только сам<br />

массив, который ^<br />

пр<strong>е</strong>дставля<strong>е</strong>т собой<br />

набор из с<strong>е</strong>ми ссылочных<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных.<br />

о д у -<br />

Вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты массива являются<br />

ссылками, в то вр<strong>е</strong>мя как<br />

массив — это объ<strong>е</strong>кт.<br />

178 глава 4


типы и ссылки<br />

Добро по)каловать на pacnpoga)ky сэндВич<strong>е</strong>й о т Д}ко!<br />

в зав<strong>е</strong>д<strong>е</strong>нии <strong>Дж</strong>о множ<strong>е</strong>ство видов мяса, хл<strong>е</strong>б на любой вкус<br />

и больш<strong>е</strong> приправ, ч<strong>е</strong>м вы мож<strong>е</strong>т<strong>е</strong> с<strong>е</strong>б<strong>е</strong> пр<strong>е</strong>дставить. Н<strong>е</strong>т только<br />

м<strong>е</strong>ню! Смож<strong>е</strong>т<strong>е</strong> создать для н<strong>е</strong>го программу, которая буд<strong>е</strong>т г<strong>е</strong>н<strong>е</strong>рировать<br />

м<strong>е</strong>ню случайным образом?<br />

У^їражн<strong>е</strong>ни<strong>е</strong>і 10І<br />

Новый про<strong>е</strong>кт, сод<strong>е</strong>ржащ ий класс М <strong>е</strong>пиМ ак<strong>е</strong>г<br />

Для м<strong>е</strong>ню вам потр<strong>е</strong>буются ингр<strong>е</strong>ди<strong>е</strong>нты. Информацию о них лучш<strong>е</strong><br />

вс<strong>е</strong>го хранить в вид<strong>е</strong> массивов. Ингр<strong>е</strong>ди<strong>е</strong>нты должны см<strong>е</strong>шиваться<br />

случайным образом, образуя сэндвич. В этом вам помож<strong>е</strong>т встро<strong>е</strong>нный<br />

класс Random , г<strong>е</strong>н<strong>е</strong>рирующий случайны<strong>е</strong> числа. Итак, наш класс<br />

буд<strong>е</strong>т им<strong>е</strong>ть ч<strong>е</strong>тыр<strong>е</strong> поля: R a n d o m iz e r для хран<strong>е</strong>ния ссылок на объ<strong>е</strong>кт<br />

R andom и три массива типа s t r i n g для информации о мяс<strong>е</strong>, приправах<br />

и хл<strong>е</strong>б<strong>е</strong>.<br />

class М<strong>е</strong>пиМак<strong>е</strong>г {<br />

public Random R andom izer;<br />

Пол<strong>е</strong> Randomizer<br />

сод<strong>е</strong>ржит ссылку— " ■,<br />

н а объ<strong>е</strong>кт Random, string [] M eats = { "Roast beef , Salami^<br />

Это инициализатор<br />

колл<strong>е</strong>кций,,<br />

с которым вы<br />

подробно познакомит<strong>е</strong>сь<br />

в глав<strong>е</strong> 8.<br />

М<strong>е</strong>пиМак<strong>е</strong>г<br />

Randomizer<br />

Meats<br />

Condiments<br />

Breads<br />

GetiVlenultemO<br />

Из эл<strong>е</strong>м<strong>е</strong>нтов этих тр<strong>е</strong>х массивов<br />

буд<strong>е</strong>т случайным образом<br />

создаваться сэндвич.<br />

"Turkey", "Ham", "Pastrami" };<br />

М <strong>е</strong> т о д NextQ г<strong>е</strong>н<strong>е</strong>- goring[] C o n d im en ts = { "yellow mustard", "brown mustard",<br />

p u p y e m случайны<strong>е</strong> "honey mustard", "mayo", "relish", "french dressing" };<br />

числа.<br />

string[] B r e a d s = { "rye", "white", "wheat", "pumpernickel",<br />

"Italian bread", "a roll" };<br />

^ Для доступа к эл<strong>е</strong>м<strong>е</strong>нту укажит<strong>е</strong> <strong>е</strong>го ном<strong>е</strong>р<br />

— в скобках. Наприм<strong>е</strong>р, эл<strong>е</strong>м<strong>е</strong>нт Breads[Z] им<strong>е</strong><strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> white.<br />

М <strong>е</strong>тод S e tM e n u Ite m O<br />

Наш класс долж<strong>е</strong>н создавать сэндвичи, поэтому добавим к н<strong>е</strong>му соотв<strong>е</strong>тствующий м<strong>е</strong>тод.<br />

Он буд<strong>е</strong>т использовать м<strong>е</strong>тод N e x t () объ<strong>е</strong>кта R andom для выбора эл<strong>е</strong>м<strong>е</strong>нта из каждого массива.<br />

При п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> м<strong>е</strong>тоду N e x t () ц<strong>е</strong>лочисл<strong>е</strong>нного парам<strong>е</strong>тра он возвраща<strong>е</strong>т случайно<strong>е</strong><br />

число м<strong>е</strong>ньш<strong>е</strong> знач<strong>е</strong>ния этого парам<strong>е</strong>тра. То <strong>е</strong>сть р<strong>е</strong>зультатом работы м<strong>е</strong>тода R a n d o m i z e r .<br />

N e x t (7) буд<strong>е</strong>т случайно<strong>е</strong> число от О до 6.<br />

Но как узнать, какой парам<strong>е</strong>тр нуж<strong>е</strong>н м<strong>е</strong>тоду N e x t {) ? Он л<strong>е</strong>гко вычисля<strong>е</strong>тся при помощи<br />

свойства массивов L e n g t h . Им<strong>е</strong>нно так вы получит<strong>е</strong> случайный ном<strong>е</strong>р эл<strong>е</strong>м<strong>е</strong>нта массива.<br />

М<strong>е</strong>тод<br />

QetMenuttemQ.<br />

возвр айка<strong>е</strong>т<br />

строку<br />

с названи<strong>е</strong>м<br />

сэндвича. }<br />

public string G etM en uItem O {<br />

string randomMeat = M e a t s [Randomizer.Next(Meats.Length)];<br />

string randomCondiment = Condiments[Randomizer.Next(Condiments.Length)];<br />

string randomBread = B r e a d s [Randomizer.Next(Breads.Length)];<br />

■r e t u r n randomMeat + " with " + randomCondiment + " on " + randomBread;<br />

Случайный эл<strong>е</strong>м<strong>е</strong>нт массива Meats попада<strong>е</strong>т в м<strong>е</strong>тод randomMeat<br />

пат<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>дачи парам<strong>е</strong>тра Meats.Length м<strong>е</strong>тоду Next() объ<strong>е</strong>кта<br />

Random. Массив Meats состоит из 5 эл<strong>е</strong>м<strong>е</strong>нтов, значит, Meats.Length<br />

равно 5, U м<strong>е</strong>тод Next(S) возвратит случайно<strong>е</strong> число от О до 4.<br />

дальш<strong>е</strong> > 179


джо говорит: «н<strong>е</strong> старый, а выд<strong>е</strong>ржанный»<br />

Р<br />

К^ак ЭЩО р»абогца<strong>е</strong>га.,<br />

в о з в р а щ а <strong>е</strong> т ч и с л о э л <strong>е</strong> м <strong>е</strong> н -<br />

т о й<br />

M e a ts . Т а к ч т о ra n d o m izer<br />

N e x t (M ea ts.L en g th ) д а <strong>е</strong> м , с л ц ч а й н о <strong>е</strong> ч и гл п<br />

> < о л и 7 с т в 7 э л <strong>е</strong> м <strong>е</strong> н т о в<br />

M e a t s [ й ш 5 о т Г г <strong>е</strong> г .N e x t ( M e a t s .Length) ]<br />

Meats - э т о массив строк, состоящий<br />

из п я т и э л <strong>е</strong> м <strong>е</strong> н т о в . tA e a ts ^ ^<br />

В<strong>е</strong><strong>е</strong>р’ (Ростбиф), л Meats[3j<br />

(В<strong>е</strong>тчина).<br />

н<br />

© Постро<strong>е</strong>ни<strong>е</strong> срормы<br />

Добавьт<strong>е</strong> к форм<strong>е</strong> ш<strong>е</strong>сть м<strong>е</strong>ток и задайт<strong>е</strong> свойство Text. Для этого воспользуйт<strong>е</strong>сь<br />

объ<strong>е</strong>ктом М<strong>е</strong>пиМак<strong>е</strong>г. Объ<strong>е</strong>кту потр<strong>е</strong>бу<strong>е</strong>тся присвоить начальны<strong>е</strong> знач<strong>е</strong>ния,<br />

используя н ов ы й экз<strong>е</strong>м п ляр класса Random.<br />

^<br />

П р и с в о и т <strong>е</strong> п о л ю R a n d o m i z e r<br />

p u b l i c F o rm l О { О б ъ <strong>е</strong> к т а М <strong>е</strong> п и М а к <strong>е</strong> г н о вы й<br />

In i tializecomponent О ; Г х^^^сса R a n d o m .<br />

}<br />

М<strong>е</strong>пиМак<strong>е</strong>г menu = new М<strong>е</strong>пиМак<strong>е</strong>гО { Randomizer = new Random О }j<br />

labell.Text = menu.GetMenuItemO;<br />

labels. Text = menu.GetMenuItemO;<br />

labels.Text = menu.GetMenuItemO;<br />

label4.Text = menu.GetMenuItemO;<br />

labels. Text = menu.GetMenuItemO;<br />

label6.Text = menu.GetMenuItemO;<br />

/ Вс<strong>е</strong> готово для запуска<br />

V<br />

м <strong>е</strong> т о Э й d^etMenыitem()<br />

Г ы получ<strong>е</strong>ния случайного<br />

\ м<strong>е</strong>ню из ш<strong>е</strong>сти пунктов.<br />

A ч т о б у д <strong>е</strong> т ,<br />

<strong>е</strong> с л и н <strong>е</strong> у к а -<br />

_ з а т ь н а ч а л ь н ы <strong>е</strong><br />

з н а ч <strong>е</strong> н и я п о л я<br />

R a n d o m iz e r ?<br />

И к а к э т о г о<br />

м о ж н о и з б <strong>е</strong> ­<br />

ж а т ь ?<br />

Посл<strong>е</strong> запуска<br />

программы ш<strong>е</strong>сть<br />

м<strong>е</strong>ток покаж ут<br />

ш<strong>е</strong>сть случайных<br />

р<strong>е</strong>ц<strong>е</strong>птов сэндвич<strong>е</strong>й.<br />

>1орру Joe's Menu<br />

Salami with honey m u sta rd on rye<br />

Roast beef with french dressing on v#ieat<br />

Turkey V/rith yellow mustard on wheat<br />

Turkey with mayo on white<br />

Pastrami vwth relish on Italian bread<br />

Roast beef vwth french dressing on pumpernicket<br />

180 глава 4


типы и ссылки<br />

Ссылки позболяют объ<strong>е</strong>ктам обращаться друг к другу<br />

Вы уж <strong>е</strong> вид<strong>е</strong>ли, как ф о р м ы обр ащ аю тся к объ<strong>е</strong>ктам п р и п о м о щ и ссы лоч н ы х<br />

п <strong>е</strong>р <strong>е</strong>м <strong>е</strong>н н ы х , к о т о р ы <strong>е</strong> вы зы ваю т м <strong>е</strong>тоды и п р о в <strong>е</strong>р я ю т зн ач <strong>е</strong>н и я пол <strong>е</strong>й . Д ля<br />

о б ъ <strong>е</strong>к т о в о п р <strong>е</strong>д <strong>е</strong> л <strong>е</strong> н ы т <strong>е</strong> ж <strong>е</strong> о п <strong>е</strong>р а ц и и , ч то и для ф о р м , п о т о м у ч то форма —<br />

это объ<strong>е</strong>кт. П р и о б р а щ <strong>е</strong> н и и объ <strong>е</strong>к тов друг к другу испол ьзу<strong>е</strong>тся к л ю ч <strong>е</strong>во<strong>е</strong><br />

сл ов о t h i s , с <strong>е</strong>го п о м ощ ь ю д<strong>е</strong>л а<strong>е</strong>тся ссы лка н а т<strong>е</strong>кущ ий экз<strong>е</strong>м п ляр класса.<br />

М<strong>е</strong>тод, заставляющий слона говорить<br />

Д о б а в и м к классу E l e p h a n t м <strong>е</strong>тод, п <strong>е</strong>рвы м п а р ам <strong>е</strong>тр ом к о т о р о г о буд<strong>е</strong>т с о о б щ <strong>е</strong> н и <strong>е</strong> о т о б ъ ­<br />

<strong>е</strong>кта e l e p h a n t . В торы м п а р ам <strong>е</strong>тр ом буд<strong>е</strong>т им я слона:<br />

public void TellMe(string message, Elephant whoSaidIt) {<br />

}<br />

MessageBox.Show(whoSaidlt.Name + ” says: " + message);<br />

М о ж н о д обав и ть м <strong>е</strong>то д b u t t o n 4 _ C l i c k ( ) , н о сд<strong>е</strong>лать э т о н уж н о до оп<strong>е</strong>ратора, п<strong>е</strong>р<strong>е</strong>загружающ<strong>е</strong>го<br />

ссылки( 1 1 o y d = l u c i n d a ;)!<br />

lloyd.TellMe("Hi", lucinda);<br />

О<br />

М ы вы звали м <strong>е</strong>то д T e llM e () (С каж и м н <strong>е</strong>) для Л л о й д а и п <strong>е</strong>р <strong>е</strong>д а л и <strong>е</strong>му два парам<strong>е</strong>тра: с т р о ­<br />

ку H i и ссылку на о б ъ <strong>е</strong>к т L ucinda. П а р а м <strong>е</strong>тр w h o S a i d I t (К то э т о сказал) испол ьзу<strong>е</strong>тся для<br />

доступ а к парам <strong>е</strong>тру Name л ю б о г о сл она, им я к о т о р о го буд<strong>е</strong>т п <strong>е</strong> р <strong>е</strong> д а н о м <strong>е</strong>тоду T e llM e ()<br />

вторы м парам <strong>е</strong>тром .<br />

Вызов одного м<strong>е</strong>тода другим<br />

Д о б а в и м м <strong>е</strong>то д S p e a k T o () к классу E l e p h a n t . И м <strong>е</strong> н н о зд<strong>е</strong>сь мы испол ьзу<strong>е</strong>м к л ю ч <strong>е</strong>в о<strong>е</strong> сл о­<br />

во t h is . О н о явля<strong>е</strong>тся ссы лк ой, позволяющ<strong>е</strong>й объ<strong>е</strong>кту рассказать о с<strong>е</strong>б<strong>е</strong>.<br />

public void SpeakTo(Elephant whoToTalkTo, string message) {<br />

whoToTalkTo.TellMe(message, this);<br />

к-як- что п я ботя р т<br />

П о см о т р и м , как эт о работа<strong>е</strong>т.<br />

Э т о т м <strong>е</strong> т о д к л а с с а E le p h a n t<br />

в(р13Ь1в а <strong>е</strong> т м с т д T a lk T o Q<br />

(П о го в о р и с ), п о з в о л я ю щ и й о д н о м у<br />

lloyd.SpeakToducinda, "Hello") ; с л о н у р а з г о в а р и в а т ь с д р у г и м .<br />

П р и вы зов<strong>е</strong> м <strong>е</strong>то д а S p e a k T o () для Л л о й д а вы исп ол ьзу<strong>е</strong>т<strong>е</strong> пар ам <strong>е</strong>тр t a l k T o (являю щ ийся<br />

ссы лк ой на Л ю си н ду), ч то б ы вы звать м <strong>е</strong>т о д T e llM e () для Л ю си н ды .<br />

WhoToTalkTo.TellMe(message, this);<br />

Ллойд использу<strong>е</strong>т<br />

WhoToTalkTo (со ссылкой на<br />

Люсинду) для вызова Т<strong>е</strong>11М<strong>е</strong>()<br />

ключ<strong>е</strong>во<strong>е</strong> слово this<br />

^зам<strong>е</strong>ня<strong>е</strong>тся ссылкой<br />

.на объ<strong>е</strong>кт Ллойд<br />

lucinda.TellMe(message, [ссылка на Ллойда]);<br />

В р<strong>е</strong>зультат<strong>е</strong> появля<strong>е</strong>тся окно диалога с обращ <strong>е</strong>н и <strong>е</strong>м к Л ю синд<strong>е</strong>:<br />

дальш<strong>е</strong> > 181


болтливы<strong>е</strong> объ<strong>е</strong>кты<br />

Сюда объ<strong>е</strong>кты <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> отправлялись<br />

с объ<strong>е</strong>ктами связано <strong>е</strong>щ<strong>е</strong> одно важно<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong> слово.<br />

Только что созданная ссылка, которгш пока никуда н<strong>е</strong> указыва<strong>е</strong>т,<br />

им<strong>е</strong><strong>е</strong>т по умолчанию знач<strong>е</strong>ни<strong>е</strong> n u ll.<br />

Dog fido;<br />

Dog lucky = new Dog();<br />

Пока сущ<strong>е</strong>ству<strong>е</strong>т один<br />

объ<strong>е</strong>кт, ссылка fido им<strong>е</strong><strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> null.<br />

fido = new DogO;<br />

Когда ссылка fido<br />

указыва<strong>е</strong>т на объ<strong>е</strong>кт, она<br />

оольил<strong>е</strong> н<strong>е</strong> равна null.<br />

Если присвоить lucky<br />

знач<strong>е</strong>ни<strong>е</strong> null, объ<strong>е</strong>кт буд<strong>е</strong>т<br />

уничтож<strong>е</strong>н, так как на н<strong>е</strong>го<br />

н<strong>е</strong> остан<strong>е</strong>тся ссылок.<br />

lucky = null;<br />

• Форма — это только объ<strong>е</strong>кт?<br />

^ ! Да! Им<strong>е</strong>нно поэтому код класса начина<strong>е</strong>тся<br />

с объявл<strong>е</strong>ния этого класса. Откройт<strong>е</strong><br />

код формы и уб<strong>е</strong>дит<strong>е</strong>сь сами. Зат<strong>е</strong>м<br />

откройт<strong>е</strong> файл P ro g ra m .cs для любой<br />

из написанных программ и посмотрит<strong>е</strong> на<br />

м<strong>е</strong>тод M ain O , вы найд<strong>е</strong>т<strong>е</strong> там строку<br />

new F o r m l{).<br />

Зач<strong>е</strong>м мн<strong>е</strong> мож<strong>е</strong>т потр<strong>е</strong>боваться<br />

ключ<strong>е</strong>во<strong>е</strong> слово null?<br />

О<br />

Часш'»<br />

^адаБа<strong>е</strong>Мы<strong>е</strong><br />

БоИ роС Ь!<br />

! Вот для такой пров<strong>е</strong>рки условия:<br />

i f ( l l o y d == n u l l) {<br />

Оно им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> tr u e , <strong>е</strong>сли ссылка<br />

l l o y d указыва<strong>е</strong>т на n u ll.<br />

Кром<strong>е</strong> того, ключ<strong>е</strong>во<strong>е</strong> слово n u l l<br />

позволя<strong>е</strong>т быстро избавиться от<br />

ставш<strong>е</strong>го н<strong>е</strong>нужным объ<strong>е</strong>кта. Если<br />

ссылки на объ<strong>е</strong>кт остаются, а вам он уж<strong>е</strong><br />

н<strong>е</strong> нуж<strong>е</strong>н, достаточно воспользоваться<br />

ключ<strong>е</strong>вым словом n u ll, и объ<strong>е</strong>кг буд<strong>е</strong>т<br />

уничтож<strong>е</strong>н.<br />

5 ах! ^<br />

/ \Л<br />

o b i« ''''<br />

Что на самом д<strong>е</strong>л<strong>е</strong> происходит<br />

с объ<strong>е</strong>ктами посл<strong>е</strong> попадания в мусор?<br />

Q ; Помнит<strong>е</strong>, в начал<strong>е</strong> п<strong>е</strong>рвой главы мы<br />

говорили об Общ<strong>е</strong>языковой исполняющ<strong>е</strong>й<br />

ср<strong>е</strong>д<strong>е</strong> (CLR)? Это виртуальная машина,<br />

управляющая вс<strong>е</strong>ми программами<br />

•NET. Виртуальной машиной называ<strong>е</strong>тся<br />

способ изоляции работающих программ<br />

от остальной оп<strong>е</strong>ративной сист<strong>е</strong>мы. Виртуальная<br />

машина управля<strong>е</strong>т использу<strong>е</strong>мой<br />

памятью. Она сл<strong>е</strong>дит за вс<strong>е</strong>ми объ<strong>е</strong>ктами,<br />

и как только посл<strong>е</strong>дняя ссылка на какойнибудь<br />

из объ<strong>е</strong>ктов исч<strong>е</strong>за<strong>е</strong>т, она освобожда<strong>е</strong>т<br />

оп<strong>е</strong>ративную память, которая была<br />

выд<strong>е</strong>л<strong>е</strong>на под этот объ<strong>е</strong>кг.<br />

182 глава 4


Часзцо<br />

З а д а в а <strong>е</strong> м ы <strong>е</strong><br />

БоИ роС Ь!<br />

типы и ссылки<br />

J > Я до сих пор н<strong>е</strong> оч<strong>е</strong>нь понимаю,<br />

как работают ссыпки.<br />

Q ; Ссылки — это способ доступа к м<strong>е</strong>тодам<br />

и полям. Создав ссылку на объ<strong>е</strong>кг Dog,<br />

вы получа<strong>е</strong>т<strong>е</strong> возможность пользоваться<br />

любыми м<strong>е</strong>тодами, опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нными для этого<br />

объ<strong>е</strong>кта. Для н<strong>е</strong>статич<strong>е</strong>ских м<strong>е</strong>тодов D o g .<br />

Bark () и D o g . Beg () можно опр<strong>е</strong>д<strong>е</strong>лить<br />

ссылку sp o t. Посл<strong>е</strong> ч<strong>е</strong>го для доступа к<br />

ним достаточно написать s p o t . Bark ()<br />

и s p o t . Beg (). Ссылки позволяют<br />

р<strong>е</strong>дакгировать поля объ<strong>е</strong>кта. Наприм<strong>е</strong>р, для<br />

вн<strong>е</strong>с<strong>е</strong>ния изм<strong>е</strong>н<strong>е</strong>ний в пол<strong>е</strong> B reed достаточно<br />

написать s p o t . Breed.<br />

Получа<strong>е</strong>тся, что р<strong>е</strong>дактируя<br />

объ<strong>е</strong>кт поср<strong>е</strong>дством одной ссылки,<br />

я м<strong>е</strong>няю <strong>е</strong>го знач<strong>е</strong>ни<strong>е</strong> для остальных<br />

ссылок?<br />

Q ; Да. Если r o v e r ссыла<strong>е</strong>тся на тот<br />

ж<strong>е</strong> объ<strong>е</strong>кт, что и spot, зам<strong>е</strong>нив r o v e r .<br />

B reed на beagle вы получит<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

beagle и для s p o t . Breed.<br />

П : я н<strong>е</strong> понимаю, поч<strong>е</strong>му п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

^зны х типов им<strong>е</strong>ют разный разм<strong>е</strong>р.<br />

Зач<strong>е</strong>м это нужно?<br />

^ ! П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> опр<strong>е</strong>д<strong>е</strong>ляют разм<strong>е</strong>р<br />

присваива<strong>е</strong>мого знач<strong>е</strong>ния. Если вы объявит<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную типа lo n g и присвоит<strong>е</strong><br />

<strong>е</strong>й знач<strong>е</strong>ни<strong>е</strong> (наприм<strong>е</strong>р, 5), CLR вс<strong>е</strong> равно<br />

выд<strong>е</strong>лит памяти на большо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

В конц<strong>е</strong> концов, на то они и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>,<br />

чтобы вс<strong>е</strong> вр<strong>е</strong>мя м<strong>е</strong>няться.<br />

CLR пр<strong>е</strong>дполага<strong>е</strong>т, что вы выбира<strong>е</strong>т<strong>е</strong><br />

тип осознанно и н<strong>е</strong> буд<strong>е</strong>т<strong>е</strong> объявлять<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную н<strong>е</strong>нужного типа. С<strong>е</strong>йчас<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная хранит н<strong>е</strong>большо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>,<br />

но потом оно мож<strong>е</strong>т стать большим. По- •<br />

этому для н<strong>е</strong><strong>е</strong> заран<strong>е</strong><strong>е</strong> выд<strong>е</strong>л<strong>е</strong>н нужный<br />

объ<strong>е</strong>м памяти.<br />

Напомнит<strong>е</strong> мн<strong>е</strong> <strong>е</strong>щ<strong>е</strong> раз, какую<br />

( )ункцию выполня<strong>е</strong>т ключ<strong>е</strong>во<strong>е</strong> слово<br />

t h i s ?<br />

Q ; t h i s — это сп<strong>е</strong>циальная п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная,<br />

использу<strong>е</strong>мая только внутри объ<strong>е</strong>кта.<br />

Она ссыла<strong>е</strong>тся на поля и м<strong>е</strong>тоды выбранного<br />

экз<strong>е</strong>мпляра. Это пол<strong>е</strong>зно при работ<strong>е</strong><br />

с классом, м<strong>е</strong>тоды которого обращаются<br />

к другим классам. Объ<strong>е</strong>кт мож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дать<br />

ссылку на с<strong>е</strong>бя другому объ<strong>е</strong>кту. Если<br />

S p ot вызыва<strong>е</strong>т один из м<strong>е</strong>тодов R over<br />

при помощи парам<strong>е</strong>тра t h i s , объ<strong>е</strong>кт<br />

R over получа<strong>е</strong>т ссылку на объ<strong>е</strong>кт Spot.<br />

Экз<strong>е</strong>мпляры объ<strong>е</strong>ктов<br />

используют<br />

ключ<strong>е</strong>во<strong>е</strong> слово this<br />

дая ссылки па самих<br />

с<strong>е</strong>бя.<br />

КЛЮЧЕВЫЕ<br />

МОМЕНТЫ<br />

При рассмотр<strong>е</strong>нии модификатора var<br />

в глав<strong>е</strong> 1 4 вы узна<strong>е</strong>т<strong>е</strong>, в каком случа<strong>е</strong> тип<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной н<strong>е</strong> обьявля<strong>е</strong>тся заран<strong>е</strong><strong>е</strong>.<br />

Объявляя п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную, вы ВСЕГДА указыва<strong>е</strong>т<strong>е</strong> <strong>е</strong><strong>е</strong><br />

тип. Иногда при этом задаются и начальны<strong>е</strong> знач<strong>е</strong>ния.<br />

Сущ<strong>е</strong>ству<strong>е</strong>т множ<strong>е</strong>ство значимых типов для хран<strong>е</strong>ния<br />

знач<strong>е</strong>ний разного разм<strong>е</strong>ра. Для огромных чис<strong>е</strong>л<br />

используйт<strong>е</strong> тип long — а для самых мал<strong>е</strong>ньких (до<br />

255) — bytes.<br />

Н<strong>е</strong>возможно присвоить знач<strong>е</strong>ни<strong>е</strong> больш<strong>е</strong>го типа п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной,<br />

принадл<strong>е</strong>жащ<strong>е</strong>й к м<strong>е</strong>ньш<strong>е</strong>му типу.<br />

При работ<strong>е</strong> с константами используйт<strong>е</strong> суффикс F<br />

для обознач<strong>е</strong>ния типа float (15.6F), а суффикс М —<br />

для обознач<strong>е</strong>ния типа decimal (36.12М).<br />

Н<strong>е</strong>которы<strong>е</strong> типы могут пр<strong>е</strong>образовываться друг<br />

в друга автоматич<strong>е</strong>ски (наприм<strong>е</strong>р, short в int).<br />

Для других случа<strong>е</strong>в используйт<strong>е</strong> оп<strong>е</strong>рацию прив<strong>е</strong>д<strong>е</strong>ния<br />

типов.<br />

Зар<strong>е</strong>з<strong>е</strong>рвированны<strong>е</strong> слова (наприм<strong>е</strong>р, for, while,<br />

using, new) н<strong>е</strong>льзя использовать в кач<strong>е</strong>ств<strong>е</strong> им<strong>е</strong>н<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных.<br />

Ссылки подобны накл<strong>е</strong>йкам: вы мож<strong>е</strong>т<strong>е</strong> им<strong>е</strong>ть множ<strong>е</strong>ство<br />

ссылок на один и тот ж<strong>е</strong> объ<strong>е</strong>кт.<br />

Если на объ<strong>е</strong>кт н<strong>е</strong>т ни одной ссылки, он отправля<strong>е</strong>тся<br />

в мусор, и м<strong>е</strong>сто, занима<strong>е</strong>мо<strong>е</strong> им в памяти, освобожда<strong>е</strong>тся.<br />

дальш<strong>е</strong> ► 183


возьми в руку карандаш<br />

П<strong>е</strong>р<strong>е</strong>д вами массив объ<strong>е</strong>ктов E lep h a n t и цикл для поиска слона<br />

с самыми большими ушами. Опр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> b ig g e s t E a r s .<br />

E ars п о сл <strong>е</strong> каждой ит<strong>е</strong>рации цикла fo r .<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

E lep h a n t [] e le p h a n t s = new E le p h a n t [7]<br />

' 8w созда<strong>е</strong>т<strong>е</strong> массив<br />

из 7 ссылок ElephantQ.<br />

e l e p h a n t s [0] = new E le p h a n t (){ Name = "L loyd", E a r S iz e = 4 0 };<br />

e l e p h a n t s [1] = new E le p h a n t () { Name = "L ucinda", E a r S iz e = 3 3 };<br />

e l e p h a n t s [2] = new E le p h a n t () { Name = "L arry", E a r S iz e = 4 2 };<br />

e l e p h a n t s [3] = new E le p h a n t () { Name = " L u c ille " , E a r S iz e = 3 2 };<br />

e l e p h a n t s [4] = new E le p h a n t () { Name = "L ars", E a r S iz e = 4 4 };<br />

П<strong>е</strong>рвый инд<strong>е</strong>кс<br />

любого массива<br />

рав<strong>е</strong>н О,<br />

поэтому п<strong>е</strong>рвым<br />

эл<strong>е</strong>м<strong>е</strong>нтом<br />

I Зуд<strong>е</strong>т<br />

Elephants[0].<br />

e l e p h a n t s [5] = new E le p h a n t () { Name = "Linda", E a r S iz e = 3 7 };<br />

e l e p h a n t s [6] = new E le p h a n t () { Name = "Humphrey", E a r S iz e = 4 5 };<br />

E lep h a n t b ig g e s t E a r s = e l e p h a n t s [0 ];<br />

Ит<strong>е</strong>рация #1 biggestEars.EarSize =<br />

f o r ( i n t i = 1; i < e le p h a n t s .L e n g t h ; i++)<br />

^ Ит<strong>е</strong>рация #2 biggestEars.EarSize =.<br />

i f ( e l e p h a n t s [ i ] .E a r S i z e > b ig g e s t E a r s .E a r S iz e )<br />

{<br />

b ig g e s t E a r s = e l e p h a n t s [ i ] ;<br />

i^licpc Ит<strong>е</strong>рация #3 biggestEars.EarSize =,<br />

} Точкд останова в этой ст рок<strong>е</strong><br />

помож<strong>е</strong>т отсл<strong>е</strong>дить знач<strong>е</strong>ния<br />

clepkantsli] вс<strong>е</strong>х эл<strong>е</strong>м<strong>е</strong>нтов массива.<br />

M essa g eB o x . S h o w ( b ig g e s t E a r s . E a r S i z e . T o S t r i n g ( ) ) ;<br />

Ит<strong>е</strong>рация #4 biggestEars.EarSize =<br />

Будьт<strong>е</strong> внимат<strong>е</strong>льны, этот цикл<br />

начина<strong>е</strong>тся со второго эл<strong>е</strong>м<strong>е</strong>нта<br />

массива (с инд<strong>е</strong>ксом 1) и выполня<strong>е</strong>тся<br />

ш<strong>е</strong>сть раз, пока 1 н<strong>е</strong> становится<br />

равной длин<strong>е</strong> массива.<br />

Ит<strong>е</strong>рация #5 biggestEars.EarSize =<br />

Ит<strong>е</strong>рация #6 biggestEars.EarSize = _<br />

184 глава 4<br />

QuiBeni на с. 92*


типы и ссылки<br />

^ а Г н и т ь ! с КоДоМ<br />

Магниты с фрагм<strong>е</strong>нтами кода упали с холодильника.<br />

В<strong>е</strong>рнит<strong>е</strong> их на м<strong>е</strong>сто, чтобы получить код, приводящий<br />

к появл<strong>е</strong>нию показанной ниж<strong>е</strong> формы.<br />

refNum = index[y]; |<br />

int refNum;<br />

while (y < 4 ) {<br />

resu<br />

]_t += islands [refNumJ ,<br />

MessageBox.Show(result);<br />

□<br />

string[] islands = new string[4]; |<br />

result += "\nisland = "•<br />

in d e x = new int f4J;<br />

у = Y + i<br />

istartd = Fiji<br />

island = C ozu m el<br />

island = Berm uda<br />

island = Azores<br />

p r i v a t e v o id b u t t o n l C lic k frihTIZZ ^ — ---------- -------------------<br />

I _ -Lick ( o b j e c t s e n d e r , E ven tA rgs e)<br />

□<br />

OK<br />

-------------- ► QuiBero Ha c. 93-


магниты с кодом и р<strong>е</strong>бус в басс<strong>е</strong>йн<strong>е</strong><br />

Р<strong>е</strong>зультат:<br />

<strong>е</strong> ^ с Б б а с с <strong>е</strong> й н <strong>е</strong><br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из<br />

басс<strong>е</strong>йна и пом<strong>е</strong>стит<strong>е</strong> их на<br />

пусты<strong>е</strong> строчки. Каждый<br />

фрагм<strong>е</strong>нт можно использовать<br />

н<strong>е</strong>сколько раз.<br />

В басс<strong>е</strong>йн<strong>е</strong> <strong>е</strong>сть и лишни<strong>е</strong><br />

фрагм<strong>е</strong>нты. Нужно получить<br />

окно, в котором для каждого<br />

тр<strong>е</strong>угольника (triangle) буд<strong>е</strong>т показана<br />

<strong>е</strong>го площадь (area).<br />

c l a s s T r ia n g le<br />

{<br />

d o u b le a r e a ;<br />

i n t h e ig h t ;<br />

i n t le n g t h ;<br />

I K “e<br />

p u b l i c s t a t i c v o id M a i n ( s t r i n g []<br />

{<br />

s t r i n g r e s u l t s =<br />

w h ile (<br />

{<br />

.h e ig h t = (x + 1) * 2;<br />

• le n g t h = X + 4;<br />

a r g s<br />

tria n g le 0, a rea 4<br />

tria n g le 1 , a rea = 10<br />

tria n g le 2, a re a = 18<br />

tria n g le 3, a re a = _<br />

y=__________<br />

}<br />

r e s u l t s += " t r ia n g l e " + x + ", area " ,<br />

r e s u l t s += " = " + _______.a r e a + "\n";<br />

OK<br />

Дополнит<strong>е</strong>льный вопрос!<br />

Вспользуйт<strong>е</strong>сь фрагм<strong>е</strong>нтами из басс<strong>е</strong>йна,<br />

чтобы составить код, заполняющий<br />

даж<strong>е</strong> пусты<strong>е</strong> поля в нижн<strong>е</strong>й части<br />

окна диалога.<br />

X = 27;<br />

T r ia n g le t5 = t a [ 2 ] ;<br />

t a [ 2 ] . a r e a = 343;<br />

r e s u l t s += "y = " + y;<br />

M e s sa g e B o x .S h o w (r e s u lts +<br />

", t5 a r e a = " + t B .a r e a ) ;<br />

v o id se tA r e a O<br />

= (h e ig h t * le n g th )<br />

Подсказка: М<strong>е</strong>тод<br />

SetAreaQ<br />

HE явля<strong>е</strong>тся<br />

статич<strong>е</strong>ским.<br />

К аж ды й ф р агм <strong>е</strong>н т кода<br />

м ож но и сп о л ь зо в ать н <strong>е</strong> ­<br />

сколько раз!<br />

4, t5 area = 18<br />

area<br />

4, t5 area = 343<br />

ta.area<br />

int х;<br />

27, t5 area = 18<br />

X ta.x.area<br />

ta.x.area<br />

int у;<br />

27, t5 area = 343<br />

X = X + 1; t a j ^ ^<br />

y laixj.area ta[x].area<br />

^<br />

int X ==0; X = X + 2; ta(x)<br />

int X<br />

Triangle [ ] ta = new Trlangle(4); setArea();<br />

== 1; ' X = X -1; ta[x]<br />

int у ==x;<br />

Triangle ta = new [ ] Triangle[4]; ta.x = setArea();<br />

ta = new<br />

28<br />

TriangleO;<br />

Triangle [ ] ta = new Triangle[4]; ta[x].setArea();<br />

ta[x]<br />

30.0<br />

= newTriangleO<br />

^ ta.x = new TriangleO;<br />

186 глава 4<br />

ОхпБ<strong>е</strong>ш на С.


типы и ссылки<br />

игра<strong>е</strong>м 6 п<strong>е</strong>чатную машинку<br />

Вы достигли п<strong>е</strong>рвых р<strong>е</strong>зультатов... и зна<strong>е</strong>т<strong>е</strong> достаточно, чтобы создать собств<strong>е</strong>нную<br />

игру! Пусть в форм<strong>е</strong> случайным образом появляются буквы. Если игрок вводит букву<br />

правильно, она исч<strong>е</strong>за<strong>е</strong>т, а уров<strong>е</strong>нь раст<strong>е</strong>т. Если ж<strong>е</strong> буква вв<strong>е</strong>д<strong>е</strong>на н<strong>е</strong>правильно, уров<strong>е</strong>нь<br />

ум<strong>е</strong>ньша<strong>е</strong>тся. По м<strong>е</strong>р<strong>е</strong> ввода букв игра усложня<strong>е</strong>тся. Как только форма оказыва<strong>е</strong>тся за-'у' / |<br />

полн<strong>е</strong>на буквами, игра заканчива<strong>е</strong>тся! \ ^<br />

Hit th e квуіїЗ<br />

и К К N С<br />

Cotrect, 18 M issed-3 Total: Д Accuracy; 85%<br />

^ іо р м а<br />

Вот как она должна выгляд<strong>е</strong>ть в конструктор<strong>е</strong> форм.<br />

listBoxI<br />

Correct О Total: О Accuracy: 0 %<br />

Уб<strong>е</strong>рит<strong>е</strong> кнопки управл<strong>е</strong>ния разм<strong>е</strong>рами окна. Для свойства FormBorderStyle выб<strong>е</strong>рит<strong>е</strong><br />

вариант FixedSD. Т<strong>е</strong>п<strong>е</strong>рь игрок н<strong>е</strong> смож<strong>е</strong>т случайно п<strong>е</strong>р<strong>е</strong>тащить форму и изм<strong>е</strong>нить <strong>е</strong><strong>е</strong><br />

разм<strong>е</strong>р. Установит<strong>е</strong> разм<strong>е</strong>р 876 X 174.<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> из окна Toolbox на форму эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния ListBox. Присвойт<strong>е</strong> свойству<br />

Dock знач<strong>е</strong>ни<strong>е</strong> Fill. Свойству MultiColimm присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> True. Для свойства<br />

Font выб<strong>е</strong>рит<strong>е</strong> к<strong>е</strong>гль 72 пункта и полужирно<strong>е</strong> нач<strong>е</strong>ртани<strong>е</strong>.<br />

В окн<strong>е</strong> Toolbox раскройт<strong>е</strong> группу All Windows Forms. Найдит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния Timer<br />

и дважды щ<strong>е</strong>лкнит<strong>е</strong> на н<strong>е</strong>м, чтобы добавить <strong>е</strong>го к форм<strong>е</strong>.<br />

Зат<strong>е</strong>м найдит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния StatusStrip и двойным щ<strong>е</strong>лчком добавьт<strong>е</strong> к форм<strong>е</strong><br />

строку состояния. В нижн<strong>е</strong>й части конструктора формы должны появиться значки эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния StatusStrip и Timer:<br />

0 timerl statusStripl<br />

J<br />

дальш<strong>е</strong> * 187


создадим что-нибудь забавно<strong>е</strong><br />

★<br />

О Парам<strong>е</strong>тры эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния StatusStrip<br />

Обратит<strong>е</strong> внимани<strong>е</strong> на п<strong>е</strong>рвый рисунок данного<br />

разд<strong>е</strong>ла. В нижн<strong>е</strong>й части строки состояния вы<br />

увидит<strong>е</strong> м<strong>е</strong>тки:<br />

I Correcte 18 M t5sedi3 T o tab Z t A c c u f a ^ 8 5 % |<br />

A с другой стороны —м<strong>е</strong>тку и индикатор:<br />

ІССЛАРТКЇ)<br />

Вы познакомились с тр<strong>е</strong>мя<br />

новыми эл<strong>е</strong>м<strong>е</strong>нтами управл<strong>е</strong>ния!<br />

Задать свойства для ListBox,<br />

StatusStrip и Timer вы смож<strong>е</strong>т<strong>е</strong> знакомым<br />

способом.<br />

I Difficulty Ь ю у у ж<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на стр<strong>е</strong>лк<strong>е</strong> справа от эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния<br />

S t a t u s S t r i p и выб<strong>е</strong>рит<strong>е</strong> в появивш<strong>е</strong>мся м<strong>е</strong>ню вариант<br />

S t a t u s L a b e l :<br />

S tatusL abel<br />

ProgressBar<br />

D ro p D o w n B u tto n<br />

Ш<br />

SplitButton<br />

★<br />

★<br />

Свойству S i z i n g G r i p эл<strong>е</strong>м<strong>е</strong>нта S t a t u s S t r i p присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> False.<br />

В окн<strong>е</strong> Properties присвойт<strong>е</strong> свойству (Name) знач<strong>е</strong>ни<strong>е</strong> c o r r e c t L a b e l , а свойству T e x t<br />

знач<strong>е</strong>ни<strong>е</strong> Correct: О (Правильных: 0). Добавьт<strong>е</strong> три аналогичны<strong>е</strong> м<strong>е</strong>тки: m i s s e d L a b e l ,<br />

t o t a l L a b e l и a c c u r a c y L a b e l (Пропущ<strong>е</strong>нных, Вс<strong>е</strong>го и Точность).<br />

О<br />

★<br />

Добавьт<strong>е</strong> S t a t u s L a b e l . Укажит<strong>е</strong> для S p r i n g знач<strong>е</strong>ни<strong>е</strong> T r u e , для T e x t A l i g n знач<strong>е</strong>ни<strong>е</strong><br />

M id d l e R ig h t и для T e x t — D i f f i c u l t y (Сложность). Напосл<strong>е</strong>док добавьт<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт<br />

P r o g r è s s B a r и присвойт<strong>е</strong> <strong>е</strong>му имя d i f f і c u l t y P r o g r e s s B a r .<br />

Парам<strong>е</strong>тры эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния Timer.<br />

Вы зам<strong>е</strong>тили, что эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния Timer на форм<strong>е</strong> отсутству<strong>е</strong>т? Д<strong>е</strong>ло в том, что это н<strong>е</strong>визуалъный<br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>нім. Он н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>т вида формы. Его функция снова и снова вы ­<br />

зы вать н<strong>е</strong>кий м<strong>е</strong>тод. Присвойт<strong>е</strong> свойству I n t e r v a l знач<strong>е</strong>ни<strong>е</strong> 800, чтобы вызов м<strong>е</strong>тода происходил<br />

кажды<strong>е</strong> 800 миллис<strong>е</strong>кунд. Зат<strong>е</strong>м дважды щ<strong>е</strong>лкнит<strong>е</strong> на значк<strong>е</strong> timerl в конструктор<strong>е</strong>,<br />

чтобы добавить к форм<strong>е</strong> м<strong>е</strong>тод tim e rl_ T ic k . Вот код для этого м<strong>е</strong>тода:<br />

p r i v a t e v o id t i m e r l_ T i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

/ / Добавим случайную клавишу к эл<strong>е</strong>м <strong>е</strong>н ту L is tB o x<br />

l i s t B o x l . Ite m s .Add ( (K eys) random .N ext (65, 9 0 ) ) ;<br />

i f ( l i s t B o x l . I t e m s . Count > 7)<br />

{<br />

l i s t B o x l . I t e m s . C l e a r 0 ;<br />

l i s t B o x l . I te m s .A d d ( "Игра оконч<strong>е</strong>на!");<br />

t i m e r l . S t o p ( );<br />

}<br />

Скоро вы добавит<strong>е</strong><br />

пол<strong>е</strong> гап(£от. Мож<strong>е</strong>т<strong>е</strong><br />

ли вы с<strong>е</strong>йчас<br />

назвать <strong>е</strong>го тип?<br />

188 глава 4


типы и ссылки<br />

Класс, отсл<strong>е</strong>живающий статистику игры<br />

Так как в форм<strong>е</strong> должно отображаться общ<strong>е</strong><strong>е</strong> колич<strong>е</strong>ство нажатых, пропущ<strong>е</strong>нных<br />

и правильно нажатых клавиш, а такж<strong>е</strong> точность, значит, мы должны<br />

отсл<strong>е</strong>живать вс<strong>е</strong> эти данны<strong>е</strong>. Каж<strong>е</strong>тся, нам потр<strong>е</strong>бу<strong>е</strong>тся новый класс!<br />

Назовит<strong>е</strong> <strong>е</strong>го S t a t s . Он буд<strong>е</strong>т сод<strong>е</strong>ржать ч<strong>е</strong>тыр<strong>е</strong> поля типа i n t с им<strong>е</strong>нами<br />

T o t a l (Вс<strong>е</strong>го), M i s s e d (Пропущ<strong>е</strong>но), C o r r e c t (Правильно) и A c c u r a c y<br />

(Точность), а такж<strong>е</strong> м<strong>е</strong>тод U p d a t e с одним парам<strong>е</strong>тром типа b o o l , который<br />

получа<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> t r u e , <strong>е</strong>сли нажатая игроком клавиша совпала с буквой,<br />

появивш<strong>е</strong>йся в окн<strong>е</strong> ListBox, и знач<strong>е</strong>ни<strong>е</strong> f a ls e , <strong>е</strong>сли игрок ошибся.<br />

c l a s s S t a t s<br />

{<br />

p u b l i c i n t T o t a l = 0;<br />

p u b l i c i n t M isse d = 0;<br />

p u b l i c i n t C o r r e c t = 0;<br />

p u b l i c i n t A c cu ra c y = 0;<br />

p u b l i c v o id U p d a te (b o o l c o r r e c tK e y )<br />

{<br />

T o t a l ++;<br />

i f ( ! c o r r e c tK e y )<br />

{<br />

M isse d + + ;<br />

}<br />

e l s e<br />

{<br />

}<br />

C o r r e c t ++;<br />

При каждом вызов<strong>е</strong> м<strong>е</strong>тода<br />

UpdateQ вычисля<strong>е</strong>тся проц<strong>е</strong>нт<br />

правильных попаданий,<br />

а р<strong>е</strong>зультат этих вычисл<strong>е</strong>ний<br />

пом<strong>е</strong>ица<strong>е</strong>тся в пол<strong>е</strong> Accuracy.<br />

}<br />

}<br />

A c cu ra c y = 100 * C o r r e c t / (M issed + C o r r e c t) ;<br />

Поля для отсл<strong>е</strong>живания объ<strong>е</strong>ктов Stats и Random<br />

Вам потр<strong>е</strong>бу<strong>е</strong>тся экз<strong>е</strong>мпляр класса Stats для хран<strong>е</strong>ния информации, поэтому добавьт<strong>е</strong> пол<strong>е</strong><br />

stats. Как вы уж<strong>е</strong> вид<strong>е</strong>ли, пол<strong>е</strong> random, сод<strong>е</strong>ржащ<strong>е</strong><strong>е</strong> объ<strong>е</strong>кт Random, пока отсутству<strong>е</strong>т.<br />

Напишит<strong>е</strong> в в<strong>е</strong>рхн<strong>е</strong>й части кода формы:<br />

p u b l i c p a r t i a l c l a s s Forml<br />

{<br />

: Form<br />

Random random = new Random();<br />

Stats stats = new Stats();<br />

Пр<strong>е</strong>жд<strong>е</strong> ч<strong>е</strong>м продолжить, присвойт<strong>е</strong> свойству<br />

Enabled тайм<strong>е</strong>ра знач<strong>е</strong>ни<strong>е</strong> True. Для эл<strong>е</strong>м<strong>е</strong>нта<br />

ProgressBar сд<strong>е</strong>лайт<strong>е</strong> свойство Maximum<br />

равным 701, а для свойства KeyPreview<br />

формы выб<strong>е</strong>рит<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> True. Попробуйт<strong>е</strong><br />

отв<strong>е</strong>тить на вопрос, что буд<strong>е</strong>т,<br />

<strong>е</strong>сли это н<strong>е</strong> сд<strong>е</strong>лать?<br />

дальш<strong>е</strong> ► 189


ключ к пр<strong>е</strong>красной игр<strong>е</strong><br />

{<br />

Оп<strong>е</strong>ратор<br />

if пров<strong>е</strong>ря<strong>е</strong>т<br />

н а л и ч и <strong>е</strong> ^<br />

в ListBox нажатой<br />

игроком<br />

буквы.<br />

Контроль за нажати<strong>е</strong>м клавиш.<br />

Осталось сд<strong>е</strong>лать так, чтобы правильно нажатая игроком буква удалялась из окна ListBox),<br />

а статистика S t a tu s S t r i p обновлялась.<br />

В<strong>е</strong>рнит<strong>е</strong>сь к конструктору форм и выд<strong>е</strong>лит<strong>е</strong><br />

форму. Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> с изображ<strong>е</strong>ни<strong>е</strong>м<br />

молнии в в<strong>е</strong>рхн<strong>е</strong>й части окна Properties, а зат<strong>е</strong>м<br />

дважды щ<strong>е</strong>лкнит<strong>е</strong> на строчк<strong>е</strong> KeyDown,<br />

чтобы добавить м<strong>е</strong>тод Forml_KeyDown (), вызыва<strong>е</strong>мый<br />

при каждом нажатии клавиши. Вот<br />

код для этого м<strong>е</strong>тода:<br />

Properties<br />

О' !<br />

InputlanguageChdf<br />

Forml System.Wim<br />

KeyPfess<br />

p r i v a t e v o id F orm l_K eyD ow n(ob ject s e n d e r , K eyE ventA rgs e)<br />

П<br />

и<br />

i f<br />

{<br />

KeyUp<br />

Е с л и п о л ь з о в а т <strong>е</strong> л ь п р а в и л ь н о н а ж и м а <strong>е</strong> т клавишу,<br />

и у в <strong>е</strong> л и ч ь т <strong>е</strong> с к о р о с т ь п о я в л <strong>е</strong> н и я букв<br />

( l i s t B o x l . I t e m s . C o n t a in s ( <strong>е</strong> . K eyC ode))<br />

l i s t B o x l . I te m s .R e m o v e (e . K eyC od e);<br />

l i s t B o x l . R e f r e s h ( );<br />

i f ( t i m e r l . I n t e r v a l<br />

t i m e r l . I n t e r v a l<br />

i f ( t i m e r l . I n t e r v a l<br />

t i m e r l . I n t e r v a l<br />

i f ( t i m e r l . I n t e r v a l<br />

t i m e r l . I n t e r v a l<br />

n l.K eyO sm i Ц<br />

Эта кнопка м<strong>е</strong>ня<strong>е</strong>т<br />

вид окна Properties.<br />

Кнопка сл<strong>е</strong>ва от<br />

н<strong>е</strong><strong>е</strong> возвраш,а<strong>е</strong>т<br />

окно к привычноми<br />

виду.<br />

Вы получа<strong>е</strong>т<strong>е</strong><br />

список событий<br />

(events). О том,<br />

что это тако<strong>е</strong>,<br />

мы поговорим<br />

поздн<strong>е</strong><strong>е</strong>.<br />

у д а л и т <strong>е</strong> б у к в у из L is tB o x ,<br />

Ум<strong>е</strong>ньшая числа, вычита<strong>е</strong>мы<strong>е</strong> из<br />

парам<strong>е</strong>тра timeri-.Interval, вы<br />

обл<strong>е</strong>гча<strong>е</strong>т<strong>е</strong> игру, а ув<strong>е</strong>личивая —<br />

усложня<strong>е</strong>т<strong>е</strong> <strong>е</strong><strong>е</strong>.<br />

d i f f i c u lt y P r o g r e s s B a r .V a l u e = 800 - t i m e r l . I n t e r v a l ;<br />

При нажатии<br />

клавиши<br />

м<strong>е</strong>тод Forml.<br />

KeyPown()<br />

вызыва<strong>е</strong>т м <strong>е</strong> ­<br />

тод UpdateQ<br />

объ<strong>е</strong>кта Stats,<br />

обновляющий<br />

ст ат ист и-<br />

ку, а зат<strong>е</strong>м<br />

р<strong>е</strong>зультат<br />

от о-<br />

6J}aжaemcя<br />

StatusStrip.<br />

''<br />

}<br />

e l s e<br />

{<br />

}<br />

/ / П р и п р а в и л ь н о м н а ж а т и и к л а в и ш и о б н о в л я <strong>е</strong> м о б ъ <strong>е</strong> к т S t a t s ,<br />

/ / в ы з ы в а я м <strong>е</strong> т о д U p d a te () с а р г у м <strong>е</strong> н т о м t r u e<br />

s t a t s . U p d a t e ( t r u e ) ;<br />

// П р и н <strong>е</strong> п р а в и л ь н о м н а ж а т и и к л а в и ш и о б н о в л я <strong>е</strong> м о б ъ <strong>е</strong> к т S t a t s ,<br />

// в ы з ы в а я м <strong>е</strong> т о д U p d a te () с а р г у м <strong>е</strong> н т о м f a l s e<br />

s t a t s . U p d a t e ( f a l s e ) ;<br />

/ / О б н о в л <strong>е</strong> н и <strong>е</strong> м <strong>е</strong> т о к э л <strong>е</strong> м <strong>е</strong> н т а S t a t u s S t r i p<br />

c o r r e c t L a b e l .T e x t = " C o rrect: " -i- s t a t s . C o r r e c t ,•<br />

m is s e d L a b e l. T ex t = "M issed: " + s t a t s . M issed ;<br />

t o t a l L a b e l.T e x t = " T o ta l: " + s t a t s . T o t a l ;<br />

a c c u r a c y L a b e l. T ex t = "A ccuracy: " + s t a t s .A c c u r a c y +<br />

Запуск игры.<br />

В окно ListBox должно пом<strong>е</strong>щаться ровно 7 букв, поэтому мож<strong>е</strong>т потр<strong>е</strong>боваться пом<strong>е</strong>нять<br />

разм<strong>е</strong>р шрифта. Для изм<strong>е</strong>н<strong>е</strong>ния уровня сложности отр<strong>е</strong>дактируйт<strong>е</strong> знач<strong>е</strong>ния вычита<strong>е</strong>мы<strong>е</strong> из<br />

парам<strong>е</strong>тра t i m e r l . I n t e r v a l в м<strong>е</strong>тод<strong>е</strong> F o rm l_ K ey D o w n ( ) .<br />

190<br />

глава 4<br />

★ -


типы и ссылки<br />

г^раж н<strong>е</strong>ниб<br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

namespace<br />

Ещ <strong>е</strong> раз напомним, что в С # сущ<strong>е</strong>ству<strong>е</strong>т прим<strong>е</strong>рно 77 за р <strong>е</strong> з<strong>е</strong> р в и р о в а н ­<br />

н ы х слов. Вам было пр<strong>е</strong>длож<strong>е</strong>но объяснить назнач<strong>е</strong>ни<strong>е</strong> н<strong>е</strong>которых из<br />

них. Вот правильны<strong>е</strong> отв<strong>е</strong>ты.<br />

Пространство им<strong>е</strong>н — это логич<strong>е</strong>ско<strong>е</strong> поняти<strong>е</strong>, объ<strong>е</strong>диняюи^<strong>е</strong><strong>е</strong><br />

связанны<strong>е</strong> друг с другом классы и типы.<br />

for<br />

Это цикл, выполняющий оп<strong>е</strong>ратор или блок оп<strong>е</strong>раторов, пока<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нно<strong>е</strong> выраж<strong>е</strong>ни<strong>е</strong> н<strong>е</strong> прим<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> false.<br />

class<br />

Класс —- это опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>кта. Классы им<strong>е</strong>ют<br />

свойства и м<strong>е</strong>тоды.<br />

public<br />

Ключ<strong>е</strong>во<strong>е</strong> слово, дающ<strong>е</strong><strong>е</strong> уров<strong>е</strong>нь доступа с максимальными правами.<br />

Public class мож<strong>е</strong>т использоваться любым другим классом.<br />

else<br />

Оп<strong>е</strong>ратор, который выполня<strong>е</strong>тся, <strong>е</strong>сли пров<strong>е</strong>рка условия if в<strong>е</strong>рнула<br />

знач<strong>е</strong>ни<strong>е</strong> false.<br />

while<br />

Цикл while выполня<strong>е</strong>тся до т<strong>е</strong>х пор, пока услови<strong>е</strong> им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

true.<br />

using<br />

Опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т пространства им<strong>е</strong>н, пр<strong>е</strong>дустановл<strong>е</strong>нны<strong>е</strong> и созданны<strong>е</strong> вами<br />

классы, которы<strong>е</strong> используются в программ<strong>е</strong>.<br />

if<br />

Оп<strong>е</strong>ратор, выбирающий други<strong>е</strong> оп<strong>е</strong>раторы по р<strong>е</strong>зультатам<br />

пров<strong>е</strong>рки условия.<br />

new<br />

Оп<strong>е</strong>ратор, создающий новый экз<strong>е</strong>мпляр объ<strong>е</strong>кта.


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

озьми в руку карандаш<br />

’<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как выглядят р<strong>е</strong>зультаты опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ния самого большого<br />

слоновь<strong>е</strong>го уха на каждой ит<strong>е</strong>рации цикла for.<br />

p r i v a t e v o id b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

E le p h a n t [] e le p h a n t s = new E le p h a n t [7 ];<br />

e l e p h a n t s [0] = new E le p h a n t () { Name = "L loyd", E a r S iz e = 4 0 };<br />

e l e p h a n t s [1] = new E le p h a n t () { Name = "L ucinda", E a r S iz e = 3 3 };<br />

e l e p h a n t s [2] = new E le p h a n t () { Name = "L arry", E a r S iz e = 4 2 };<br />

e l e p h a n t s [3] = new E le p h a n t () { Name = " L u c ille " , E a r S iz e = 3 2 };<br />

e l e p h a n t s [4] = new E le p h a n t () { Name = " L a rs" , E a r S iz e = 44 };<br />

e le p h a n t s [5] = new E le p h a n t () { Name = "L inda", E a r S iz e = 3 7 };<br />

e le p h a n t s [6] = new E le p h a n t () { Name = "Humphrey", E a r S iz e = 45 }<br />

Помнит<strong>е</strong>, 41^0<br />

цикл НйИиНйбИЛСЯ<br />

со второго эл<strong>е</strong>м<strong>е</strong>нта<br />

т с с м а .<br />

Как 6(?| Эулла<strong>е</strong>т<strong>е</strong>,<br />

поч<strong>е</strong>му?<br />

E lep h a n t b ig g e s t E a r s = e l e p h a n t s [0 ];<br />

Ит<strong>е</strong>рация #1 biggestEars.EarSize = 4 0<br />

f o r ( i n t i = 1; i < e le p h a n t s .L e n g t h ; i++ )<br />

{<br />

Ит<strong>е</strong>рация #2 biggestEars.EarSize = 4 2<br />

i f ( e l e p h a n t s [ i ] . E a r S iz e > b ig g e s t E a r s .E a r S iz e )<br />

{<br />

t Ссылка<br />

biggestEars<br />

b ig g e s t E a r s = e le p h a n t s [i] ; отсл<strong>е</strong>жива<strong>е</strong>т 4 2 ,<br />

самый боль - Ит<strong>е</strong>рация #3 biggestEars.EarSize =<br />

} Пом<strong>е</strong>стит<strong>е</strong> сюда точку эл<strong>е</strong>м<strong>е</strong>нт<br />

— останова для пров<strong>е</strong>рки g ц^кл<strong>е</strong>.<br />

>} р<strong>е</strong>зультата.<br />

M e s s a g e B o x .S h o w ( b ig g e s t E a r s .E a r S iz e .T o S tr in g ( ) );<br />

/<br />

иОЛОШ^, .. - .......<br />

на<strong>е</strong>т указывать нд н<strong>е</strong>го. Таким<br />

образом опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся слон с самыми<br />

большими ушами.<br />

Ит<strong>е</strong>рация #4 biggestEars.EarSize =<br />

Ит<strong>е</strong>рация #5 biggestEars.EarSize =<br />

•4 -S<br />

Ит<strong>е</strong>рация #6 biggestEars.EarSize = _____<br />

192 глава 4


типы и ссылки<br />

|^<strong>е</strong>1Н<strong>е</strong>ни<strong>е</strong> Задачи сг МаГнишаМи<br />

Вот каким образом нужно было расположить на холодильник<strong>е</strong><br />

магниты с фрагм<strong>е</strong>нтами кода.<br />

f ^ c b задаются<br />

^лчальны<strong>е</strong><br />

знач<strong>е</strong>ния<br />

массива fndexli<br />

Зд<strong>е</strong>сь задаются<br />

начальны<strong>е</strong> знач<strong>е</strong>ния<br />

массива 1$1апи51].<br />

i n t refN um ; |<br />

Итоговая строка<br />

составля<strong>е</strong>тся<br />

при помощи<br />

оп<strong>е</strong>ратора +=■<br />

while<br />

^^^М<strong>е</strong>нилы<br />

^^ссива indexn<br />

w h ile ^ (y < 4) { P<br />

retN um = i n d e x [ y ] ;<br />

r e s u l t += " \ n i s l a n d = 1<br />

r e s u l t += isla n d s[r e fN u m ];<br />

J<br />

island = Fiji<br />

island = C o zu m el<br />

island = B erm uda<br />

island = Azores<br />

О<br />

□<br />

дальш<strong>е</strong> > 193


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>буса<br />

<strong>е</strong> Ш <strong>е</strong> н и <strong>е</strong> ]= * <strong>е</strong> ^ с а Б б а с с <strong>е</strong> й н <strong>е</strong><br />

ОтВ<strong>е</strong>ш на дополнит<strong>е</strong>льный<br />

Вопрос:<br />

trtangte 0, area = 4<br />

triangle 1, area = 10<br />

triangte 2, area = 18<br />

triangle 3, area = z s<br />

V = 4^ ts a re a = 3 4 5<br />

Посл<strong>е</strong> этой строки<br />

вы получа<strong>е</strong>т<strong>е</strong> массив<br />

из ч<strong>е</strong>тыр<strong>е</strong>х ссылок<br />

Triangle, но пока н<strong>е</strong>т<br />

ни оЭного оЗь<strong>е</strong>кта___<br />

Triangle!<br />

OK<br />

М<strong>е</strong>тод setAreaQ использу<strong>е</strong>т<br />

поля height и length для<br />

вычисл<strong>е</strong>ния знач<strong>е</strong>ния поля<br />

area. Так как м<strong>е</strong>тод н<strong>е</strong><br />

явля<strong>е</strong>тся статич<strong>е</strong>ским, он<br />

мож<strong>е</strong>т вызываться только<br />

для экз<strong>е</strong>мпляра Triangle.<br />

r<br />

c l a s s T r ia n g le<br />

{<br />

}<br />

d o u b le a r e a ;<br />

i n t h e i g h t ;<br />

i n t le n g t h ;<br />

Вы зам<strong>е</strong>тили, что класс<br />

им<strong>е</strong><strong>е</strong>м мочку входа и при<br />

этом созда<strong>е</strong>м экз<strong>е</strong>мпляр<br />

с<strong>е</strong>бя? В С* тако<strong>е</strong> вполн<strong>е</strong><br />

допусмимо.<br />

p u b l i c s t a t i c v o id M a i n ( s t r i n g [] a r g s)<br />

{<br />

s t r i n g r e s u l t s =<br />

i n t X = O;<br />

Triangle[] ta = new Triangle[4];<br />

w h ile ( X < 4 )<br />

{<br />

ta[x] = new TriangleQ)<br />

tafxl -height = (x + 1) * 2;<br />

tafxl . len g th = x + 4;<br />

ta[x].setAreaQ;_____<br />

r e s u l t s += " t r ia n g l e " + x +<br />

r e s u l t s +=<br />

X = X + 1;<br />

}<br />

i n t у ~ x;<br />

X = 27;<br />

T r ia n g le t 5 = t a [ 2 ] ;<br />

t a [2] .a r e a = 343;<br />

r e s u l t s += "y = " + y;<br />

M e s s a g e B o x .S h o w (r e s u lts +<br />

Цикл while<br />

созда<strong>е</strong>т ч<strong>е</strong>тыр<strong>е</strong><br />

экз<strong>е</strong>мпляра<br />

Triangle, ч<strong>е</strong>тыр<strong>е</strong><br />

раза вызывая<br />

оп<strong>е</strong>ратор new.<br />

area"<br />

= " + tafxl .area + "\n" ;<br />

", t 5 a r e a = " + t S . a r e a ) ;<br />

}<br />

v o i d s e tA r e a O<br />

{<br />

area = ( h e ig h t * le n g t h ) / 2;<br />

194 глава 4


5 инкапсуляция<br />

Пусть лично<strong>е</strong> оста<strong>е</strong>тся...<br />

личным<br />

Вы когда-нибудь м<strong>е</strong>чтали о том, чтобы вашу личную жизнь<br />

оставили в поко<strong>е</strong>? Иногда объ<strong>е</strong>кты чувствуют то ж<strong>е</strong> само<strong>е</strong>. Вы ж<strong>е</strong> н<strong>е</strong><br />

хотит<strong>е</strong>, чтобы посторонни<strong>е</strong> люди читали ваши записки или рассматривали<br />

банковски<strong>е</strong> выписки. Вот и объ<strong>е</strong>кты н<strong>е</strong> хотят, чтобы други<strong>е</strong> объ<strong>е</strong>кты<br />

им<strong>е</strong>ли доступ к их полям, в этой глав<strong>е</strong> мы поговорим об инкапсуляции.<br />

Вы научит<strong>е</strong>сь закрывать объ<strong>е</strong>кты и добавлять м<strong>е</strong>тоды защищающи<strong>е</strong><br />

данны<strong>е</strong> от доступа.


помогит<strong>е</strong> кэтлин<br />

Кэтлин проф<strong>е</strong>ссиональный массобик-зат<strong>е</strong>йник<br />

Она организу<strong>е</strong>т в<strong>е</strong>ликол<strong>е</strong>пны<strong>е</strong> званы<strong>е</strong> ужины.<br />

Но для н<strong>е</strong><strong>е</strong> настали тяж<strong>е</strong>лы<strong>е</strong> вр<strong>е</strong>м<strong>е</strong>на, так как<br />

по мн<strong>е</strong>нию кли<strong>е</strong>нтов Кэтлин н<strong>е</strong>достаточно<br />

стро называ<strong>е</strong>т стоимость услуг.<br />

5юЭж<strong>е</strong>т.<br />

Посл<strong>е</strong> получ<strong>е</strong>ния от нового кли<strong>е</strong>нта информации о колич<strong>е</strong>ств<strong>е</strong> участников,<br />

ж<strong>е</strong>ла<strong>е</strong>мых напитках и оформл<strong>е</strong>нии она с помощью сп<strong>е</strong>циальной<br />

диаграммы выполня<strong>е</strong>т довольно сложны<strong>е</strong> вычисл<strong>е</strong>ния, чтобы опр<strong>е</strong>д<strong>е</strong>лить<br />

кон<strong>е</strong>чную стоимость, к сожал<strong>е</strong>нию, это м<strong>е</strong>дл<strong>е</strong>нный проц<strong>е</strong>сс,<br />

и пока Кэтлин счита<strong>е</strong>т, кли<strong>е</strong>нты звонят <strong>е</strong><strong>е</strong> конкур<strong>е</strong>нтам.<br />

Вы мож<strong>е</strong>т<strong>е</strong> написать программу, автоматизирующую расч<strong>е</strong>ты, и спасти<br />

бизн<strong>е</strong>с Кэтлин. Только пр<strong>е</strong>дставьт<strong>е</strong>, какой об<strong>е</strong>д она устроит вам в кач<strong>е</strong>ств<strong>е</strong><br />

благодарности!<br />

196 глава 5


инкапсуляция<br />

Как происходит оц<strong>е</strong>нка<br />

Вот фрагм<strong>е</strong>нт запис<strong>е</strong>й Кэтлин, касающийся расч<strong>е</strong>тов<br />

стоимости м<strong>е</strong>роприятия:<br />

О и<strong>е</strong>нка стоимости об<strong>е</strong>да<br />

За каждого гостя — $25.<br />

Большинство об<strong>е</strong>дов с<strong>е</strong>рвиру<strong>е</strong>тся с алкогольными напитками — это<br />

дополнит<strong>е</strong>льны<strong>е</strong> $20 на ч<strong>е</strong>лов<strong>е</strong>ка. Можно выбрать «здоровый» вариант<br />

- это стоит вс<strong>е</strong>го $5 на ч<strong>е</strong>лов<strong>е</strong>ка, вм<strong>е</strong>сто алкоголя подаются<br />

соки и газировка. «Здоровый» вариант намного прош<strong>е</strong> в организации,<br />

поэтому скидка составит 5% на всю стоимость м<strong>е</strong>роприятия.<br />

. Обычно<strong>е</strong> оформл<strong>е</strong>ни<strong>е</strong> стоит $7.50 на ч<strong>е</strong>лов<strong>е</strong>ка плюс п<strong>е</strong>рвоначальный<br />

взнос $30. Стоимость особого оформл<strong>е</strong>ния ув<strong>е</strong>личива<strong>е</strong>тся до<br />

$15 на ч<strong>е</strong>лов<strong>е</strong>ка, а п<strong>е</strong>рвоначальный взнос составит $50.<br />

Для наглядности пр<strong>е</strong>дставим эти правила в вид<strong>е</strong><br />

диаграммы:<br />

В н<strong>е</strong>которых случаях<br />

м<strong>е</strong>ня<strong>е</strong>тся н<strong>е</strong> только<br />

стоимость на одного<br />

гостя, но и общая ц<strong>е</strong>на<br />

м<strong>е</strong>роприятия.<br />

Колич<strong>е</strong>ство<br />

гост<strong>е</strong>й<br />

Еда ($2Ь<br />

на ч<strong>е</strong>лов<strong>е</strong>ка)<br />

ч «Здоровы й»<br />

вариант?<br />

Н<strong>е</strong>т<br />

$5<br />

на ч<strong>е</strong>лов<strong>е</strong>ка-«^<br />

5% скидки<br />

с общ<strong>е</strong>й<br />

суммы<br />

чштшшлштт<br />

$20 с ч<strong>е</strong>лов<strong>е</strong>ка<br />

О собо<strong>е</strong><br />

оф ормл<strong>е</strong>ни<strong>е</strong>?<br />

ч<br />

$15 на ч<strong>е</strong>лов<strong>е</strong>ка<br />

+ВЗНОС<br />

$50<br />

$7.50 на ^<br />

ч<strong>е</strong>лов<strong>е</strong>ка 1<br />

+взнос$30 1<br />

г<br />

Выбор этого варианта<br />

н<strong>е</strong> только влия<strong>е</strong>т на ст о­<br />

имость за одного ч<strong>е</strong>лов<strong>е</strong>ка,<br />

но и включа<strong>е</strong>т <strong>е</strong>диновр<strong>е</strong>м<strong>е</strong>нный<br />

взнос.<br />

дальш<strong>е</strong> > 197


ok, н<strong>е</strong>т пробл<strong>е</strong>м<br />

н<strong>е</strong>ни<strong>е</strong><br />

Dinnerparty<br />

NumberOfPeople<br />

CostOfBeveragesPerPerson<br />

CostOfDecorations<br />

SetHealthyOptionO<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

Создадим программу, оц<strong>е</strong>нивающую стоимость об<strong>е</strong>дов.<br />

@<br />

Создайт<strong>е</strong> про<strong>е</strong>кт Windows Application, добавьт<strong>е</strong> класс D in n e rP arty .cs<br />

и оформит<strong>е</strong> <strong>е</strong>го в соотв<strong>е</strong>тствии с показанной сл<strong>е</strong>ва диаграммой. М<strong>е</strong>тоды<br />

затрачивают расч<strong>е</strong>ты стоимости «здорового» варианта, стоимости<br />

оформл<strong>е</strong>ния, а такж<strong>е</strong> общ<strong>е</strong>й стоимости м<strong>е</strong>роприятия. Два<br />

посл<strong>е</strong>дних поля должны принадл<strong>е</strong>жать типу d ecim al, а п<strong>е</strong>рво<strong>е</strong> —<br />

типу i n t. Уб<strong>е</strong>дит<strong>е</strong>сь, что в конц<strong>е</strong> каждой константы типа d ecim al<br />

стоит б уквам (наприм<strong>е</strong>р, 10 . ОМ).<br />

Так как стоимость <strong>е</strong>ды на одного ч<strong>е</strong>лов<strong>е</strong>ка н<strong>е</strong> буд<strong>е</strong>т м<strong>е</strong>няться, <strong>е</strong><strong>е</strong><br />

можно объявить как консгттту. Вот как это д<strong>е</strong>ла<strong>е</strong>тся:<br />

p u b l i c c o n s t i n t C o stO fF o o d P erP erso n = 25;<br />

e Один из м<strong>е</strong>тодов возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> типа d ecim al, два других<br />

—н<strong>е</strong>т. М<strong>е</strong>тод C a lc u la te C o stO fD e c o ra tio n s O вычисля<strong>е</strong>т<br />

стоимость оформл<strong>е</strong>ния в зависимости от колич<strong>е</strong>ства приглаш<strong>е</strong>нных.<br />

М<strong>е</strong>тод C a lc u la te C o s t () вычисля<strong>е</strong>т общую стоимость,<br />

складывая ц<strong>е</strong>ну оформл<strong>е</strong>ниы, <strong>е</strong>ды и напитков в зависимости от<br />

колич<strong>е</strong>ства приглащ<strong>е</strong>нных. При выбор<strong>е</strong> здорового варианта д<strong>е</strong>ла<strong>е</strong>тся<br />

скидка с общ<strong>е</strong>й стоимости.<br />

Рям<strong>е</strong>тр<br />

обновл<strong>е</strong>ния SHauff<br />

Код using System.<br />

VJindows.forms: для<br />

класса Dinnerparty<br />

н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся, так<br />

как вы н<strong>е</strong> собира<strong>е</strong>т<strong>е</strong>сь<br />

(^спользовать м <strong>е</strong>т о­<br />

ды из пространства<br />

им<strong>е</strong>н .NET Framework.<br />

198 глава 5<br />

О<br />

Добавьт<strong>е</strong> к форм<strong>е</strong> код:<br />

Вы объявля<strong>е</strong>т<strong>е</strong> пол<strong>е</strong><br />

Dinnerparty dinnerparty;<br />

dinnerparty и добавля<strong>е</strong>т<strong>е</strong><br />

p u b l i c F o r m lО {<br />

ч<strong>е</strong>тыр<strong>е</strong> строчки.<br />

I n it i a l iz e C o m p o n e n t O ;<br />

dinnerparty = new DinnerParty() { NumberOfPeople = 5 };<br />

dinnerparty.SetHealthyOption(false);<br />

dinnerparty.CalculateCostOfDecorations(true);<br />

DisplayDinnerPartyCost0;<br />

><br />

Форма должна выгля- ^<br />

д<strong>е</strong>ть так. Используйт<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нт NumericUpDown, ццсА®<br />

чтобы задать максимально<strong>е</strong><br />

колич<strong>е</strong>ство люд<strong>е</strong>й ~~~<br />

равным 20, а минимально<strong>е</strong><br />

— 1. По умолчанию Свойство<br />

колич<strong>е</strong>ство приглаш<strong>е</strong>н- ^l^ccked<br />

ных равно 5. Избавьт<strong>е</strong>сь t t Z a t i o n ^ ^<br />

от кнопок управл<strong>е</strong>ния должно им<strong>е</strong>ть<br />

разм<strong>е</strong>рами окна. знач<strong>е</strong>ни<strong>е</strong> True.<br />

Party Planner<br />

Number rf People<br />

^<br />

i t<br />

[V] Fancy Oeceathms<br />

Ej HeÄyOf*«!<br />

Cost i<br />

Имя этой м<strong>е</strong>тки labelCost. Свойство Text оставл<strong>е</strong>но<br />

пустым, свойство BorderStyle им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>--------<br />

FixedsD, а свойство AutoSize знач<strong>е</strong>ни<strong>е</strong> false.


инкапсуляция<br />

О<br />

Этот hAtmob вызыва<strong>е</strong>мся<br />

вс<strong>е</strong>ми м <strong>е</strong>-<br />

тоЗаМи, связанными<br />

с формой, им<strong>е</strong>нно<br />

т а к обновля<strong>е</strong>тся<br />

Сд<strong>е</strong>ла<strong>е</strong>м так, чтобы итоговая сумма автоматич<strong>е</strong>ски м<strong>е</strong>нялась при изм<strong>е</strong>н<strong>е</strong>нии<br />

флажков и показаний сч<strong>е</strong>тчика Ыит<strong>е</strong>г1сирВо1А?п. Для этого вам потр<strong>е</strong>бу<strong>е</strong>тся м<strong>е</strong>тод,<br />

отображающий сумму.<br />

Добавим <strong>е</strong>го к Forml ( ).<br />

NumericUpDown:<br />

зн а ч <strong>е</strong> н и <strong>е</strong> м <strong>е</strong> т к и Cost. d e c im a l C o st =<br />

c o s t L a b e l . T ext<br />

При двойном<br />

щ<strong>е</strong>лчк<strong>е</strong> на<br />

кнопк<strong>е</strong> ИСР<br />

добавля<strong>е</strong>т обработчик<br />

события<br />

Click.<br />

О<br />

p r i v a t e v o i d D is p la y D in n e r P a r t y C o s t ()<br />

{<br />

Присвойт<strong>е</strong> м<strong>е</strong>тк<strong>е</strong>,<br />

отображающ<strong>е</strong>й<br />

ц<strong>е</strong>ну, имя costLabel.<br />

O h буд<strong>е</strong>т вызываться п р и щ <strong>е</strong>лчк<strong>е</strong> на эл<strong>е</strong>м <strong>е</strong>н т<strong>е</strong><br />

М<strong>е</strong>тод рассчитыва<strong>е</strong>т ст о-<br />

" р <strong>е</strong> з у л ь т а т м <strong>е</strong>тк<strong>е</strong> Cost.<br />

d in n e r p a r t y .C a lc u la t e C o s t ( c h e c k B o x 2 . Checked)<br />

= C o s t .T o S t r in g ( " c " ) ;<br />

Аргум<strong>е</strong>нт "с” м<strong>е</strong>тода<br />

ToStringO отобража<strong>е</strong>т в а л ю<br />

с использовани<strong>е</strong>м принятого<br />

по соглаш<strong>е</strong>нию символа.<br />

t<br />

Знач<strong>е</strong>ни<strong>е</strong> true появля-<br />

Healthy Option,<br />

Со<strong>е</strong>диним пол<strong>е</strong> NumericUpDown с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной Num berOfPeople, принадл<strong>е</strong>жащ<strong>е</strong>й<br />

классу D in n e rp a rty , чтобы в форм<strong>е</strong> начала отображаться сумма<br />

расходов. Дважды щ<strong>е</strong>лкнит<strong>е</strong> на эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong> NumericUpDown, в код буд<strong>е</strong>т добавл<strong>е</strong>н<br />

обработчик событий (event handler). Так называ<strong>е</strong>тся м<strong>е</strong>тод, запуска<strong>е</strong>мый<br />

при каждом изм<strong>е</strong>н<strong>е</strong>нии эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния. Он сбросит колич<strong>е</strong>ство<br />

гост<strong>е</strong>й. Впишит<strong>е</strong> сл<strong>е</strong>дующий код:<br />

p r i v a t e<br />

{<br />

v o id<br />

nu m ericU pD ow nl_V alueC hanged(<br />

o b j e c t se n d e r , E ven tA rgs e)<br />

d in n e rp a rty .N u m b er O fP e o p le (i n t ) num ericU pD ow nl. V a lu e ;<br />

^ D is p la y D in n e r P a r t y C o s t ( );<br />

J<br />

C_ Знач<strong>е</strong>ни<strong>е</strong> numericUpPown-Value<br />

принадл<strong>е</strong>жит типу Decimal,<br />

поэтому тр<strong>е</strong>бу<strong>е</strong>тся оп<strong>е</strong>рация<br />

прив<strong>е</strong>д<strong>е</strong>ния типов.<br />

Ой... код сод<strong>е</strong>ржит ошибку. Вы <strong>е</strong><strong>е</strong> видит<strong>е</strong>? Если н<strong>е</strong>т, н<strong>е</strong> волнуйт<strong>е</strong>сь. Скоро мы<br />

вс<strong>е</strong> объясним!<br />

Из формы м<strong>е</strong>тоду<br />

П<strong>е</strong>рвый м<strong>е</strong>тод рассчит^.,а<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся ло -<br />

^ ^ ^ ‘^Мость<br />

гич<strong>е</strong>ско<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> \ второй<br />

fancyBox.Checked.<br />

кон<strong>е</strong>чную сумму в форм<strong>е</strong>.<br />

Дважды щ <strong>е</strong>лкнит<strong>е</strong> на флажк<strong>е</strong>(РапсуВ<strong>е</strong>сога11оп5’у уб<strong>е</strong>дит<strong>е</strong>сь, что<br />

сначала он вызыва<strong>е</strong>т м<strong>е</strong>тод C alcuiacscC igiC C fD ecSrations (), а потом<br />

м<strong>е</strong>тод D lspla^diiB i^erPartyC G St (). Зат<strong>е</strong>м дважды щ<strong>е</strong>лкнит<strong>е</strong><br />

на флажк<strong>е</strong> ^Healthy Option? и уб<strong>е</strong>дит<strong>е</strong>сь, что он сначала вызыва<strong>е</strong>т<br />

м<strong>е</strong>тод S e tH e a lth y O p tio ^ ) класса D in n e rP a rty , а зат<strong>е</strong>м м<strong>е</strong>тод<br />

D isp la y D in n e rP a rty C o st ( ) /<br />

дальш<strong>е</strong> > 199


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

т н ш<br />

c l a s s D in n e r P a r ty {<br />

В о т так ой код д о л ж <strong>е</strong> н сод<strong>е</strong>р ж аться в ф а й л <strong>е</strong> D i n n e r P a r t y . c s .<br />

c o n s t i n t C o stO fF o o d P erP erso n = 25;<br />

p u b l i c i n t N um berO fPeople;<br />

p u b l i c d e c im a l C o stO fB e v e r a g e sP e r P e r so n ;<br />

p u b l i c d e c im a l C o s tO fD e c o r a tio n s = 0;<br />

И с п о л ь з о в а н и <strong>е</strong> к о н с т а н т , г а р а н т и р у ­<br />

<strong>е</strong> м , ч т о д а н н ы <strong>е</strong> п а р а м <strong>е</strong> т р ы о с т а н у т ­<br />

ся н <strong>е</strong> и з м <strong>е</strong> н н ы м и н а п р о т я ж <strong>е</strong> н и и в с <strong>е</strong> й<br />

п р о г р а м м ы .<br />

p u b l i c v o i d S e t H e a lt h y O p t io n ( b o o l h e a lth y O p tio n )<br />

i f (h e a lth y O p tio n ) {<br />

} e l s e {<br />

C o stO fB e v e r a g e sP e r P e r so n = 5.00M ;<br />

{<br />

Создав объ<strong>е</strong>кт, форма использу<strong>е</strong>т<br />

инициализатор<br />

для указания парам<strong>е</strong>тра<br />

NumberOfPeople. Зат<strong>е</strong>м м <strong>е</strong> ­<br />

тоды SetHealthyOptionO<br />

и CalculateCostOfDecorationsO<br />

задают знач<strong>е</strong>ния других пол<strong>е</strong>й.<br />

}<br />

}<br />

C o stO fB e v e r a g e sP e r P e r so n = 20.00M ;<br />

Оп<strong>е</strong>ратор if в с <strong>е</strong> г д а п р о в <strong>е</strong> р я <strong>е</strong> т , CO<br />

5 л ю д а <strong>е</strong> т с я л и у с л о в и <strong>е</strong> , п о э т о м у<br />

д о с т а т о ч н о н а п и с а т ь " if (F a n c y )”<br />

в м <strong>е</strong> с т о " if (F a n c y = - t r u e ) ”.<br />

p u b l i c v o i d C a lc u la t e C o s t O fD e c o r a tio n s ( b o o l fa n c y )<br />

i f (fa n c y )<br />

{<br />

}<br />

}<br />

C o s tO fD e c o r a tio n s = (N um berO fPeople * 15.00M ) + SOM;<br />

} e l s e {<br />

C o s tO fD e c o r a tio n s = (N um berO fPeople * 7.50M ) + 30M;<br />

p u b l i c d e c im a l C a lc u la t e C o s t ( b o o l h e a lth y O p tio n )<br />

d e c im a l t o t a l C o s t = C o s tO fD e c o r a tio n s +<br />

( (C o stO fB e v e r a g e sP e r P e r so n + C o stO fF ood P erP erson )<br />

{<br />

{<br />

Num berO fPeople)<br />

i f (h e a lth y O p tio n ) {<br />

r e t u r n t o t a l C o s t .95М;<br />

} e l s e {<br />

^ М ы и с п о л ь з о в а л и с к о б к и , ч т о б ы г а -<br />

р а н т и р о в а т ь п р а в и л ь н о с т ь м а т <strong>е</strong> ­<br />

м а т и ч <strong>е</strong> с к и х вы ч и с л <strong>е</strong>н и й .<br />

r e t u r n t o t a l C o s t ;<br />

}<br />

S % - я с к и д к а п р и у с л о в и и ,<br />

ч т о о б <strong>е</strong> д п о д а <strong>е</strong> т с я б <strong>е</strong> з а л -<br />

к о го л я .<br />

200 глава 5


инкапсуляция<br />

Для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных, сод<strong>е</strong>ржащих ц<strong>е</strong>ны, выбира<strong>е</strong>тся тип decim al. Вс<strong>е</strong>гда пом<strong>е</strong>щайт<strong>е</strong> букву М<br />

посл<strong>е</strong> цифры: чтобы присвоить п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной знач<strong>е</strong>ни<strong>е</strong> $35.26, нужно написать 35.2 6М. Это<br />

л<strong>е</strong>гко запомнить, потому что М — п<strong>е</strong>рвая буква в слов<strong>е</strong> money (д<strong>е</strong>ньги)!<br />

p u b l i c p a r t i a l c l a s s Form l : Form { DisplayDinnerPartyCost п<strong>е</strong>р<strong>е</strong>-<br />

/-■ Оа<strong>е</strong>пл. оанны<strong>е</strong> м<strong>е</strong>т.к<strong>е</strong>, которая от о-<br />

D in n e r P a r ty d in n e r p a r t y ; / бража<strong>е</strong>т сумму расходов сразу посл<strong>е</strong><br />

p u b l i c F orm iO { / загрузки формы.<br />

I n it ia liz e C o m p o n e n t O ;<br />

d in n e r p a r t y = new D in n e r P a r t y () { N um berO fPeople = 5 };<br />

d in n e r p a r t y .C a lc u la t e C o s t O f D e c o r a t io n s (f a n c y B o x .C h e c k e d ) ;<br />

d i n n e r p a r t y . S e t H e a lt h y O p t io n ( h e a lt h y B o x .C h e c k e d ) ;<br />

D is p la y D in n e r P a r ty C o s t 0 ;<br />

флажки м<strong>е</strong>няьот знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>н-<br />

} healthyOption и Fancy с true на<br />

false и обратно.<br />

p r i v a t e v o i d fa n c y B o x _ C h ec k e d C h a n g e d (o b jec t s e n d e r , E v en tA rg s e) {<br />

d in n e r p a r t y .C a lc u la t e C o s t O f D e c o r a t io n s (f a n c y B o x .C h e c k e d ) ;<br />

D is p la y D in n e r P a r t y C o s t 0 ;<br />

Мы присвоили флажкам им<strong>е</strong>на healthyBox<br />

и fo.t\cyЗoxJ Ч1/\лоды вш мо2ли<br />

чидо 1^роис~<br />

ходит в их м<strong>е</strong>тодах обработчиков событий.<br />

p r i v a t e v o i d h e a lth y B o x _ C h e c k e d C h a n g e d (o b je c t s e n d e r , E v en tA rg s e) {<br />

}<br />

d i n n e r p a r t y . S e t H e a lt h y O p t io n ( h e a lt h y B o x . C h e c k e d );<br />

D is p la y D in n e r P a r t y C o s t ( ) ;<br />

p r i v a t e v o i d n u m ericU p D o w n l_ V a lu eC h a n g ed (o b ject se n d e r , E v en tA rg s e) {<br />

d in n e rp a rty .N u m b er O fP e o p le = (in t)n u m er icU p D o w n l.V a lu e;<br />

D is p la y D in n e r P a r ty C o s t 0 ; ^ --------СуМма должна tv'V"/»/-I"»* п<strong>е</strong>р<strong>е</strong>считываться<br />

---- -<br />

и отображаться при каждом изм<strong>е</strong>-<br />

' ^ л ■ • л 1. (УЛ ЧА/ ЛЛ<br />

J у ^ н<strong>е</strong>нии колич<strong>е</strong>ства гост<strong>е</strong>й и каждой t~i<br />

V- установк<strong>е</strong> флажка.<br />

p r i v a t e v o i d D is p la y D in n e r P a r t y C o s t О {<br />

}<br />

d e c im a l C o st = d i n n e r P a r t y .C a lc u la t e C o s t ( h e a lt h y B o x .C h e c k e d ) ;<br />

c o s t L a b e l.T e x t = C o s t . T o S t r i n g ( "c");<br />

М<strong>е</strong>тод ToStringQ пр<strong>е</strong>образу<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> в строки. Аргум<strong>е</strong>нт при<br />

этом пр<strong>е</strong>образу<strong>е</strong>тся в локальную д<strong>е</strong>н<strong>е</strong>жную <strong>е</strong>диницу. Аргум<strong>е</strong>нт "ft5”<br />

форматиру<strong>е</strong>т р<strong>е</strong>зультат в вид<strong>е</strong> типа decimal с тр<strong>е</strong>мя знаками посл<strong>е</strong><br />

запятой^ (ноль) пр<strong>е</strong>враща<strong>е</strong>т р<strong>е</strong>зультат в ц<strong>е</strong>ло<strong>е</strong> число, "0%” — в ц<strong>е</strong>ло<strong>е</strong><br />

с проц<strong>е</strong>нтами, а "п” да<strong>е</strong>т число с запятой в кач<strong>е</strong>ств<strong>е</strong> разд<strong>е</strong>лит<strong>е</strong>ля<br />

групп разрядов. Вы сами мож<strong>е</strong>т<strong>е</strong> посмотр<strong>е</strong>ть, как это работа<strong>е</strong>т!<br />

дальш<strong>е</strong> > 201


что-то пошло н<strong>е</strong> так<br />

Кэтлин т <strong>е</strong> с т и р у <strong>е</strong> т программу<br />

Потрясающ<strong>е</strong>! Как<br />

быстро я т<strong>е</strong>п<strong>е</strong>рь могу<br />

назвать сумму!<br />

г, S из AhoSuMfIX кли<br />

лй К э т л и н . Она о р г а и ы з о -<br />

бйни<strong>е</strong> званого об<strong>е</strong>да.<br />

Роб (по т<strong>е</strong>л<strong>е</strong>фону): Прив<strong>е</strong>т, Кэтлин! Как там подготовка<br />

мо<strong>е</strong>й в<strong>е</strong>ч<strong>е</strong>ринки?<br />

Кэтлин: В<strong>е</strong>ликол<strong>е</strong>пно. Мы уж<strong>е</strong> заказали оформл<strong>е</strong>ни<strong>е</strong>.<br />

Т<strong>е</strong>б<strong>е</strong> должно понравиться.<br />

Роб: Фантастика! Послушай, мн<strong>е</strong> только что позвонила<br />

т<strong>е</strong>тя ж<strong>е</strong>ны. Она с муж<strong>е</strong>м собира<strong>е</strong>тся погостить<br />

у нас пару н<strong>е</strong>д<strong>е</strong>ль. Сколько буд<strong>е</strong>т стоит включ<strong>е</strong>ни<strong>е</strong><br />

в список гост<strong>е</strong>й <strong>е</strong>ш;<strong>е</strong> двух ч<strong>е</strong>лов<strong>е</strong>к?<br />

Кэтлин: Подожди минутку...<br />

флажок Fancy Decorations<br />

установл<strong>е</strong>н по умолча-<br />

HUhOj так как <strong>е</strong>го свойство<br />

Checked им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

true. Если колич<strong>е</strong>ство гост<strong>е</strong>й<br />

равно Ю , стоимость<br />

об<strong>е</strong>да составит $575.<br />

ш Party P lann er<br />

Number rf People<br />

12<br />

Fancy DecoraJtons<br />

H He^hyC^ton<br />

Изм<strong>е</strong>нив парам<strong>е</strong>тр<br />

Number of People с l o<br />

на IZ j в итог<strong>е</strong> получа<strong>е</strong>м<br />

$б&5. Сумма<br />

каж<strong>е</strong>тся <strong>е</strong>й слишком<br />

мал<strong>е</strong>нькой...<br />

Coat !№65:00<br />

Кэтлин: Каж<strong>е</strong>тся, общая стоимость об<strong>е</strong>да возраст<strong>е</strong>т<br />

с $575 до $665.<br />

Роб: Вс<strong>е</strong>го на $90? Соблазнит<strong>е</strong>льно! А какая ц<strong>е</strong>на<br />

получится, <strong>е</strong>сли убрать особо<strong>е</strong> оформл<strong>е</strong>ни<strong>е</strong>?<br />

202 глава 5


инкапсуляция<br />

'iff Party Planner<br />

Сняти<strong>е</strong> флажка<br />

Рапсу Decorations<br />

s r s a<br />

r<br />

^пакого н<strong>е</strong> мож<strong>е</strong>т!<br />

МшЛ<strong>е</strong>г«# Peofrfe<br />

Ратсу OecOTthjns<br />

Healthy Option<br />

Coat | ii«6b.00<br />

Кэтлин; Ээээ... получа<strong>е</strong>тся сумма в $660.<br />

Роб: $660? Я думал, оформл<strong>е</strong>ни<strong>е</strong> стоит $15 с ч<strong>е</strong>лов<strong>е</strong>ка. Вы что, пом<strong>е</strong>няли ц<strong>е</strong>ну?<br />

Если разница составит вс<strong>е</strong>го $5, оставим особый вариант. Хотя, долж<strong>е</strong>н зам<strong>е</strong>тить,<br />

что в твоих ц<strong>е</strong>нах я уж<strong>е</strong> запутался.<br />

Кэтлин: Я только что получила новую программу для оц<strong>е</strong>нки расходов. Но<br />

каж<strong>е</strong>тся, она гд<strong>е</strong>-то ошиба<strong>е</strong>тся. Подожди с<strong>е</strong>кунду, я попробую снова добавить<br />

к сч<strong>е</strong>ту особо<strong>е</strong> оформл<strong>е</strong>ни<strong>е</strong>.<br />

Itete-rfPes^jte<br />

12<br />

g ] Fancy DecotaHws<br />

H HeafchyOptiOTi<br />

н<strong>е</strong> Эол>кно!<br />

Кэтлин: Роб, произошла ошибка. С особым оформл<strong>е</strong>ни<strong>е</strong>м ц<strong>е</strong>на возраста<strong>е</strong>т до<br />

$770. Что-то я н<strong>е</strong> дов<strong>е</strong>ряю этому прилож<strong>е</strong>нию. В<strong>е</strong>рну-ка я <strong>е</strong>го на доработку и посчитаю<br />

вручную, как и раньш<strong>е</strong>. Я могу позвонить т<strong>е</strong>б<strong>е</strong> завтра?<br />

Роб: Я н<strong>е</strong> готов платить $770 за двух дополнит<strong>е</strong>льных гост<strong>е</strong>й. Сначала ты озвучила<br />

мн<strong>е</strong> намного бол<strong>е</strong><strong>е</strong> разумную ц<strong>е</strong>ну. Я дам $665 и ни ц<strong>е</strong>нтом больш<strong>е</strong>!<br />

ШТУРМ<br />

Как вы дума<strong>е</strong>т<strong>е</strong>, поч<strong>е</strong>му каждо<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> условий давало ошибку в р<strong>е</strong>зультат<strong>е</strong>?<br />

дальш<strong>е</strong> У 203


н<strong>е</strong>ожиданно оказалось, что...<br />

Ка)кдьш бариант ну)кно было с ч и тать<br />

отд<strong>е</strong>льно<br />

Подсч<strong>е</strong>т сумм в<strong>е</strong>лся строго по диаграмм<strong>е</strong> Кэтлин, но мы н<strong>е</strong> учли<br />

того, каким образом на общий сч<strong>е</strong>т влия<strong>е</strong>т изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> каждого<br />

парам<strong>е</strong>тра формы.<br />

При запуск<strong>е</strong> формы колич<strong>е</strong>ство гост<strong>е</strong>й по умолчанию равно<br />

5, кром<strong>е</strong> того, установл<strong>е</strong>н флажок Fancy Decorations. Флажок<br />

Healthy Option н<strong>е</strong> установл<strong>е</strong>н. При этих условиях стоимость м<strong>е</strong>роприятия<br />

равна $350. Вот как получа<strong>е</strong>тся эта сумма:<br />

АССЛ^?Т)ТК1)<br />

Это н<strong>е</strong> ваша вина!<br />

В код сп<strong>е</strong>циально была пом<strong>е</strong>щ<strong>е</strong>на<br />

ошибка, чтобы показать, каки<strong>е</strong><br />

пробл<strong>е</strong>мы возникают, когда<br />

объ<strong>е</strong>кты используют поля друг<br />

друга, и то, как сложно эти пробл<strong>е</strong>мы<br />

отсл<strong>е</strong>дить.<br />

5 ч<strong>е</strong>лов<strong>е</strong>к<br />

$20 с ч<strong>е</strong>лов<strong>е</strong>ка за напитки<br />

Стоимость напитков = $100<br />

«в Party Planner<br />

Nwnbe-of Peof^e<br />

$25 с ч<strong>е</strong>лов<strong>е</strong>ка за <strong>е</strong>ду - —<br />

$15 с ч<strong>е</strong>лов<strong>е</strong>ка за —-----------<br />

оф ормл<strong>е</strong>ни<strong>е</strong> и взнос $50<br />

Стоимость <strong>е</strong>ды = $125<br />

С тоимость оф ормл<strong>е</strong>ния = $125<br />

Farwy Oecwafior»<br />

He^qrOjjBon<br />

Cost<br />

a<br />

j<br />

^OKa вс<strong>е</strong><br />

‘^Р^вильно.<br />

$ 1 0 0 + $ 1 2 5 + 125 = $350<br />

При изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства гост<strong>е</strong>й прилож<strong>е</strong>ни<strong>е</strong> должно п<strong>е</strong>р<strong>е</strong>считывать<br />

сумму аналогичным образом. Но этого н<strong>е</strong> происходит:<br />

10 ч<strong>е</strong>лов<strong>е</strong>к<br />

$20 с ч<strong>е</strong>лов<strong>е</strong>ка за напитки<br />

$25 с ч<strong>е</strong>лов<strong>е</strong>ка за <strong>е</strong>ду — -<br />

$15 с ч<strong>е</strong>лов<strong>е</strong>ка за -------------<br />

оф ормл<strong>е</strong>ни<strong>е</strong> и взнос $50<br />

С тоимость напитков = $200<br />

- V Стоимость <strong>е</strong>ды = $250<br />

^ С тоимость оф орм л<strong>е</strong>ния = $200<br />

$200 + $250+ 200 = $650<br />

Щ Party Planner<br />

Р<strong>е</strong>с^<br />

Н Fmc^ О<strong>е</strong>ояйюпз<br />

В Н<strong>е</strong>Луйэ<strong>е</strong>оп<br />

Сол<br />

Снимит<strong>е</strong> флажок Fancy Decorations<br />

и пров<strong>е</strong>рьт<strong>е</strong> р<strong>е</strong>зультат.<br />

Пол<strong>е</strong> C o s t O f D e c o r a t i o n s объ<strong>е</strong>кта<br />

D i n n e r P a r t y обновится, и вы получит<strong>е</strong><br />

правильную сумму $650.<br />

204 глава 5<br />

'^^^лунит.ь.<br />

Программа складыва<strong>е</strong>т<br />

старцю и<strong>е</strong>нц оформл<strong>е</strong>ния<br />

с новьши ц<strong>е</strong>нами <strong>е</strong>ды<br />

и напитков.<br />

+ ^3-2.5= $575.<br />

t У ' ^<br />

Н<strong>е</strong>на <strong>е</strong>ды С тарая ц<strong>е</strong>на<br />

^»1^итков. оформл<strong>е</strong>ния.


инкапсуляция<br />

П р о б л <strong>е</strong> м а ЦоД уВ<strong>е</strong>ЛиЧшп<strong>е</strong>ЛьНьїМ с т <strong>е</strong> И Іо М<br />

Рассмотрим м<strong>е</strong>тод, обрабатывающий изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> состояния эл<strong>е</strong>м<strong>е</strong>нта<br />

n u m ericU p D o w n . Он б<strong>е</strong>р<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной N u m b e r o f P e o p l e и вызыва<strong>е</strong>т<br />

м<strong>е</strong>тод D i s p l a y D i n n e r P a r t y C o s t О . Им<strong>е</strong>нно зд<strong>е</strong>сь осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

п<strong>е</strong>р<strong>е</strong>сч<strong>е</strong>т кон<strong>е</strong>чной суммы.<br />

p r i v a t e v o i d n u m e r ic U p D o w n l_ V a lu e C h a n g e d<br />

o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

d i n n e r P a r t y . N u m b e r o f P e o p l e = ( i n t ) n u m e r i c U p D o w n l .V a l u e ;<br />

D i s p l a y D i n n e r P a r t y C o s t ( ) ;<br />

1 Аанный m m o d вызыва<strong>е</strong>т м<strong>е</strong>тод<br />

'<br />

CalculateCostO, но забыва<strong>е</strong>т вызвать<br />

м<strong>е</strong>тод CalculateCostofPecorationsO-<br />

Эта строка<br />

зада<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

парам<strong>е</strong>тра<br />

l^umЬerofPeopie■<br />

Эля экз<strong>е</strong>мпляра<br />

ріппсграгіу на<br />

основ<strong>е</strong> вв<strong>е</strong>д<strong>е</strong>нных<br />

в форму данных.<br />

То <strong>е</strong>сть при изм<strong>е</strong>н<strong>е</strong>нии знач<strong>е</strong>ния в пол<strong>е</strong> N u m b e r o f P e o p l e<br />

показанный ниж<strong>е</strong> м<strong>е</strong>тод никогда н<strong>е</strong> вызыва<strong>е</strong>тся:<br />

p u b l i c v o i d C a lc u la t e C o s t O fD e c o r a tio n s ( b o o l Fancy) {<br />

i f (Fancy) {<br />

Эта п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная сохраня<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> получ<strong>е</strong>нно<strong>е</strong><br />

при п<strong>е</strong>рвом вызов<strong>е</strong> формы.<br />

C o s tO fD e c o r a tio n s = (Num berO fPeople * 15.00М ) + 50М;<br />

} e l s e {<br />

C o s tO fD e c o r a tio n s<br />

= (N um berO fPeople * 7 . SOM) + 30M;<br />

}<br />

Повторная установка флажка Fancy<br />

Pecorations снова запуска<strong>е</strong>т м<strong>е</strong>тод<br />

CalculateCostOf PecorationsQ, что<br />

приводит к корр<strong>е</strong>кции данных.<br />

Пр<strong>е</strong>дполагалось, что вс<strong>е</strong><br />

три варианта будут выбираться<br />

одновр<strong>е</strong>м<strong>е</strong>нно!<br />

К сожал<strong>е</strong>нию, пользоват<strong>е</strong>ли н<strong>е</strong> вс<strong>е</strong>гда используют<br />

классы так, как пр<strong>е</strong>дполагал разработчик.<br />

К счастью, в <strong>C#</strong> <strong>е</strong>сть функция, позволяющая гарантировать<br />

корр<strong>е</strong>ктную работу программы, даж<strong>е</strong><br />

когда пользоват<strong>е</strong>ль д<strong>е</strong>ла<strong>е</strong>т в<strong>е</strong>щи, о которых вы и<br />

пр<strong>е</strong>дположить н<strong>е</strong> могли. Она называ<strong>е</strong>тся инкапсуляци<strong>е</strong>й<br />

(encapsulation).<br />

...иногда этими<br />

«пользова т<strong>е</strong>ля -<br />

м и» явля<strong>е</strong>т<strong>е</strong>сь<br />

вы сами!<br />

дальш<strong>е</strong> ► 205


защити свои объ<strong>е</strong>кты<br />

Н<strong>е</strong>правильно<strong>е</strong> использовани<strong>е</strong> объ<strong>е</strong>ктов<br />

Программа н<strong>е</strong> прин<strong>е</strong>сла Кэтлин пользы, так как форма, проигнорировав м<strong>е</strong>тод<br />

C a l c u l a t e C o s t O f D e c o r a t i o n s О , сразу п<strong>е</strong>р<strong>е</strong>шла к полям класса D i n n e r P a r t y .<br />

Этот класс написан б<strong>е</strong>з ошибок, но программа вс<strong>е</strong> равно работа<strong>е</strong>т н<strong>е</strong>корр<strong>е</strong>ктно.<br />

Как нужно было бы вызывать класс DinnerParty<br />

Класс D i n n e r P a r t y пр<strong>е</strong>доставля<strong>е</strong>т форм<strong>е</strong> пр<strong>е</strong>красный м<strong>е</strong>тод расч<strong>е</strong>та<br />

кон<strong>е</strong>чной стоимости оформл<strong>е</strong>ния. Достаточно указать колич<strong>е</strong>ство гост<strong>е</strong>й<br />

и вызвать м<strong>е</strong>тод C a l c u l a t e C o s t O f D e c o r a t i o n s (), посл<strong>е</strong> ч<strong>е</strong>го<br />

м<strong>е</strong>тод C a l c u l a t e C o s t {) покаж<strong>е</strong>т правильную сумму.<br />

N u m b e r O f P e o p l e = Ю ;<br />

CalculateCostOfDecorations(true)<br />

C a l c u l a t e C o s t O returns $650<br />

о этот класс на самом д<strong>е</strong>л<strong>е</strong> вызыва<strong>е</strong>тся<br />

Посл<strong>е</strong> указания колич<strong>е</strong>ства гост<strong>е</strong>й форма сразу вызыва<strong>е</strong>т м<strong>е</strong>тод<br />

C a l c u l a t e C o s t O , игнорируя расч<strong>е</strong>т стоимости оформл<strong>е</strong>ния. То<br />

<strong>е</strong>сть пропуска<strong>е</strong>тся ц<strong>е</strong>лый этап, и в итог<strong>е</strong> получа<strong>е</strong>тся н<strong>е</strong>в<strong>е</strong>рная сумма.<br />

N u m b e r O f P e o p l e - 10;<br />

C a lc u la te C o s tO возвращ;а<strong>е</strong>т$575<br />

М<strong>е</strong>тод CalculateCostO<br />

\ возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>,<br />

но Кэтлин н<strong>е</strong> мож<strong>е</strong>т<br />

знать, что р<strong>е</strong>зультат<br />

расч<strong>е</strong>тов н<strong>е</strong>корр<strong>е</strong>кт<strong>е</strong>н.<br />

206 глава 5


инкапсуляция<br />

инкапсуляция как управл<strong>е</strong>ни<strong>е</strong> доступом к данным<br />

Подобных пробл<strong>е</strong>м можно изб<strong>е</strong>жать: достаточно оставить один способ<br />

работы с классом. Для это в <strong>C#</strong> в объявл<strong>е</strong>нии п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных использу<strong>е</strong>тся<br />

ключ<strong>е</strong>во<strong>е</strong> слово p r iv a te . До этого мом<strong>е</strong>нта вы встр<strong>е</strong>чали только модификатор<br />

public. Поля объ<strong>е</strong>ктов, пом<strong>е</strong>ч<strong>е</strong>нны<strong>е</strong> этим модификатором,<br />

были доступны для чт<strong>е</strong>ния и р<strong>е</strong>дактирования любым другим объ<strong>е</strong>ктом.<br />

Модификатор private д<strong>е</strong>ла<strong>е</strong>т пол<strong>е</strong> доступным только изнутри объ<strong>е</strong>кта<br />

(или из другого объ<strong>е</strong>кта этого ж<strong>е</strong> класса).<br />

В С* поля по умолчанию<br />

считаются закрытыми<br />

поэтому модификатор<br />

private зачастую опц~<br />

ска<strong>е</strong>тся.<br />

Статич<strong>е</strong>ски<strong>е</strong> м<strong>е</strong>тоды им<strong>е</strong>ют<br />

доступ к закрытым полям вс<strong>е</strong>х<br />

к .« .» ,<br />

полю достаточ-<br />

Х "<br />

ключ<strong>е</strong>дым хлк>ч<strong>е</strong>вым словом private<br />

class DinnerParty {<br />

X при <strong>е</strong>го объявл<strong>е</strong>нии. В итог<strong>е</strong> доступ к полю<br />

^ экз<strong>е</strong>мпляра DinnerPartu<br />

p r i v a t e int numberOfPeople; ^ >


шпионско<strong>е</strong> противостояни<strong>е</strong><br />

Д о ступ к м<strong>е</strong>тодам и полям класса<br />

Доступ к ПОЛЯМ и м<strong>е</strong>тодам, пом<strong>е</strong>ч<strong>е</strong>нным словом public, им<strong>е</strong><strong>е</strong>т любой класс. Вся сод<strong>е</strong>ржащаяся в них<br />

информация подобна открытой книг<strong>е</strong>... вы уж<strong>е</strong> вид<strong>е</strong>ли, как подобны<strong>е</strong> в<strong>е</strong>щи могут стать причиной н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>мых<br />

р<strong>е</strong>зультатов. Инкапсуляция м<strong>е</strong>ня<strong>е</strong>т уров<strong>е</strong>нь доступа к данным. Рассмотрим на прим<strong>е</strong>р<strong>е</strong>,<br />

как это работа<strong>е</strong>т:<br />

Суп<strong>е</strong>ршпион Х<strong>е</strong>рб <strong>Дж</strong>онс стоит на страж<strong>е</strong> инт<strong>е</strong>р<strong>е</strong>сов, свободы<br />

и счастья, работая с<strong>е</strong>кр<strong>е</strong>тным аг<strong>е</strong>нтом в СССР. Его объ<strong>е</strong>кт<br />

с1аАд<strong>е</strong>пЪ (Аг<strong>е</strong>нт ЦРУ) явля<strong>е</strong>тся экз<strong>е</strong>мпляром класса<br />

З<strong>е</strong>сг<strong>е</strong>ЬАд<strong>е</strong>пЬ (С<strong>е</strong>кр<strong>е</strong>тный аг<strong>е</strong>нт).<br />

Р<strong>е</strong>ально<strong>е</strong> имя (R ea lN a m e): "Х<strong>е</strong>рб <strong>Дж</strong>онс"<br />

Пс<strong>е</strong>вдоним ( A l i a s ) : "Даш Мартин"<br />

Пароль (P a ssw o r d ): "ворона л <strong>е</strong> т а <strong>е</strong> т в полночь"<br />

SecretAgent<br />

Alias<br />

RealName<br />

Password<br />

AgentGreetingO<br />

©<br />

e<br />

У аг<strong>е</strong>нта <strong>Дж</strong>онса <strong>е</strong>сть план, как изб<strong>е</strong>жать аг<strong>е</strong>нтов КГБ. Он<br />

добавил м<strong>е</strong>тод A g e n tG re e tin g (), парам<strong>е</strong>тром которого явля<strong>е</strong>тся<br />

пароль. Н<strong>е</strong> получив правильного пароля, он называ<strong>е</strong>т<br />

только свой пс<strong>е</strong>вдоним —Даш Мартин.<br />

Каж<strong>е</strong>тся, что это вполн<strong>е</strong> над<strong>е</strong>жная защита, н<strong>е</strong> так ли? Если<br />

объ<strong>е</strong>кт, вызывающий м<strong>е</strong>тод, н<strong>е</strong> «зна<strong>е</strong>т» правильного пароля,<br />

он н<strong>е</strong> «узна<strong>е</strong>т» настоящ<strong>е</strong><strong>е</strong> имя аг<strong>е</strong>нта <strong>Дж</strong>онса.<br />

EnemyAgent<br />

Borscht<br />

Vodka<br />

ContactComradesO<br />

OverthrowCapitalistsO<br />

Объ<strong>е</strong>кт<br />

экз<strong>е</strong>мпляром<br />

Аг<strong>е</strong>нт К-Г5 использц<strong>е</strong>т<br />

V —__'"это<br />

^ кач<strong>е</strong>ств<strong>е</strong> прив<strong>е</strong>тст и<br />

yA^e^t. ^ н<strong>е</strong>в<strong>е</strong>рный парол<strong>е</strong>,.<br />

AАд<strong>е</strong>пьаг<strong>е</strong><strong>е</strong>ь1пд("джип aen tG :<br />

п р и п а р к о в а н с н а р у ж и " )<br />

"Д а ш М а р т и н "<br />

Поэтому он узна<strong>е</strong>т только пс<strong>е</strong>вдоним аг<strong>е</strong>нта ЦРУ.<br />

208 глава 5


НА С А М О М л и Д ЕД Е защищ<strong>е</strong>но пол<strong>е</strong> realName?<br />

инкапсуляция<br />

Итак, мы закончили на том, что н<strong>е</strong> знгш пароля, аг<strong>е</strong>нт КГБ н<strong>е</strong> смож<strong>е</strong>т<br />

узнать настоящ<strong>е</strong><strong>е</strong> имя аг<strong>е</strong>нта ЦРУ. Т<strong>е</strong>п<strong>е</strong>рь посмотрим на объявл<strong>е</strong>ни<strong>е</strong><br />

поля realName:<br />

Модификатор<br />

public означа<strong>е</strong>т,<br />

что п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

доступна для<br />

р<strong>е</strong>дактирования<br />

извн<strong>е</strong> класса.<br />

piiblic s t r i n g R e al Na me;<br />

А пол<strong>е</strong>-то осталось<br />

в общ<strong>е</strong>м доступ<strong>е</strong>...<br />

Так зач<strong>е</strong>м мн<strong>е</strong> тогда<br />

пароль? Я могу узнать<br />

имя и б<strong>е</strong>з н<strong>е</strong>го! s trin g<br />

name = ciaAgent.RealName;<br />

для npocMoiMpa.<br />

Для сохран<strong>е</strong>ния тайны аг<strong>е</strong>нту <strong>Дж</strong>онсу нужно использовать поля ^<br />

закры того доступа. Стоит объявить пол<strong>е</strong> realN am e с модификатором<br />

private, <strong>е</strong>динств<strong>е</strong>нным способом узнать информацию стан<strong>е</strong>т<br />

вызов м<strong>е</strong>тода им<strong>е</strong>ющих доступ к закрытым эл<strong>е</strong>м<strong>е</strong>там класса. И аг<strong>е</strong>нт<br />

КГБ остан<strong>е</strong>тся с носом!<br />

Зам<strong>е</strong>нив public<br />

ка private, вы<br />

скро<strong>е</strong>т<strong>е</strong> пол<strong>е</strong> от<br />

он<strong>е</strong>шн<strong>е</strong>го Мира.<br />

- ^ p r i v a t e s t r i n g re al Na me;<br />

объ<strong>е</strong>кт каЬАд<strong>е</strong>пЬ н<strong>е</strong><br />

мож<strong>е</strong>т «бид<strong>е</strong>ть» закрыты<strong>е</strong><br />

поля объ<strong>е</strong>к-<br />

принадл<strong>е</strong>жит другому<br />

классу.<br />

Модификатор private<br />

, гарантиру<strong>е</strong>т, что<br />

вн<strong>е</strong>шний код н<strong>е</strong> смож<strong>е</strong>т<br />

отр<strong>е</strong>дактировать<br />

знач<strong>е</strong>ния пол<strong>е</strong>й б<strong>е</strong>з<br />

ваш<strong>е</strong>го в<strong>е</strong>дома.<br />

ябля<strong>е</strong>тся пол<strong>е</strong>, о к<br />

хранится пароль.<br />

р<br />

дальш<strong>е</strong> > 209


сохранить с<strong>е</strong>кр<strong>е</strong>т<br />

Закры ты <strong>е</strong> поля и м<strong>е</strong>тоды доступны только изнутри класса<br />

Сущ<strong>е</strong>ству<strong>е</strong>т вс<strong>е</strong>го один способ доступа к информации, хранящ<strong>е</strong>йся в за- закрытых<br />

полях: использовани<strong>е</strong> пол<strong>е</strong>й и м<strong>е</strong>тодов общ<strong>е</strong>го доступа, воз­<br />

Т^Т'»Ч-.ТТ'КТУ‘ ГТ/~^ тг с т V • тл^^ттгчттт »-».г-» ________ __________ ___ ________<br />

вращающих знач<strong>е</strong>ни<strong>е</strong>. Но <strong>е</strong>сли аг<strong>е</strong>нтам КГБ и МИ5 тр<strong>е</strong>бу<strong>е</strong>тся м<strong>е</strong>тод<br />

A g e n tG re e tin g (), колл<strong>е</strong>ги из ЦРУ могут вид<strong>е</strong>ть вс<strong>е</strong> что угодно —любой<br />

класс им<strong>е</strong><strong>е</strong>т доступ к закрытым полям любого сво<strong>е</strong>го экз<strong>е</strong>мпляра.<br />

Объ<strong>е</strong>кт m isaqent<br />

‘принадл<strong>е</strong>жит<br />

классу BritishAqent<br />

поэтому он m L e<br />

н<strong>е</strong> им<strong>е</strong><strong>е</strong>т доступа<br />

'^^^_^'^Рытым полям<br />

объ<strong>е</strong>кта ciaAgent.<br />

f<br />

Их мож<strong>е</strong>т вид<strong>е</strong>ть<br />

только другой<br />

CiaAgent.<br />

"Х<strong>е</strong>рб <strong>Дж</strong>онс<br />

Посл<strong>е</strong> закрытия<br />

дост ум к полям это<br />

<strong>е</strong>динств<strong>е</strong>нный способ<br />

для m iSAgent узнать<br />

настоящ<strong>е</strong><strong>е</strong> имя<br />

объ<strong>е</strong>кта ciaAgent.<br />

_ Чаапо<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Б о Г ^ о с ы<br />

Что произойд<strong>е</strong>т, <strong>е</strong>спи класс с закрытыми полями<br />

н<strong>е</strong> даст мн<strong>е</strong> доступа к данным, в то вр<strong>е</strong>мя<br />

как мн<strong>е</strong> это нужно?<br />

^ ! В этом случа<strong>е</strong> вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong> получить доступ<br />

извн<strong>е</strong>. При конструировании классов нужно гарантировать<br />

доступ для других объ<strong>е</strong>ктов. Закрыты<strong>е</strong> поля<br />

являются важной частью инкапсуляции, но нужно<br />

оставлять удобный способ доступа к данным на случай,<br />

<strong>е</strong>сли вдруг возникн<strong>е</strong>т такая н<strong>е</strong>обходимость.<br />

из н<strong>е</strong>скольких дюжин чис<strong>е</strong>л, которы<strong>е</strong> гарантируют,<br />

что м<strong>е</strong>тод Next () вс<strong>е</strong>гда даст на выход<strong>е</strong> случайно<strong>е</strong><br />

число. Создав новый экз<strong>е</strong>мпляр Random, вы<br />

н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong> увид<strong>е</strong>ть этот массив. Да это и н<strong>е</strong> нужно.<br />

Им<strong>е</strong>я доступ, вы могли бы добавлять знач<strong>е</strong>ния, что<br />

прив<strong>е</strong>ло бы к г<strong>е</strong>н<strong>е</strong>рации н<strong>е</strong>случайных чис<strong>е</strong>л. Поэтому<br />

начальны<strong>е</strong> числа должны быть полностью инкапсулированы.<br />

^ 5 А поч<strong>е</strong>му вс<strong>е</strong> обработчики событий объявляются<br />

со словом private?<br />

А зач<strong>е</strong>м запр<strong>е</strong>щать доступ к полям объ<strong>е</strong>ктам<br />

из другого класса?<br />

: Формы в <strong>C#</strong> сконструированы таким образом,<br />

что запуск обработчиков событий мож<strong>е</strong>т осущ<strong>е</strong>ствляться<br />

только при помощи эл<strong>е</strong>м<strong>е</strong>нтов формы. Модификатор<br />

p r i v a t e означа<strong>е</strong>т, что м<strong>е</strong>тод мож<strong>е</strong>т ис­<br />

I Иногда классу приходится отсл<strong>е</strong>живать информацию,<br />

н<strong>е</strong>обходимую для выполн<strong>е</strong>ния каких-то оп<strong>е</strong>раций,<br />

но при этом другим объ<strong>е</strong>ктам эта информа­<br />

обработчики событий н<strong>е</strong> могут управляться постопользоваться<br />

только внутри класса. По умолчанию<br />

ция н<strong>е</strong> нужна. Скаж<strong>е</strong>м, при г<strong>е</strong>н<strong>е</strong>рации случайных ронними формами или объ<strong>е</strong>ктами. Но н<strong>е</strong>т правила,<br />

чис<strong>е</strong>л прим<strong>е</strong>няются так называ<strong>е</strong>мы<strong>е</strong> начальны<strong>е</strong> это пр<strong>е</strong>дписывающ<strong>е</strong>го. Вы мож<strong>е</strong>т<strong>е</strong> щ<strong>е</strong>лкнуть два<br />

числа (seeds). О том, как им<strong>е</strong>нно происходит г<strong>е</strong>н<strong>е</strong>рация,<br />

мы говорить н<strong>е</strong> буд<strong>е</strong>м, достаточно знать, событий модификатор p u b lic . И код вс<strong>е</strong> равно бу­<br />

раза на кнопк<strong>е</strong> и указать в объявл<strong>е</strong>нии обработчика<br />

что каждый экз<strong>е</strong>мпляр Random сод<strong>е</strong>ржит массив д<strong>е</strong>т компилироваться и запускаться.<br />

Е^цинств<strong>е</strong>нным<br />

способом<br />

получ<strong>е</strong>ния информации<br />

из<br />

закрытых пол<strong>е</strong>й<br />

являются<br />

м<strong>е</strong>тоды общ<strong>е</strong>го<br />

доступа, которы<strong>е</strong><br />

возвращают<br />

данны<strong>е</strong>.<br />

210 глава 5


-Jo3bM H в руку карандаш<br />

инкапсуляция<br />

П<strong>е</strong>р<strong>е</strong>д вами класс с закрытыми полями. Обв<strong>е</strong>дит<strong>е</strong> оп<strong>е</strong>раторы,<br />

которы<strong>е</strong> н<strong>е</strong> будут компилироваться, <strong>е</strong>сли их запустить извн<strong>е</strong><br />

класса, используя экз<strong>е</strong>мпляр объ<strong>е</strong>кта mySuperChef.<br />

class SuperChef<br />

{<br />

public string cookieRecipe;<br />

private string secretlngredient;<br />

private const int loyalCustomerOrderAmount = 60;<br />

public int Temperature;<br />

private string ingredientSupplier;<br />

public string GetRecipe (int orderAmount)<br />

{<br />

if (orderAmount >= loyalCustomerOrderAmount)<br />

else<br />

return cookieRecipe;<br />

1. string ovenTemp = mySuperChef.Temperature;<br />

2. string supplier = mySuperChef.ingredientSupplier;<br />

3. int loyalCustomerOrderAmount = 94;<br />

4. mySuperChef.secretlngredient = "кардамон";<br />

5. mySuperChef.cookieRecipe = "3 яйца, 2 1/2 чашки муки, 1 ст. л. соли,<br />

1 ст. л. ванили и 1.5 чашки сахара см<strong>е</strong>шать. Вып<strong>е</strong>кать 10 минут при<br />

т<strong>е</strong>мп<strong>е</strong>ратур<strong>е</strong> 190 °С. Приятного апп<strong>е</strong>тита!";<br />

6. string recipe = mySuperChef.GetRecipe(56);<br />

7. Како<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> буд<strong>е</strong>т им<strong>е</strong>ть п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная recipe посл<strong>е</strong> запуска вс<strong>е</strong>х этих строк кода?<br />

дальш<strong>е</strong> > 211


простор для воображ<strong>е</strong>ния<br />

^озьми в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот каки<strong>е</strong> оп<strong>е</strong>раторы н<strong>е</strong> будут компилироваться, <strong>е</strong>сли запустить<br />

их извн<strong>е</strong> класса, используя экз<strong>е</strong>мпляр объ<strong>е</strong>кта<br />

mySuperChef.<br />

c l a s s SuperC hef<br />

{<br />

p u b l i c s t r i n g c o o k ie R e c ip e ;<br />

p r i v a t e s t r i n g s e c r e t l n g r e d i e n t ;<br />

p r i v a t e c o n s t i n t loyalC ustom erO rderA m ount = 60;<br />

p u b l i c i n t T em p eratu re;<br />

p r i v a t e s t r i n g in g r e d ie n t S u p p l ie r ;<br />

p u b l i c s t r i n g G etR ec ip e<br />

{<br />

i f<br />

( i n t orderAm ount)<br />

(orderAm ount >= loyalC ustom erO rderA m ount)<br />

r e t u r n c o o k ie R e c ip e +<br />

+ s e c r e t l n g r e d i e n t ;<br />

e l s e<br />

r e t u r n c o o k ie R e c ip e ;<br />

Единств<strong>е</strong>нным способом получ<strong>е</strong>ния<br />

с<strong>е</strong>кр<strong>е</strong>тного компон<strong>е</strong>нта ябля<strong>е</strong>тся<br />

заказ вс<strong>е</strong>х ингр<strong>е</strong>ди<strong>е</strong>нтов. Ви<strong>е</strong>шнии<br />

код н<strong>е</strong> им<strong>е</strong><strong>е</strong>т н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нного<br />

доступа к этому польо.<br />

C V ^ r i n g ovenTemp = m ySuperC hef . T em peratu re ;<br />

^^^T itring s u p p l i e r = m ySuperC hef . i n ^ e d i e n t S u ^ T T e r 7<br />

3. i n t loyalC ustom erO rderA m ount = 54;<br />

V<br />

Строки<br />

Попытка присвоить<br />

■‘^^Р^м<strong>е</strong>нную типа<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

типа string<br />

2. м 4 н<strong>е</strong> будут ком ­<br />

пилироваться из-за закры-<br />

5. m y S u p e r C h e f.c o o k ie R e c ip e = "3 яйца, 2 1/2 чашки муки, 1 ст. л. соли,<br />

1 с т . л . ванили и 1 .5 чашки са х а р а см<strong>е</strong>ш ать. Вып<strong>е</strong>кать 10 минут при<br />

т<strong>е</strong>м п <strong>е</strong>ратур<strong>е</strong> 190 °С. Приятного а п п <strong>е</strong>т и т а !» ;<br />

6. s t r i n g r e c ip e = m y S u p e r C h e f.G e tR e c ip e (5 6 );<br />

^^^и локальная<br />

/. Како<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> буд<strong>е</strong>т им<strong>е</strong>ть п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная r e c ip e посл<strong>е</strong> запуска вс<strong>е</strong>х этих строк кода^Ту<br />

3 яйца, Z 1 / Z чашки м ук и , 1 с т . л. соли, 1 с т . л. ванили и 1 .S чаш ки сахара см <strong>е</strong>ш а т ь.<br />

.......м и н у т при т <strong>е</strong> м п <strong>е</strong> р а т у р <strong>е</strong> Х йО °С. П рият ного а п п <strong>е</strong>т и т а !<br />

212 глава 5


инкапсуляция<br />

Нич<strong>е</strong>го н<strong>е</strong> понимаю. Закрыто<strong>е</strong> пол<strong>е</strong> н<strong>е</strong><br />

позволя<strong>е</strong>т другом классу использовать с<strong>е</strong>бя. Но <strong>е</strong>сли<br />

пом<strong>е</strong>нять private на public програллма вс<strong>е</strong> равно буд<strong>е</strong>т<br />

постро<strong>е</strong>на! А вот добавл<strong>е</strong>ни<strong>е</strong> модификатора private<br />

д<strong>е</strong>ла<strong>е</strong>т компиляцию н<strong>е</strong>возможной. Зач<strong>е</strong>м мн<strong>е</strong> тогда<br />

вообщ<strong>е</strong> <strong>е</strong>го использовать?<br />

Потому что иногда возника<strong>е</strong>т н<strong>е</strong>обходимость<br />

скрыть н<strong>е</strong>кую информацию от остальной части<br />

программы.<br />

Большинство пользоват<strong>е</strong>л<strong>е</strong>й поначалу н<strong>е</strong> могут принять<br />

ид<strong>е</strong>ю инкапсуляции, так как н<strong>е</strong> понимают, зач<strong>е</strong>м<br />

нужно скрывать поля, м<strong>е</strong>тоды или свойства одного<br />

класса от другого. Но пост<strong>е</strong>п<strong>е</strong>нно вы пойм<strong>е</strong>т<strong>е</strong> причины,<br />

по которым н<strong>е</strong>которы<strong>е</strong> классы им<strong>е</strong><strong>е</strong>т смысл<br />

д<strong>е</strong>лать н<strong>е</strong>видимыми для остальной части программы.<br />

инкапсуляция д<strong>е</strong>ла<strong>е</strong>т классы...<br />

-к Л<strong>е</strong>гкими в прим<strong>е</strong>н<strong>е</strong>нии<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что поля нужны для отсл<strong>е</strong>живания данных. И большинство<br />

из них прим<strong>е</strong>ня<strong>е</strong>т м<strong>е</strong>тоды для обновл<strong>е</strong>ния информации —<br />

эти м<strong>е</strong>тоды н<strong>е</strong> нужны никакому другому классу. Часто поля, м<strong>е</strong>тоды<br />

и свойства одного класса сов<strong>е</strong>рш<strong>е</strong>нно н<strong>е</strong> нужны в других частях<br />

программы. Пом<strong>е</strong>тив их словом private, вы уб<strong>е</strong>р<strong>е</strong>т<strong>е</strong> их из окна<br />

IntelliSense.<br />

★<br />

•к<br />

Л<strong>е</strong>гкими в управл<strong>е</strong>нии<br />

Вспомнит<strong>е</strong> программу Кэтлин? Пробл<strong>е</strong>ма возникала потому, что<br />

форма им<strong>е</strong>ла н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нный доступ к полю. Если бы пол<strong>е</strong> было<br />

закрытым, программа работала бы правильно.<br />

Гибкими<br />

Иногда по прош<strong>е</strong>ствии вр<strong>е</strong>м<strong>е</strong>ни возника<strong>е</strong>т н<strong>е</strong>обходимость вн<strong>е</strong>сти<br />

в программу изм<strong>е</strong>н<strong>е</strong>ния. С хорошо инкапсулированными классами<br />

н<strong>е</strong> возника<strong>е</strong>т вопросов по их дгшьн<strong>е</strong>йш<strong>е</strong>му использованию.<br />

Инкапсуляция<br />

означа<strong>е</strong>т скрыти<strong>е</strong><br />

информации<br />

одного<br />

класса от другого.<br />

Она помога<strong>е</strong>т<br />

пр<strong>е</strong>дотвратить<br />

появл<strong>е</strong>ни<strong>е</strong><br />

ошибок.<br />

ШTVP»Л<br />

Как плохо инкапсулированны<strong>е</strong> классы могут пом<strong>е</strong>шать<br />

р<strong>е</strong>дактированию программы в будущ<strong>е</strong>м?<br />

дальш<strong>е</strong> > 213


путаница у майка<br />

Программ<strong>е</strong> Майка н<strong>е</strong> пом<strong>е</strong>шала бы инкапсуляция<br />

Помнит<strong>е</strong> программу Майка из главы 3? Майк увл<strong>е</strong>кся г<strong>е</strong>окэшингом и над<strong>е</strong><strong>е</strong>тся<br />

на помощь навигатора. Он давно н<strong>е</strong> обновлял программу и с<strong>е</strong>йчас испытыва<strong>е</strong>т<br />

пробл<strong>е</strong>мы. Класс Route в <strong>е</strong>го программ<strong>е</strong> хранит маршрут м<strong>е</strong>жду<br />

двумя точками. Но Майк н<strong>е</strong> помнит, как им пользоваться! Вот что получа<strong>е</strong>тся<br />

при попытках р<strong>е</strong>дактировать код:<br />

Г<strong>е</strong>окэшингом называ<strong>е</strong>тся<br />

игра, в которой<br />

игроки иш,ут тайники,<br />

с помощью аР5<br />

опр<strong>е</strong>д<strong>е</strong>ляют их координаты<br />

и сообщают<br />

о Инт<strong>е</strong>рн<strong>е</strong>т<strong>е</strong>.<br />

Свойству StartPoint были присво<strong>е</strong>ны координаты дома Майка,<br />

а свойству EndPoint —координаты офиса. Свойство Length показало,<br />

что расстояни<strong>е</strong> равно 15.3. Но м<strong>е</strong>тод GetRouteLength () в<strong>е</strong>рнул<br />

Ов кач<strong>е</strong>ств<strong>е</strong> р<strong>е</strong>зультата.<br />

Свойству SetStartPoint О были присво<strong>е</strong>ны координаты<br />

дома, а свойству SetEndPoint () - координаты офиса. М<strong>е</strong>тод<br />

GetRouteLength () в<strong>е</strong>рнул знач<strong>е</strong>ни<strong>е</strong> 9.51, в то вр<strong>е</strong>мя как свойство<br />

Length показало расстояни<strong>е</strong> 5.91.<br />

Н<strong>е</strong> могу вспомнить,<br />

мн<strong>е</strong> тр<strong>е</strong>бовалось пол<strong>е</strong><br />

StaгtPoint или м<strong>е</strong>тод<br />

SetStaгtPoint(). Но раньш<strong>е</strong><br />

вс<strong>е</strong> работало!<br />

У<br />

ПpипoпыткaxиcпoльзoвaтьcвoйcтБaStartPointиSetEndPoint {)<br />

м<strong>е</strong>тод GetRouteLength () вс<strong>е</strong>гда возвращал О, тако<strong>е</strong> ж<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

показывало свойство Length.<br />

Попытавшись взять для задания начальной и кон<strong>е</strong>чной точ<strong>е</strong>к<br />

м<strong>е</strong>тод SetStartPoint () и свойство EndPoint соотв<strong>е</strong>тств<strong>е</strong>нно,<br />

Майк увид<strong>е</strong>л, что свойство Length им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> О, а м<strong>е</strong>тод<br />

GetRouteLength () приводит к сообщ<strong>е</strong>нию об ошибк<strong>е</strong>... что-то про<br />

н<strong>е</strong>возможность д<strong>е</strong>л<strong>е</strong>ния на ноль.<br />

^<br />

V<br />

^Возьми в руку карандаш<br />

Route<br />

Вот объ<strong>е</strong>кт Route из программы Майка. Каки<strong>е</strong> свойства и м<strong>е</strong>тоды<br />

вы бы пом<strong>е</strong>тили как private, чтобы обл<strong>е</strong>гчить их использовани<strong>е</strong>?<br />

StartPoint<br />

EndPoint<br />

Length<br />

GetRouteLengtliO<br />

GetStartPointO<br />

GetEndPointQ<br />

SetStartPointO<br />

SetEndPointO<br />

ChangeStartPointO<br />

ChangeEndPointQ<br />

Есть много пот<strong>е</strong>нциально правильных способов р<strong>е</strong>ш<strong>е</strong>ния этой задачи!<br />

Запишит<strong>е</strong> лучши<strong>е</strong>.<br />

214 глава 5


инкапсуляция<br />

npegcmaBuM объ<strong>е</strong>кт ß Buge «ч<strong>е</strong>рного ящика»<br />

Иногда можно услышать, как программисты называют объ<strong>е</strong>кты<br />

«ч<strong>е</strong>рным ящиком». Прим<strong>е</strong>рно так вс<strong>е</strong> и выглядит. При вызов<strong>е</strong> м<strong>е</strong>тодов<br />

объ<strong>е</strong>кта вы вряд ли заботит<strong>е</strong>сь о том, как им<strong>е</strong>нно они работают,<br />

по крайн<strong>е</strong>й м<strong>е</strong>р<strong>е</strong>, н<strong>е</strong> на т<strong>е</strong>кущ<strong>е</strong>м этап<strong>е</strong> обуч<strong>е</strong>ния. Вам пока<br />

нужно, чтобы м<strong>е</strong>тод взял указанны<strong>е</strong> вами знач<strong>е</strong>ния и выдал нужный<br />

р<strong>е</strong>зультат<br />

О ткры в ч<strong>е</strong>р<strong>е</strong>з н<strong>е</strong>которо<strong>е</strong> вр<strong>е</strong>мя<br />

старую програм му, вы вряд ли<br />

вспом нит<strong>е</strong>, как пр<strong>е</strong>дполагалось<br />

использовать т<strong>е</strong> или ины <strong>е</strong> п <strong>е</strong>р <strong>е</strong>­<br />

м<strong>е</strong>нны <strong>е</strong>. В от т у т инкапсуляция<br />

м ож <strong>е</strong>т сильно обл<strong>е</strong>гчить вам<br />

жизнь!<br />

Мой объ<strong>е</strong>кт Route<br />

работа<strong>е</strong>т! Но вот как <strong>е</strong>го<br />

с<strong>е</strong>йчас приспособить<br />

<strong>е</strong>го для г<strong>е</strong>окэшинга?<br />

Когда 6 глав<strong>е</strong> 3 Майк создавал<br />

навигатор, он хорошо знал,<br />

как работа<strong>е</strong>т одь<strong>е</strong>кт Route.<br />

Но прошло вр<strong>е</strong>т ...<br />

Правильно<br />

инкапсулировав<br />

классы с<strong>е</strong>годня,<br />

вы обл<strong>е</strong>гчит<strong>е</strong> с<strong>е</strong>б<strong>е</strong><br />

работу с ними<br />

завтра.<br />

ЧУ<br />

МйЫК цсп<strong>е</strong>шно ислол<strong>е</strong>?зобйЛ<br />

н Х г ^ т о р и т <strong>е</strong>п<strong>е</strong>р. он хоч<strong>е</strong>т<br />

«лЙидо^7Н0 исполмоба!!!^<br />

объ<strong>е</strong>кт Route.<br />

V<br />

Если 5tp! Майк вспомнил об<br />

инкапсуляции при ^озЗянии<br />

объ<strong>е</strong>кта Route, с<strong>е</strong>годня у<br />

н<strong>е</strong>го н<strong>е</strong> бол<strong>е</strong>ла 6t>i голова.<br />

s t a r t P o in t<br />

Исходная точка<br />

Майк хоч<strong>е</strong>т воспринимать<br />

объ<strong>е</strong>кт Route как «ч<strong>е</strong>рный<br />

ящмк». Просто указывать<br />

координаты, а о отв<strong>е</strong>т<br />

получать длину маршрута.<br />

Его н<strong>е</strong> волну<strong>е</strong>т, как им<strong>е</strong>нно<br />

объ<strong>е</strong>кт Route вычисля<strong>е</strong>т<br />

эту длину.<br />

L en gth<br />

Длина маршрута<br />

End P o in t<br />

Кон<strong>е</strong>чная точка<br />

дальш<strong>е</strong> * 215


как лучш<strong>е</strong> пров<strong>е</strong>сти инкапсуляцию<br />

Получа<strong>е</strong>тся, что<br />

инкапсулированный класс д<strong>е</strong>ла<strong>е</strong>т ровно<br />

то ж<strong>е</strong>, что и н<strong>е</strong>инкапсулированный.<br />

Ест<strong>е</strong>ств<strong>е</strong>нно! Основно<strong>е</strong> отличи<strong>е</strong> инкапсулированного<br />

класса в том, что он пр<strong>е</strong>дотвраща<strong>е</strong>т появл<strong>е</strong>ни<strong>е</strong><br />

ошибок и бол<strong>е</strong><strong>е</strong> прост в использовании.<br />

Испортить инкапсулированный класс л<strong>е</strong>гко: воспользуйт<strong>е</strong>сь<br />

функци<strong>е</strong>й поиска с посл<strong>е</strong>дующ<strong>е</strong>й зам<strong>е</strong>ной, чтобы зам<strong>е</strong>нить<br />

вс<strong>е</strong> модификаторы p r i v a t e на p u b lic .<br />

Как ни странно, посл<strong>е</strong> этого программа вс<strong>е</strong> равно буд<strong>е</strong>т благополучно<br />

скомпилирована. И даж<strong>е</strong> буд<strong>е</strong>т работать так ж<strong>е</strong>,<br />

как и раньш<strong>е</strong>. Им<strong>е</strong>нно поэтому многим пользоват<strong>е</strong>лям так<br />

сложно понять, зач<strong>е</strong>м вообщ<strong>е</strong> нужна инкапсуляция.<br />

До этого мом<strong>е</strong>нта вы учились тому, как заставить программу<br />

вы полнять д<strong>е</strong>йствия. Инкапсуляция ж<strong>е</strong> н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>т способ<br />

достиж<strong>е</strong>ния поставл<strong>е</strong>нной ц<strong>е</strong>ли. Она похожа на игру<br />

в шахматы: скрывая опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нную информацию на стадии<br />

создания классов, вы зада<strong>е</strong>т<strong>е</strong> страт<strong>е</strong>гию взаимод<strong>е</strong>йствия<br />

этих классов в будущ<strong>е</strong>м. Ч<strong>е</strong>м лучш<strong>е</strong> буд<strong>е</strong>т эта страт<strong>е</strong>гия, т<strong>е</strong>м<br />

бол<strong>е</strong><strong>е</strong> гибкой получится программа, и т<strong>е</strong>м больш<strong>е</strong>го колич<strong>е</strong>ства<br />

ошибок вы изб<strong>е</strong>жит<strong>е</strong>.<br />

Как в шакматак сущ<strong>е</strong>ству<strong>е</strong>т<br />

множ<strong>е</strong>ство вариантов кодов, так<br />

и колич<strong>е</strong>ство страт<strong>е</strong>гий инкапсуляции<br />

явля<strong>е</strong>тся почти б<strong>е</strong>скон<strong>е</strong>чным.<br />

216 глава 5


инкапсуляция<br />

К^ак ираБиЛьНо инкапсули]=‘оБаш ь КЛассы<br />

Думайт<strong>е</strong> о способах н<strong>е</strong>правильного использования пол<strong>е</strong>й.<br />

Что мож<strong>е</strong>т пойти н<strong>е</strong> так, <strong>е</strong>сли выбрать н<strong>е</strong>правильный уров<strong>е</strong>нь доступа?<br />

★ Вся ли информация в класс<strong>е</strong> мож<strong>е</strong>т быть открытой?<br />

Если вс<strong>е</strong> поля и м<strong>е</strong>тоды в класс<strong>е</strong> являются открытыми, сл<strong>е</strong>ду<strong>е</strong>т бол<strong>е</strong><strong>е</strong><br />

д<strong>е</strong>тально подумать об инкапсуляции.<br />

★ Каки<strong>е</strong> поля будут участвовать в вычисл<strong>е</strong>ниях?<br />

Они — п<strong>е</strong>рвы<strong>е</strong> кандидаты на инкапсуляцию. Если позж<strong>е</strong> к программ<strong>е</strong> буд<strong>е</strong>т<br />

добавл<strong>е</strong>н м<strong>е</strong>тод, использующий знач<strong>е</strong>ни<strong>е</strong> одного из таких пол<strong>е</strong>й, это мож<strong>е</strong>т<br />

прив<strong>е</strong>сти к ошибк<strong>е</strong>.<br />

Сначала нужно вычислить<br />

стоимость офор/йл<strong>е</strong>ния. Посл<strong>е</strong><br />

этого остан<strong>е</strong>тся добавить стоимость<br />

<strong>е</strong>ды и напитков.<br />

★ Открывайт<strong>е</strong> доступ к полям и м<strong>е</strong>тодам только в случа<strong>е</strong><br />

н<strong>е</strong>обходимости.<br />

Если у вас н<strong>е</strong>т в<strong>е</strong>ской причины оставлять общий доступ к полю или м<strong>е</strong>тоду,<br />

н<strong>е</strong> д<strong>е</strong>лайт<strong>е</strong> этого. Оставив доступ ко вс<strong>е</strong>м полям, вы только запута<strong>е</strong>т<strong>е</strong><br />

программу. Впроч<strong>е</strong>м, н<strong>е</strong> стоит впадать и в другую крайность д<strong>е</strong>лать вс<strong>е</strong><br />

поля закрытыми. Правильно выбрав уровни доступа, вы сэкономит<strong>е</strong> вр<strong>е</strong>мя<br />

в будущ<strong>е</strong>м.<br />

дальш<strong>е</strong> ► 217


чита<strong>е</strong>м, записыва<strong>е</strong>м, получа<strong>е</strong>м р<strong>е</strong>зультат<br />

инкапсуляция сохраня<strong>е</strong>т данны<strong>е</strong> н<strong>е</strong>тронуты м и<br />

Иногда знач<strong>е</strong>ни<strong>е</strong> поля м<strong>е</strong>ня<strong>е</strong>тся по ходу выполн<strong>е</strong>ния программы. Если программ<strong>е</strong> в явном<br />

вид<strong>е</strong> н<strong>е</strong> сказано возвращать поля в исходно<strong>е</strong> состояни<strong>е</strong>, вычисл<strong>е</strong>ния д<strong>е</strong>лаются с новыми знач<strong>е</strong>ниями.<br />

В н<strong>е</strong>которых случаях им<strong>е</strong>нно это и тр<strong>е</strong>бу<strong>е</strong>тся, то <strong>е</strong>сть программа должна выполнять<br />

н<strong>е</strong>ки<strong>е</strong> вычисл<strong>е</strong>ния при каждом изм<strong>е</strong>н<strong>е</strong>нии знач<strong>е</strong>ния поля. Помнит<strong>е</strong> программу Кэтлин, в которой<br />

стоимость м<strong>е</strong>роприятия п<strong>е</strong>р<strong>е</strong>считывалась при каждом изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства гост<strong>е</strong>й?<br />

Мы мож<strong>е</strong>м изб<strong>е</strong>жать такого пов<strong>е</strong>д<strong>е</strong>ния, просто инкапсулировав поля. Посл<strong>е</strong> этого потр<strong>е</strong>бу<strong>е</strong>тся<br />

м<strong>е</strong>тод, получающий их знач<strong>е</strong>ни<strong>е</strong>, и другой м<strong>е</strong>тод, который присваива<strong>е</strong>т знач<strong>е</strong>ния полям и<br />

выполня<strong>е</strong>т вс<strong>е</strong> н<strong>е</strong>обходимы<strong>е</strong> расч<strong>е</strong>ты.<br />

Прим<strong>е</strong>р инкапсуляции<br />

Класс Farm er (Ф<strong>е</strong>рм<strong>е</strong>р) использу<strong>е</strong>т пол<strong>е</strong> для хран<strong>е</strong>ния информации о колич<strong>е</strong>ство коров<br />

(numberOfCows), которо<strong>е</strong> зат<strong>е</strong>м умножа<strong>е</strong>тся на колич<strong>е</strong>ство м<strong>е</strong>шков с кормом, н<strong>е</strong>обходимо<strong>е</strong><br />

для одной коровы:<br />

c l a s s Farmer<br />

{<br />

p r i v a t e i n t numberOfCows;<br />

Сд<strong>е</strong>ла<strong>е</strong>м эт о пол<strong>е</strong> закры т ы м ,<br />

чтобы никто н<strong>е</strong> м ог пом<strong>е</strong>нят ь<br />

<strong>е</strong>го, н<strong>е</strong> от р<strong>е</strong>дакт ировав при<br />

эт ом пол<strong>е</strong> bagsOfFeed (м<strong>е</strong>шки<br />

с кормом). Рассинхронизация<br />

эт их пол<strong>е</strong>й приводит<br />

к ошибкам в програм м <strong>е</strong>!<br />

Ввод пользоват<strong>е</strong>л<strong>е</strong>м колич<strong>е</strong>ства коров в форму долж<strong>е</strong>н м<strong>е</strong>нять знач<strong>е</strong>ни<strong>е</strong><br />

поля numberOfCows. Значит, потр<strong>е</strong>бу<strong>е</strong>тся м<strong>е</strong>тод, возвращающий знач<strong>е</strong>ни<strong>е</strong><br />

этого поля форм<strong>е</strong>:<br />

Одной коров<strong>е</strong><br />

m .peбу<strong>е</strong>тся<br />

,<br />

30 м<strong>е</strong>шкоо ><br />

КОрМД-<br />

p u b l i c c o n s t i n t F e e d M u lt ip lie r = 3 0;<br />

p u b l i c i n t GetNum berOfCows()<br />

r e t u r n numberOfCows;<br />

Э т от м <strong>е</strong>т од сообща<strong>е</strong>т<br />

другим классам<br />

колич<strong>е</strong>ство коров.<br />

p u b l i c v o i d SetN u m berO fC ow s(int newNumberOfCows)<br />

{<br />

numberOfCows = newNumberOfCows;<br />

B agsO fF eed = numberOfCows * F e e d M u lt ip lie r ;<br />

Им<strong>е</strong>на пол<strong>е</strong>й огранич<strong>е</strong>нного дост упа<br />

начинаются со строчной буквы, в то<br />

вр<strong>е</strong>мя как у пол<strong>е</strong>й обш,<strong>е</strong>го дост упа<br />

им<strong>е</strong>на начинаются с прописной буквы.<br />

М <strong>е</strong>тод, задаюи^ий число<br />

коров, который га р а н -<br />

т .иру<strong>е</strong>т одновр<strong>е</strong>м<strong>е</strong>нно<strong>е</strong><br />

изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

8a^sC>fFeec^.<br />

218 глава 5


инкапсуляция<br />

инкапсуляция при помои^и сВойстВ<br />

Свойства (properties) объ<strong>е</strong>диняют функции пол<strong>е</strong>й и м<strong>е</strong>тодов. Они используются для чт<strong>е</strong>ния<br />

и записи вспомогат<strong>е</strong>льного поля (backing field). Им<strong>е</strong>нно так называ<strong>е</strong>тся пол<strong>е</strong>, заданно<strong>е</strong><br />

свойством.<br />

Закрыто<strong>е</strong> пол<strong>е</strong> numherOfCo^s стан<strong>е</strong>т<br />

в ^м о га т <strong>е</strong> льн ы м м л <strong>е</strong> м свойства<br />

p r i v a t e int n i m b e r O f C o w S ; N u m berO fC ow s.<br />

i n t K u ^ e . 0 . c o „ s<br />

{<br />

М<strong>е</strong>тод чт<strong>е</strong>ния вызыва<strong>е</strong>тся каждый раз,<br />

}<br />

r e t u r n n u m b e r O f C o w s ;<br />

записи<br />

n u m b e r O f C o w s = value;<br />

B a g s O f F e e d = n u m b e r O f C o w s * F e e d M u l t i p l i e r ;<br />

М<strong>е</strong>тоды чт<strong>е</strong>ния и записи используют так ж<strong>е</strong>, как поля. Вот код<br />

для кнопки, которая зада<strong>е</strong>т колич<strong>е</strong>ство коров, а в отв<strong>е</strong>т получа<strong>е</strong>т<br />

колич<strong>е</strong>ство м<strong>е</strong>шков с кормом:<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t se n d e r , E v en tA rg s e) {<br />

Farm er myFarmer = new F a rm er();<br />

myFarmer.NumberOfCows = 10;<br />

В этой строчк<strong>е</strong> м <strong>е</strong> ­<br />

тод записи зада<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> закрытого<br />

поля numberOfCows<br />

и т<strong>е</strong>м самым обновля<strong>е</strong>т<br />

открыто<strong>е</strong> пол<strong>е</strong><br />

BagsOfFeed.<br />

i n t howManyBags = m yF arm er.B agsO fFeed;<br />

myFarmer.NumberOfCows = 20;<br />

howManyBags = m yF arm er.B agsO fFeed;<br />

^<br />

Так как м<strong>е</strong>тод записи<br />

' NumberOfCows обновил<br />

пол<strong>е</strong> BagsOfFeed, вы<br />

мож<strong>е</strong>т<strong>е</strong> получить <strong>е</strong>го<br />

знач<strong>е</strong>ни<strong>е</strong>.<br />

враш,ающий знач<strong>е</strong>ни<strong>е</strong> 300.<br />

дальш<strong>е</strong> > 219


частная собств<strong>е</strong>нность (н<strong>е</strong> входить)<br />

Придо)к<strong>е</strong>ни<strong>е</strong> для проВ<strong>е</strong>рки класса Farmer<br />

Создайт<strong>е</strong> ново<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong> Windows Forms для пров<strong>е</strong>рки класса Farmer<br />

и <strong>е</strong>го свойств. Для вывода р<strong>е</strong>зультатов буд<strong>е</strong>т использован м<strong>е</strong>тод C o n s o le .<br />

WriteLineO.<br />

Л Т ^<br />

У11Р & Ж Н Р Н Ц Р<br />

-•<br />

О<br />

Добавьт<strong>е</strong> к про<strong>е</strong>кту класс Farm er:<br />

c l a s s Farm er {<br />

p u b l i c i n t B agsO fF eed;<br />

p u b l i c c o n s t i n t F e e d M u lt ip lie r = 30;<br />

p r i v a t e i n t numberOfCows;<br />

p iib lic i n t NumberOfCows {<br />

(добавьт<strong>е</strong> м<strong>е</strong>тоды чт<strong>е</strong>ния и записи с пр<strong>е</strong>дыдущ<strong>е</strong>й страницы)<br />

О Создайт<strong>е</strong> форму:<br />

О<br />

Кнопка называ<strong>е</strong>мся<br />

«вычислить» и использу<strong>е</strong>т<br />

открыты<strong>е</strong><br />

данны<strong>е</strong> класса Farmer<br />

для вывода р<strong>е</strong>зультата.<br />

Присвойт<strong>е</strong> парам<strong>е</strong>-<br />

>^рам Value, Minimum<br />

и Maximum эл<strong>е</strong>м<strong>е</strong>нта<br />

NumericUpDown знач<strong>е</strong>ния<br />

3 0 0 соотв<strong>е</strong>т -<br />

ств<strong>е</strong>нно.<br />

Код формы использу<strong>е</strong>т м<strong>е</strong>тод C o n so le .W rite L in e {) для отправки итоговых данных<br />

в окно O utput (это окно вызыва<strong>е</strong>тся такж<strong>е</strong> командой O utput из м<strong>е</strong>ню Debug » Windows).<br />

М<strong>е</strong>тоду W rite L in e () можно п<strong>е</strong>р<strong>е</strong>дать н<strong>е</strong>сколько парам<strong>е</strong>тров и п<strong>е</strong>рвый - это выводимая<br />

строка. Включив в эту строку “ {О} ” вы выв<strong>е</strong>д<strong>е</strong>т<strong>е</strong> п<strong>е</strong>рвый парам<strong>е</strong>тр, “ {1} ” - второй парам<strong>е</strong>тр,<br />

“ {2} ” —тр<strong>е</strong>тий парам<strong>е</strong>тр и т. д.<br />

%<br />

p u b l i c p a r t i a l c l a s s Form l : Form {<br />

Farm er farm er;<br />

p u b l i c Forml 0 { .дйШКоб<br />

I n it i a liz e C o m p o n e n t O ;<br />

fa rm er = new Farm er () { NumberOfCows = 15 };<br />

}<br />

p r i v a t e v o i d n u m ericU p D o w n l_ V a lu eC h a n g ed {o b ject s e n d e r ,<br />

farm er.N um berofC ow s = (in t)n u m e r ic U p D o w n l.V a lu e ;<br />

}<br />

p r i v a t e v o i d c a l c u l a t e _ C l i c k ( o b j e c t s e n d e r , E v en tA rg s e) {<br />

C o n s o le .W r it e L in e ("I n e e d {o} b a g s o f f e e d f o r {l} cow s" ,<br />

fa r m e r .B a g sO fF ee d ,<br />

farm er.N u m berO fC ow s);<br />

E ven tA rgs<br />

[ м <strong>е</strong> т о д Console.WriteLineO<br />

^ отправля<strong>е</strong>т строчки<br />

WriteLine () зам<strong>е</strong>ща<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong>м п<strong>е</strong>рвого парам<strong>е</strong>тра, а {1} -<br />

с т<strong>е</strong>кстом в окно Output. знач<strong>е</strong>ни<strong>е</strong>м второго парам<strong>е</strong>тра.<br />

220 глава 5


Автоматич<strong>е</strong>ски<strong>е</strong> сВойстВа<br />

инкапсуляция<br />

Каж<strong>е</strong>тся, наш сч<strong>е</strong>тчик коров работа<strong>е</strong>т корр<strong>е</strong>ктно. Запустит<strong>е</strong> программу и щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> для пров<strong>е</strong>рки.<br />

Сд<strong>е</strong>лайт<strong>е</strong> колич<strong>е</strong>ство коров равным 30 и снова щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong>. Повторит<strong>е</strong> эту оп<strong>е</strong>рацию<br />

для 5 коров, а потом для 20 коров. Вот что должно появиться в окн<strong>е</strong> Output:<br />

I need 450 bags of feed for is cows<br />

I need see bags of feed for 30 co»s<br />

I need 150 bags of feed for 5 cows<br />

I need 600 bags of feed for 20 cows<br />

Но <strong>е</strong>сть н<strong>е</strong>большая пробл<strong>е</strong>ма. Добавьт<strong>е</strong> к форм<strong>е</strong> кнопку, которая выполня<strong>е</strong>т оп<strong>е</strong>ратор:<br />

farmer.BagsOfFeed = 5;<br />

Вы понима<strong>е</strong>т<strong>е</strong>,<br />

поч<strong>е</strong>му это<br />

стало причиной<br />

ошибки?<br />

Запустит<strong>е</strong> программу. Вс<strong>е</strong> работа<strong>е</strong>т до нажатия новой кнопки. Попробуйт<strong>е</strong> посл<strong>е</strong> этого нажать кнопку<br />

Calculate. Окаж<strong>е</strong>тся, что 5 м<strong>е</strong>шков корма тр<strong>е</strong>бу<strong>е</strong>тся для любого колич<strong>е</strong>ства коров! Посл<strong>е</strong> р<strong>е</strong>дактирования<br />

парам<strong>е</strong>тра N u m ericU p D o w n кнопка Calculate снова начн<strong>е</strong>т работать корр<strong>е</strong>ктно.<br />

Полностью инкапсулиру<strong>е</strong>м класс Farmer<br />

Нап<strong>е</strong>чатав<br />

и дважды нажаЬ<br />

Пробл<strong>е</strong>ма в том, что класс н<strong>е</strong> полностью инкапсулирован. С помощью свойств мы tab, вы добавит<strong>е</strong><br />

инкапсулировали п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную N u m berO fC ow s, но п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная B a g s O f F e e d до сих пор к коду автоматич<strong>е</strong>ско<strong>е</strong><br />

свойство.<br />

общ<strong>е</strong>доступна. Это крайн<strong>е</strong> распростран<strong>е</strong>нная пробл<strong>е</strong>ма. Настолько распростран<strong>е</strong>нная,<br />

что в <strong>C#</strong> сущ<strong>е</strong>ству<strong>е</strong>т автоматич<strong>е</strong>ская проц<strong>е</strong>дура <strong>е</strong><strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ния. Просто зам<strong>е</strong>нит<strong>е</strong> пол<strong>е</strong><br />

общ<strong>е</strong>го доступа B a g s O f F e e d автоматич<strong>е</strong>ским свойством. Вот как это сд<strong>е</strong>лать:<br />

/<br />

Удалит<strong>е</strong> пол<strong>е</strong> B a g s O f F e e d из класса F a rm er. Вм<strong>е</strong>сто н<strong>е</strong>го вв<strong>е</strong>дит<strong>е</strong> prop и дважды нажмит<strong>е</strong><br />

tab. Появится сл<strong>е</strong>дующая строка кода:<br />

о<br />

public[xnt] МуProperty { get; set; }<br />

Снова нажмит<strong>е</strong> tab, чтобы выд<strong>е</strong>лить пол<strong>е</strong> M y P r o p e r ty . Вв<strong>е</strong>дит<strong>е</strong> имя B a g sO fF e e d :<br />

public int BagsOfFeed { get; set; }<br />

о<br />

Т<strong>е</strong>п<strong>е</strong>рь у вас свойство вм<strong>е</strong>сто поля. Компилятор обрабатыва<strong>е</strong>т эту информацию, как вспомогат<strong>е</strong>льно<strong>е</strong><br />

пол<strong>е</strong>.<br />

Впроч<strong>е</strong>м пробл<strong>е</strong>ма <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>на. Для <strong>е</strong><strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ния сд<strong>е</strong>лайт<strong>е</strong> свойство доступным только<br />

для чт<strong>е</strong>ния:<br />

public int BagsOfFeed { get; private set; }<br />

При попытк<strong>е</strong> построить код вы получит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong> в строчк<strong>е</strong>, задающ<strong>е</strong>й<br />

свойство B a g s O f F e e d , —м<strong>е</strong>тод записи н<strong>е</strong>доступ<strong>е</strong>н. В<strong>е</strong>дь вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> р<strong>е</strong>дактировать<br />

свойство B a g s O f F e e d вн<strong>е</strong> класса F a rm e r. Удалит<strong>е</strong> строчку кода, соотв<strong>е</strong>тствующую второй<br />

кнопк<strong>е</strong>. Т<strong>е</strong>п<strong>е</strong>рь класс F a r m e r хорошо инкапсулирован!<br />

дальш<strong>е</strong> ► 221


настройки<br />

Р<strong>е</strong>дактиру<strong>е</strong>м мно)кит<strong>е</strong>ль feed<br />

При постро<strong>е</strong>нии сч<strong>е</strong>тчика коров множит<strong>е</strong>ль, указывающий колич<strong>е</strong>ство<br />

корма на одну особь, мы опр<strong>е</strong>д<strong>е</strong>лили как константу. Но пр<strong>е</strong>дставим, что<br />

нам тр<strong>е</strong>бу<strong>е</strong>тся <strong>е</strong>го изм<strong>е</strong>нить. Вы уж<strong>е</strong> вид<strong>е</strong>ли, как доступ к полям одного<br />

класса со стороны других классов мож<strong>е</strong>т стать причиной ошибки. Им<strong>е</strong>нно<br />

поэтому общий доступ к полям и м<strong>е</strong>тодам им<strong>е</strong><strong>е</strong>т смысл оставлять<br />

только там, гд<strong>е</strong> это н<strong>е</strong>обходимо. Так как программа никогда н<strong>е</strong> обновля<strong>е</strong>т<br />

F e e d M u ltip lie r, нам н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся запись в это пол<strong>е</strong> из других классов.<br />

Поэтому сд<strong>е</strong>ла<strong>е</strong>м <strong>е</strong>го свойством доступным только для чт<strong>е</strong>ния, которо<strong>е</strong> использу<strong>е</strong>т<br />

вспомогат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong>.<br />

Удалит<strong>е</strong> строчку<br />

p u b l i c c o n s t i n t F e e d M u lt ip lie r = 30;<br />

Воспользуйт<strong>е</strong>сь комбинаци<strong>е</strong>й prop-tab-tab, чтобы добавить свойство,<br />

доступно<strong>е</strong> только для чт<strong>е</strong>ния. Но вм<strong>е</strong>сто автоматич<strong>е</strong>ского свойства<br />

добавьт<strong>е</strong> вспомогат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong>:<br />

p r i v a t e i n t f e e d M u l t i p l i e r ;<br />

p u b l i c i n t F e e d M u lt ip lie r { g e t { r e t u r n f e e d M u lt i p l i e r ; } }<br />

J<br />

Так как вм<strong>е</strong>сто константы общ<strong>е</strong>го доступа у наст крыт о<strong>е</strong> пол<strong>е</strong><br />

типа intj <strong>е</strong>го имя т<strong>е</strong>п<strong>е</strong>рь начина<strong>е</strong>тся со строчной буквы г.<br />

Ф t<br />

У п ]^ а ж н <strong>е</strong> н и <strong>е</strong> !<br />

Свойство<br />

гат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong><br />

.<strong>е</strong>г<br />

М<strong>е</strong>тод записи отсутству<strong>е</strong>т,<br />

то <strong>е</strong>сть оно доступно толь<br />

ко для чт<strong>е</strong>ния. М<strong>е</strong>тод чт<strong>е</strong>тя<br />

при этом открыт, то <strong>е</strong>сть<br />

знач<strong>е</strong>ни<strong>е</strong> поля<br />

можно прочитать из людого<br />

другого класса.<br />

0 Запуск кода посл<strong>е</strong> вн<strong>е</strong>с<strong>е</strong>ния в н<strong>е</strong>го изм<strong>е</strong>н<strong>е</strong>ний покаж<strong>е</strong>т абсурдный р<strong>е</strong>зультат. Свойство<br />

BagsOfFeed вс<strong>е</strong>гда возвраща<strong>е</strong>т Ом<strong>е</strong>шков.<br />

Д<strong>е</strong>ло в том, что п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная F e e d M u ltip lie r н<strong>е</strong> была инициализирована. Поэтому она по<br />

умолчанию им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> ноль. Добавим инициализатор объ<strong>е</strong>кта:<br />

p u b l i c F o r m lО {<br />

I n it i a l iz e C o m p o n e n t ( );<br />

fa rm er = new F arm er{) { NumberOfCows = 15, f e e d M u l t i p l i e r = 3 0 };<br />

Т<strong>е</strong>п<strong>е</strong>рь программа н<strong>е</strong> компилиру<strong>е</strong>тся! Вот как выглядит сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>:<br />

Error List<br />

0 1 Error -li 0 Warnings {! i) 0 Messages<br />

’ O X<br />

Description File Line Column Project *<br />

0 1 'Cow_Cakulator.Farmer,feedMu{tiplier' is Forml.cs<br />

inaccessible due to its protection level<br />

18 56 Cow Calculator (N<br />

T<br />

Д<strong>е</strong>ло в том, что инициализатор объ<strong>е</strong>кта работа<strong>е</strong>т только с открытыми полями<br />

и свойствами. Что ж<strong>е</strong> д<strong>е</strong>лать, <strong>е</strong>сли тр<strong>е</strong>бу<strong>е</strong>тся инициализировать закрыты<strong>е</strong> поля?<br />

222 глава 5


инкапсуляция<br />

Конструктор<br />

Итак, вы уж<strong>е</strong> уб<strong>е</strong>дились, что с закрытыми полями инциализатор объ<strong>е</strong>ктов н<strong>е</strong><br />

работа<strong>е</strong>т. К счастью, сущ<strong>е</strong>ству<strong>е</strong>т особый м<strong>е</strong>тод, называ<strong>е</strong>мый конструктором<br />

(constructor). Это самый п<strong>е</strong>рвый м<strong>е</strong>тод, который выполня<strong>е</strong>тся при создании<br />

класса оп<strong>е</strong>ратором new. П<strong>е</strong>р<strong>е</strong>давая конструктору парам<strong>е</strong>тры, вы указыва<strong>е</strong>т<strong>е</strong><br />

знач<strong>е</strong>ния, которы<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся инициализировать. Но этот м<strong>е</strong>тод н<strong>е</strong> им<strong>е</strong><strong>е</strong>т<br />

возвраща<strong>е</strong>мого знач<strong>е</strong>ния, так как напрямую н<strong>е</strong> вызыва<strong>е</strong>тся. Парам<strong>е</strong>тр п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся<br />

оп<strong>е</strong>ратору new. А как вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, этот оп<strong>е</strong>ратор возвраща<strong>е</strong>т объ<strong>е</strong>кт,<br />

поэтому конструктору возвращать уж<strong>е</strong> нич<strong>е</strong>го н<strong>е</strong> нужно.<br />

Чтобы снабдить<br />

класс конструктором,<br />

добавьт<strong>е</strong> м<strong>е</strong>тод,<br />

им<strong>е</strong>ющий имя класса<br />

и н<strong>е</strong> им<strong>е</strong>ющий возвраща<strong>е</strong>мого<br />

знач<strong>е</strong>ния.<br />

Добавл<strong>е</strong>ни<strong>е</strong> конструктора к классу Farmer<br />

Тр<strong>е</strong>бу<strong>е</strong>тся добавить вс<strong>е</strong>го дв<strong>е</strong> строчки кода, но как много они значат. Как вы помнит<strong>е</strong>, в класс<strong>е</strong><br />

должны присутствовать данны<strong>е</strong> о колич<strong>е</strong>ств<strong>е</strong> коров и м<strong>е</strong>шков корма на одну корову Добавим эту<br />

информацию к конструктору в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тров. Для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной f e e d M u l t i p l i e r тр<strong>е</strong>бу<strong>е</strong>тся<br />

начально<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>, так как она бол<strong>е</strong><strong>е</strong> н<strong>е</strong> явля<strong>е</strong>тся константой.<br />

Отсутстви<strong>е</strong> посл<strong>е</strong> риЫ,с<br />

int или других обшвл<strong>е</strong>нии типа связано с т <strong>е</strong>м,<br />

^ цто конструктор н<strong>е</strong> возвраща<strong>е</strong>т знач<strong>е</strong>нии.<br />

Farmer(Int nxunberOfCows, int feedMultiplier)<br />

t h i s .feedMultiplier = feedMultiplier;<br />

Ключ<strong>е</strong>во<strong>е</strong> слово<br />

this в кон- public<br />

струкции this.<br />

feedMultiplier ^__<br />

указыва<strong>е</strong>т,<br />

что вы им<strong>е</strong><strong>е</strong>т<strong>е</strong> NuniberOfCows = numberOfCows;<br />

в виду пол<strong>е</strong>, ------ — V<br />

а н<strong>е</strong> одноим<strong>е</strong>н- } Запись в закрыто<strong>е</strong> пол<strong>е</strong> numberOfCows исключа<strong>е</strong>т<br />

ный парам<strong>е</strong>тр. дальн<strong>е</strong>йший вызов м<strong>е</strong>тода записи NumberOrCows.<br />

Данная ж<strong>е</strong> строка гарантиру<strong>е</strong>т <strong>е</strong>го вызов.<br />

{<br />

П<strong>е</strong>р<strong>е</strong>д вызовом<br />

м<strong>е</strong>тода запи -<br />

си NumberOfCows<br />

нужно за ­<br />

дать парам<strong>е</strong>тр<br />

reedMultiplier.<br />

Эт о сообщ<strong>е</strong>-, 2 Errors 0 Warnirtgs 0 Messages [ ^<br />

ниє об ошибк<strong>е</strong><br />

означа<strong>е</strong>т, что<br />

Description<br />

File<br />

Line Column Project<br />

оп<strong>е</strong>ратор new 0 1 'Cowr_CBkulator.Farme’does not contain Forml.cs 18 22 Cow Calcutetor<br />

н<strong>е</strong> им<strong>е</strong><strong>е</strong>т п а ­<br />

а constructor that takes § argument<br />

рам<strong>е</strong>тров.<br />

0 Настройки яюрмы, н<strong>е</strong>обходимы<strong>е</strong> для работы с конструктором<br />

Т<strong>е</strong>п<strong>е</strong>рь нужно сд<strong>е</strong>лать так, чтобы оп<strong>е</strong>ратор new , создающий объ<strong>е</strong>кт F a rm e r, использовал конструктор<br />

вм<strong>е</strong>сто инициализатора объ<strong>е</strong>кта. Посл<strong>е</strong> р<strong>е</strong>дактирования оп<strong>е</strong>ратора n e w сообщ<strong>е</strong>ния об<br />

ошибках исч<strong>е</strong>знут, и код начн<strong>е</strong>т компилироваться!<br />

public F o r m l О {<br />

I n i t i a l i z e C o m p o n e n t O ;<br />

farmer<br />

}<br />

= new F a r m e r (15, 30)<br />

^ ------------^ _______ ^<br />

М<strong>е</strong>тод new, вызывающий конструктор,<br />

отлича<strong>е</strong>тся наличи<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>дава<strong>е</strong>мых конст<br />

руктору парам<strong>е</strong>тров.<br />

Так как форма — это тож<strong>е</strong><br />

обь<strong>е</strong>кт, для н<strong>е</strong><strong>е</strong> опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>н<br />

конструктор с им<strong>е</strong>н<strong>е</strong>м Form l.<br />

обрат ит <strong>е</strong> внимани<strong>е</strong>, что он н<strong>е</strong><br />

возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>.<br />

дальш<strong>е</strong> > 223


разбира<strong>е</strong>м конструктор<br />

KoHCHlJ>ljKlIioJ>bi<br />

зіоД м и кроскопом<br />

К-онструкторы<br />

н<strong>е</strong> возвращают<br />

знач<strong>е</strong>ния.<br />

Внимат<strong>е</strong>льно рассмотрим конструктор Farmer, чтобы составить<br />

пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> о том, как он работа<strong>е</strong>т.<br />

Данный конструктор им<strong>е</strong><strong>е</strong>т два<br />

парам<strong>е</strong>тра: колич<strong>е</strong>ство коров<br />

и колич<strong>е</strong>ство корма на одну корову.<br />

public Farmer(int пглпЬ<strong>е</strong>гО£Cows, int<br />

NximberOfCows = nxnnberOf Cows ;<br />

V<br />

Чтобы отличить пол<strong>е</strong><br />

feedMultiplier от одноим<strong>е</strong>нного<br />

парам<strong>е</strong>тра, мы воспользовались<br />

словом this.<br />

feedMultiplier;<br />

feedMultiplier) {<br />

Так как второй оп<strong>е</strong>ратор<br />

вызыва<strong>е</strong>т м<strong>е</strong>тод записи<br />

NumberOfCows, для вычисл<strong>е</strong>ния<br />

парам<strong>е</strong>тра BagsOfFeed вам<br />

нужно знач<strong>е</strong>ни<strong>е</strong> feedMultiplier.<br />

Так как this означа<strong>е</strong>т ссылку на т<strong>е</strong>кущий одь<strong>е</strong>кт,<br />

запись this.feedMultiplier явля<strong>е</strong>тся ссылкой на пол<strong>е</strong>.<br />

Так что сначала мы присваива<strong>е</strong>м закрытому полю<br />

feedMultiplier второй парам<strong>е</strong>тр конструктора.<br />

• Бывают ли конструкторы б<strong>е</strong>з парам<strong>е</strong>тров?<br />

Q ; Да. Классы часто снабж<strong>е</strong>ны конструктором, н<strong>е</strong> им<strong>е</strong>ющим<br />

парам<strong>е</strong>тров. И вы уж<strong>е</strong> вид<strong>е</strong>ли прим<strong>е</strong>р — конструктор ваш<strong>е</strong>й<br />

формы. Посмотрит<strong>е</strong> на <strong>е</strong>го объявл<strong>е</strong>ни<strong>е</strong>:<br />

Ч а с зц о<br />

ЧаДаБа<strong>е</strong>Мы<strong>е</strong><br />

Б о Іїр о С ь і<br />

М<strong>е</strong>тод I n it ia liz e C o m p o n e n t ( ) вызыва<strong>е</strong>тся внутри<br />

конструктора формы, поэтому инициализация вс<strong>е</strong>х эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния происходит в мом<strong>е</strong>нт создания формы. (Помнит<strong>е</strong>, что<br />

вс<strong>е</strong> формы — н<strong>е</strong> бол<strong>е</strong><strong>е</strong> ч<strong>е</strong>м объ<strong>е</strong>кты, использующи<strong>е</strong> м<strong>е</strong>тоды .NET<br />

Frameworl< из пространства им<strong>е</strong>н S y s te m . W indow s. Forms<br />

для отображ<strong>е</strong>ния окон, кнопок и другох эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния.)<br />

p u b l i c F o r m lО {<br />

I n it ia liz e C o m p o n e n t О ;<br />

}<br />

Как видит<strong>е</strong>, конструктор формы д<strong>е</strong>йствит<strong>е</strong>льно н<strong>е</strong> им<strong>е</strong><strong>е</strong>т парам<strong>е</strong>тров.<br />

Откройт<strong>е</strong> файл F o rm l. D e s i g n e r . c s и найдит<strong>е</strong><br />

м<strong>е</strong>тод I n it ia liz e C o m p o n e n t (), щ<strong>е</strong>лкнув на значк<strong>е</strong> +<br />

рядом со строчкой «Windows Form Designer generated code».<br />

Этот м<strong>е</strong>тод зада<strong>е</strong>т н<strong>е</strong> только начальны<strong>е</strong> знач<strong>е</strong>ния вс<strong>е</strong>х эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния формы, но и их свойства. П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> на форму<br />

новый эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния, отр<strong>е</strong>дактируйт<strong>е</strong> <strong>е</strong>го свойства<br />

в окн<strong>е</strong> Properties и обратит<strong>е</strong> внимани<strong>е</strong> на изм<strong>е</strong>н<strong>е</strong>ния, которы<strong>е</strong><br />

произойдут с м<strong>е</strong>тодом I n it ia liz e C o m p o n e n t ().<br />

Как различать одноим <strong>е</strong>нны <strong>е</strong><br />

парам <strong>е</strong>тры и поля?<br />

qae<br />

о О р<br />

_<br />

о р<br />

J<br />

о Ж Н ь ї!<br />

Вы зам<strong>е</strong>тили, что парам<strong>е</strong>тр<br />

конструктора f e e d M u lt i p l i e r называ<strong>е</strong>тся<br />

так ж<strong>е</strong>, как вспомогат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong> свойства<br />

F e e d M u lt ip lie r ? Чтобы использовать в конструктор<strong>е</strong><br />

посл<strong>е</strong>дн<strong>е</strong><strong>е</strong>, н<strong>е</strong> забудьт<strong>е</strong> про ключ<strong>е</strong>во<strong>е</strong><br />

слово t h i s ; имя f e e d M u lt i p l i e r указыва<strong>е</strong>т на<br />

парам<strong>е</strong>тр, а запись t h i s . f e e d M u lt i p l i e r на доступ<br />

к закрытому полю.<br />

224 глава 5


Зач<strong>е</strong>м нужна проц<strong>е</strong>дура создания<br />

м<strong>е</strong>тодов чт<strong>е</strong>ния и записи? Поч<strong>е</strong>му<br />

н<strong>е</strong>льзя просто создать пол<strong>е</strong>?<br />

Ql Поля нужны для вычисл<strong>е</strong>ний или<br />

иных д<strong>е</strong>йствий. Вспомнит<strong>е</strong> о пробл<strong>е</strong>м<strong>е</strong><br />

Кэтлин — посл<strong>е</strong> указания колич<strong>е</strong>ства<br />

гост<strong>е</strong>й в класс<strong>е</strong> D in n e r P a r ty форма<br />

н<strong>е</strong> запускала м<strong>е</strong>тод, п<strong>е</strong>р<strong>е</strong>считывающий<br />

стоимость оформл<strong>е</strong>ния. Зам<strong>е</strong>нив пол<strong>е</strong><br />

на м<strong>е</strong>тод записи, мы гарантиру<strong>е</strong>м, что<br />

этот п<strong>е</strong>р<strong>е</strong>сч<strong>е</strong>т буд<strong>е</strong>т сд<strong>е</strong>лан. (Ч<strong>е</strong>р<strong>е</strong>з пару<br />

страниц вы уб<strong>е</strong>дит<strong>е</strong>сь в этом!)<br />

Ч<strong>е</strong>м ж<strong>е</strong> отличаются просто м<strong>е</strong>тоды<br />

от м<strong>е</strong>тодов чт<strong>е</strong>ния и записи?<br />

Q ; Нич<strong>е</strong>м! Это особы<strong>е</strong> виды м<strong>е</strong>тодов —<br />

для других объ<strong>е</strong>шв они выглядят как поля<br />

и вызываются при записи в пол<strong>е</strong>. М<strong>е</strong>тод<br />

чт<strong>е</strong>ния в кач<strong>е</strong>ств<strong>е</strong> знач<strong>е</strong>ния возвраща<strong>е</strong>т тип<br />

поля. А м<strong>е</strong>тод записи им<strong>е</strong><strong>е</strong>т только один<br />

парам<strong>е</strong>тр с им<strong>е</strong>н<strong>е</strong>м v a lu e , тип которого<br />

совпада<strong>е</strong>т с типом поля. Вм<strong>е</strong>сто фомоздких<br />

«м<strong>е</strong>тод чт<strong>е</strong>ния» и «м<strong>е</strong>тод записи» можно<br />

говорить просто — «свойства».<br />

_ Часзцо<br />

ЧаДаБа<strong>е</strong>Мы<strong>е</strong><br />

O<br />

BoTij>oc:i>i<br />

: 0# позволя<strong>е</strong>т н<strong>е</strong> писать информацию,<br />

которая н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся компилятору.<br />

Парам<strong>е</strong>тр объявля<strong>е</strong>тся б<strong>е</strong>з ваших явных<br />

указаний. Это н<strong>е</strong> им<strong>е</strong><strong>е</strong>т особого знач<strong>е</strong>ния,<br />

когда вы вводит<strong>е</strong> один или два оп<strong>е</strong>ратора,<br />

но <strong>е</strong>сли тр<strong>е</strong>бу<strong>е</strong>тся вв<strong>е</strong>сти сотню, подобный<br />

подход р<strong>е</strong>ально экономит вр<strong>е</strong>мя<br />

и ум<strong>е</strong>ньша<strong>е</strong>т колич<strong>е</strong>ство возможных<br />

ошибок.<br />

М<strong>е</strong>тод записи вс<strong>е</strong>гда им<strong>е</strong><strong>е</strong>т <strong>е</strong>динств<strong>е</strong>нный<br />

парам<strong>е</strong>тр v a lu e , тип которого<br />

вс<strong>е</strong>гда совпада<strong>е</strong>т с типом свойства. 0#<br />

получа<strong>е</strong>т всю н<strong>е</strong>обходимую информацию<br />

о тип<strong>е</strong> и парам<strong>е</strong>тр<strong>е</strong> в мом<strong>е</strong>нт, когда вы набрали<br />

“s e t Больш<strong>е</strong> нич<strong>е</strong>го набирать<br />

н<strong>е</strong> нужно.<br />

То <strong>е</strong>сть я могу н<strong>е</strong> добавлять в кон-<br />

( труктор возвраща<strong>е</strong>мо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>?<br />

^ ! Им<strong>е</strong>нно так! Конструктор н<strong>е</strong> им<strong>е</strong><strong>е</strong>т<br />

возвраща<strong>е</strong>мого знач<strong>е</strong>ния, так как принадл<strong>е</strong>жит<br />

к типу v o id . Было бы излишн<strong>е</strong><br />

заставлять вас набирать v o id в начал<strong>е</strong><br />

каждого конструктора.<br />

инкапсуляция<br />

Passw ord, в которо<strong>е</strong> други<strong>е</strong> шпионы<br />

могут только записывать информацию, но<br />

н<strong>е</strong> читать <strong>е</strong><strong>е</strong>:<br />

p u b l i c s t r i n g P a ssw o rd {<br />

s e t {<br />

}.<br />

i f (v a lu e == s e c r e tC o d e ) {<br />

name = "Herb J o n e s" ;<br />

}<br />

A как ж<strong>е</strong> с объ<strong>е</strong>ктами, которы<strong>е</strong> мы<br />

( оздавали, н<strong>е</strong> создав для них конструктор?<br />

Получа<strong>е</strong>тся, что он нуж<strong>е</strong>н дал<strong>е</strong>ко<br />

н<strong>е</strong> вс<strong>е</strong>гда?<br />

^ ! Н<strong>е</strong>т, это означа<strong>е</strong>т, что 0# автоматич<strong>е</strong>ски<br />

созда<strong>е</strong>т конструктор с нул<strong>е</strong>вым<br />

парам<strong>е</strong>тром, <strong>е</strong>сли вы н<strong>е</strong> д<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> этого.<br />

Вы мож<strong>е</strong>т<strong>е</strong> заставить пользоват<strong>е</strong>ля<br />

создать экз<strong>е</strong>мпляр ваш<strong>е</strong>го класса, чтобы<br />

воспользоваться конструктором.<br />

Получа<strong>е</strong>тся, что в свойство можно<br />

пр<strong>е</strong>вратить ЛЮБОЙ оп<strong>е</strong>ратор?<br />

; Вы полностью правы. Вс<strong>е</strong>, что можно<br />

р<strong>е</strong>ализовать при помощи м<strong>е</strong>тода, можно<br />

пр<strong>е</strong>вратить в свойство. Свойства могут<br />

вызывать м<strong>е</strong>тоды, получать доступ к полям<br />

и даж<strong>е</strong> создавать объ<strong>е</strong>кты и экз<strong>е</strong>мпляры.<br />

Но вс<strong>е</strong> эти функции р<strong>е</strong>ализуются<br />

только в мом<strong>е</strong>нт доступа к свойству,<br />

поэтому н<strong>е</strong> им<strong>е</strong><strong>е</strong>т смысла пр<strong>е</strong>вращать<br />

в свойства оп<strong>е</strong>раторы, н<strong>е</strong> им<strong>е</strong>ющи<strong>е</strong> отнош<strong>е</strong>ния<br />

к проц<strong>е</strong>дурам чт<strong>е</strong>ния или записи.<br />

Если м<strong>е</strong>тод записи им<strong>е</strong><strong>е</strong>т парам<strong>е</strong>тр<br />

v a lu e , поч<strong>е</strong>му этот парам<strong>е</strong>тр н<strong>е</strong> указан<br />

в скобках как i n t v a lu e , как это<br />

происходит с другими м<strong>е</strong>тодами?<br />

Могу ли я использовать только м<strong>е</strong>тод<br />

чт<strong>е</strong>ния или только м<strong>е</strong>тод записи?<br />

Q ; Кон<strong>е</strong>чно! Воспользовавшись свойством<br />

get б<strong>е</strong>з свойства set, вы получит<strong>е</strong><br />

свойство только для чт<strong>е</strong>ния. Наприм<strong>е</strong>р,<br />

класс S e c r e tA g e n t мож<strong>е</strong>т им<strong>е</strong>ть пол<strong>е</strong><br />

R e a d o n ly (только для чт<strong>е</strong>ния) для<br />

им<strong>е</strong>ни (name):<br />

s t r i n g name = "Dash M a rtin " ;<br />

p u b l i c s t r i n g Name {<br />

}<br />

g e t { r e t u r n name; }<br />

A <strong>е</strong>сли воспользоваться свойством<br />

set б<strong>е</strong>з свойства get, вспомогат<strong>е</strong>льно<strong>е</strong><br />

пол<strong>е</strong> буд<strong>е</strong>т доступно только для записи.<br />

Класс S e c r e tA g e n t созда<strong>е</strong>т свойство<br />

Свойства (м<strong>е</strong>тоды<br />

чт<strong>е</strong>ния и записи) —<br />

это особый вид м<strong>е</strong>тодов,<br />

запуска<strong>е</strong>мых<br />

при попытк<strong>е</strong> другого<br />

класса прочитать<br />

свойство или сд<strong>е</strong>лать<br />

запись в п<strong>е</strong>го.<br />

дальш<strong>е</strong> * 225


что в им<strong>е</strong>ни?<br />

r|Jo3bM H Вруку карандаш<br />

Форма использу<strong>е</strong>т экз<strong>е</strong>мпляр класса c a b l e B i l l (Сч<strong>е</strong>т за т<strong>е</strong>л<strong>е</strong>вид<strong>е</strong>ни<strong>е</strong>) с им<strong>е</strong>н<strong>е</strong>м th isM o n th<br />

(Этот м<strong>е</strong>сяц) и при нажатии кнопки вызыва<strong>е</strong>т м<strong>е</strong>тод G e tT h is M o n th sB ill () (Получить сч<strong>е</strong>т за<br />

этот м<strong>е</strong>сяц). Укажит<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной amountOwed (Сумма, которую я долж<strong>е</strong>н) посл<strong>е</strong> выполн<strong>е</strong>ния<br />

кода.<br />

c l a s s С а Ы <strong>е</strong> В Ш {<br />

p r i v a t e i n t r e n t a lF e e ;<br />

p u b l i c C a b l e B i l l ( i n t r e n t a lF e e ) {<br />

t h i s . r e n t a lF e e ^ r e n t a lF e e ;<br />

d is c o u n t = f a l s e ;<br />

}<br />

p r i v a t e i n t p a y P e rV ie w D isc o u n t;<br />

p r i v a t e b o o l d is c o u n t ;<br />

p u b l i c b o o l D is c o u n t {<br />

s e t {<br />

d is c o u n t = v a lu e ;<br />

i f (d is c o u n t)<br />

p a y P e rV ie w D isc o u n t = 2;<br />

e l s e<br />

p a y Pe rV i e wD i s c ou n t<br />

}<br />

}<br />

= 0;<br />

p u b l i c i n t C a lc u la te A m o u n t(in t payP erV iew M oviesO rdered) {<br />

r e tu r n (r e n ta lF e e - payP erV iew D iscount) * payPerVie\»M oviesOrdered;<br />

}<br />

1 . C a b le B i ll ja n u a r y = new C a b l e B i l l (4 );<br />

M e s sa g e B o x .S h o w (ja n u a r y .C a lc u la te A m o u n t( 7 ) . T o S t r i n g O );<br />

2 . C a b le B i ll fe b r u a r y = new C a b l e B i l l (7 );<br />

fe b r u a r y .p a y P e r V ie w D is c o u n t = 1;<br />

M e ssa g e B o x .S h o w (fe b r u a r y .C a lc u la te A m o u n t( 3 ) . T o S t r i n g O ) ;<br />

3 . C a b le B i ll m arch = new C a b l e B i l l (9 );<br />

m a r c h .D isc o u n t = t r u e ;<br />

M essa g eB o x .S h o w (m a r ch .C a lc u la teA m o u n t( 6 ) . T o S t r i n g O );<br />

Знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

amountOwed?<br />

Знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

amountOwed?<br />

Знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

amountOwed?<br />

226 глава 5


Часзцо<br />

'^ а д а В а <strong>е</strong> М ы <strong>е</strong><br />

БоП роС Ь!<br />

Поч<strong>е</strong>му им<strong>е</strong>на одних пол<strong>е</strong>й начинаются<br />

с прописной буквы, а других —<br />

со строчной? Это что-то означа<strong>е</strong>т?<br />

0 ; Да, означа<strong>е</strong>т. Для вас. Но н<strong>е</strong> для компилятора.<br />

С# вс<strong>е</strong> равно, каки<strong>е</strong> им<strong>е</strong>на вы выбира<strong>е</strong>т<strong>е</strong><br />

для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных. Выбор странных<br />

им<strong>е</strong>н затруднит чт<strong>е</strong>ни<strong>е</strong> кода в будущ<strong>е</strong>м. Вы<br />

мож<strong>е</strong>т<strong>е</strong> запутаться в одноим<strong>е</strong>нных п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных,<br />

вс<strong>е</strong> отличи<strong>е</strong> им<strong>е</strong>н которых заключа<strong>е</strong>тся<br />

в р<strong>е</strong>гистр<strong>е</strong> п<strong>е</strong>рвой буквы.<br />

в <strong>C#</strong> р<strong>е</strong>гистр им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>. Внутри<br />

одного м<strong>е</strong>тода можно им<strong>е</strong>ть дв<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

с им<strong>е</strong>нами P a r ty и p a r ty .<br />

Это н<strong>е</strong> пом<strong>е</strong>ша<strong>е</strong>т компиляции кода. Вот<br />

н<strong>е</strong>сколько сов<strong>е</strong>тов по выбору им<strong>е</strong>н для<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных, которы<strong>е</strong> упростят чт<strong>е</strong>ни<strong>е</strong><br />

программы в будущ<strong>е</strong>м.<br />

1. Им<strong>е</strong>на пол<strong>е</strong>й закрытого доступа должны<br />

начинаться со строчной буквы.<br />

2. Им<strong>е</strong>на свойств и пол<strong>е</strong>й общ<strong>е</strong>го доступа<br />

должны начинаться с прописной буквы.<br />

3. Им<strong>е</strong>на парам<strong>е</strong>тров м<strong>е</strong>тодов должны<br />

начинаться со строчной буквы.<br />

инкапсуляция<br />

4. В н<strong>е</strong>которых м<strong>е</strong>тодах, особ<strong>е</strong>нно это каса<strong>е</strong>тся<br />

конструкторов, им<strong>е</strong>на парам<strong>е</strong>тров<br />

совпадают с им<strong>е</strong>нами пол<strong>е</strong>й. В итог<strong>е</strong> парам<strong>е</strong>тр<br />

маскиру<strong>е</strong>т пол<strong>е</strong>, то <strong>е</strong>сть оп<strong>е</strong>раторы<br />

м<strong>е</strong>тодов, которы<strong>е</strong> используют это имя,<br />

ссылаются на парам<strong>е</strong>тр, а н<strong>е</strong> на пол<strong>е</strong>. Эта<br />

пробл<strong>е</strong>ма р<strong>е</strong>ша<strong>е</strong>тся при помощи ключ<strong>е</strong>вого<br />

слова th is, достаточно добавить<br />

<strong>е</strong>го к им<strong>е</strong>ни, и компилятор пойм<strong>е</strong>т, что вы<br />

им<strong>е</strong><strong>е</strong>т в виду пол<strong>е</strong>, а н<strong>е</strong> парам<strong>е</strong>тр.<br />

Код сод<strong>е</strong>ржит ошибки. Напишит<strong>е</strong>, в ч<strong>е</strong>м, по ваш<strong>е</strong>му мн<strong>е</strong>нию, они заключаются<br />

и как их исправить.<br />

c l a s s G um ballM achine {<br />

p r i v a t e i n t g u m b a lls;<br />

p r i v a t e i n t p r i c e ;<br />

p u b l i c i n t P r ic e<br />

■{<br />

g e t<br />

{<br />

r e t u r n p r i c e ;<br />

.p u b lic G u m b a llM a c h in e (in t g u m b a lls , i n t p r i c e<br />

g u m b a lls = t h i s . g u m b a lls ;<br />

p u b l i c s t r i n g D isp e n se O n e G u m b a ll(in t p r i c e , i n t c o i n s l n s e r t e d )<br />

{<br />

i f ( t h i s . c o i n s l n s e r t e d >= p r i c e ) { / / пров<strong>е</strong>рка поля<br />

} e l s e {<br />

}<br />

g u m b a lls -= 1;<br />

r e t u r n "Вот ваша ж <strong>е</strong>ват<strong>е</strong>льная р <strong>е</strong> зи н к а " ;<br />

r e t u r n "Сумма н <strong>е</strong> д о ст а т о ч н а " ;<br />

дальш<strong>е</strong> > 227


инкапсуляция пр<strong>е</strong>дотвраща<strong>е</strong>т ошибки<br />

^ ^ о з ь м и В руку карандаш<br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

1 . C a b le B i ll ja n u a r y = new C a b l e B i l l (4 );<br />

M essa g eB o x . Show {j a n u a r y . C a lcu la teA m o u n t (7) . T o S tr in g () )<br />

2 . C a b le B i ll fe b r u a r y = new C a b l e B i l l {7 );<br />

Вот каки<strong>е</strong> знач<strong>е</strong>ния должна им<strong>е</strong>ть п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная amountOwed<br />

посл<strong>е</strong> выполн<strong>е</strong>ния кода:<br />

Знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

amountOwed?<br />

fe b r u a r y . p a y P e rV ie w D isc o u n t = li-<br />

M essa g eB o x .S h o w C feb ru a ry -C a lcu la teA m o u n t (3) .T o S tr in g O<br />

3 . C a b le B i ll m arch = new C a b l e B i l l (9);<br />

m a r c h .D isc o u n t = t r u e ;<br />

M essa g eB o x .S h o w (m a r ch .C a lc u la teA m o u n t( 6 ) . T o S t r i n g O );<br />

Z 8<br />

Знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

amountOwed?<br />

н<strong>е</strong> компилиру<strong>е</strong>тся<br />

Знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

amountOwed?<br />

42.<br />

Возьми В руку карандаш<br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот каки<strong>е</strong> ошибки сод<strong>е</strong>ржит код:<br />

относится н<strong>е</strong> к полю, а к па-<br />

Р^м<strong>е</strong>трц конструктора. Эта строчка<br />

присваива<strong>е</strong>т ПАРАМЕТРУ знач<strong>е</strong>ни<strong>е</strong>, возвраща<strong>е</strong>мо<strong>е</strong><br />

м<strong>е</strong>тодом чт<strong>е</strong>ния Price кошп<br />

р ш <strong>е</strong>щ<strong>е</strong> даж<strong>е</strong> н<strong>е</strong> задан! Строчка c m Z m<br />

зам <strong>е</strong>нить имя парам<strong>е</strong>-<br />

^ р а конструктора на Price (с прош<strong>е</strong>ной<br />

p u b l i c G u m b a llM a c h in e (in t g u m b a lls ,<br />

{<br />

}<br />

g u m b a lls = t h i s . g u m b a lls ;<br />

p r i c e = P r ic e ;<br />

i n t<br />

Ключ<strong>е</strong>во<strong>е</strong> слобо у ,1s<br />

6 m o вр<strong>е</strong>мя как gumballs -<br />

это парам<strong>е</strong>тр.<br />

Эт от парам<strong>е</strong>тр м а -<br />

i > I скиру<strong>е</strong>т закрыто<strong>е</strong> пол<strong>е</strong><br />

Р<br />

Price, в то вр<strong>е</strong>мя как<br />

м<strong>е</strong>тод долж<strong>е</strong>н пров<strong>е</strong>рять<br />

знач<strong>е</strong>ни<strong>е</strong> вспомогат<strong>е</strong>льного<br />

поля price.<br />

p u b l i c s t r i n g D isp e n se O n e G u m b a ll(in t p r i c e , i n t c o i n s l n s e r t e d )<br />

{<br />

Ключ<strong>е</strong>во<strong>е</strong> слово this a h i s . c o i n s l n s e r t e d >= p r i c e ) { / / пров<strong>е</strong>рка поля<br />

н<strong>е</strong> им<strong>е</strong><strong>е</strong>т отнош<strong>е</strong>ния g u m b a lls - 1;<br />

к данному парам<strong>е</strong>тру. r e t u r n "Вот ваша ж <strong>е</strong>ват<strong>е</strong>льная р<strong>е</strong>зинка" ;<br />

Оно должно } e l s e {<br />

присутствовать<br />

рядом С парам<strong>е</strong>тром<br />

r e t u r n "Сумма н <strong>е</strong>достаточн а" ;<br />

price. ^ ‘<br />

228 глава 5


инкапсуляция<br />

н<strong>е</strong>нк<strong>е</strong><br />

Использу<strong>е</strong>м получ<strong>е</strong>нную информацию, чтобы заставить программу Кэтлин<br />

работать корр<strong>е</strong>ктно.<br />

Заставим сч<strong>е</strong>тчик Dinner Party считать правильно<br />

Исправить ошибку можно при условии, что м<strong>е</strong>тод C a l c u l a t e C o s t O f D e c o r a t i o n s <<br />

зыва<strong>е</strong>тся при каждом изм<strong>е</strong>н<strong>е</strong>нии парам<strong>е</strong>тра N u m b e r O fP e o p le .<br />

вы-<br />

NumberOfPeople 1 0 ;<br />

.CalculateCostOfDecorations()<br />

CmouMocM.t> оформл<strong>е</strong>ния должна п<strong>е</strong>р<strong>е</strong>счимывамься<br />

при каждом изм<strong>е</strong>н<strong>е</strong>нии<br />

колич<strong>е</strong>ства гост<strong>е</strong>й.<br />

'^'’<strong>е</strong>гРоХ^<br />

CalculateCostO возвраща<strong>е</strong>т $650 Заставив программу п<strong>е</strong>р<strong>е</strong>считывать<br />

стоимость оформл<strong>е</strong>ния при<br />

каждом изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства гост<strong>е</strong>й,<br />

мы гарантиру<strong>е</strong>м корр<strong>е</strong>ктную<br />

работу м<strong>е</strong>тода CalculateCostQ.<br />

Добавл<strong>е</strong>ни<strong>е</strong> свойств и конструкторо<br />

Нужно инкапсулировать класс D i n n e r P a r t y . Для начала сд<strong>е</strong>ла<strong>е</strong>м парам<strong>е</strong>тр N u m b e r C f-<br />

P eop le свойством, вызывающим м<strong>е</strong>тод C a l c u l a t e C o s t O f D e c o r a t i o n s О . Зат<strong>е</strong>м нужно<br />

добавить конструктор, гарантировав корр<strong>е</strong>ктную инициализацию экз<strong>е</strong>мпляра. И након<strong>е</strong>ц<br />

остан<strong>е</strong>тся заставить форму использовать этот конструктор.<br />

★<br />

★<br />

Создайт<strong>е</strong> свойство для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной N u m b e r O fP e o p le , снабж<strong>е</strong>нно<strong>е</strong> м<strong>е</strong>тодом записи,<br />

вызывающим м<strong>е</strong>тод C a l c u l a t e C o s t O f D e c o r a t i o n s ( ) . Вам потр<strong>е</strong>бу<strong>е</strong>тся вспомогат<strong>е</strong>льно<strong>е</strong><br />

пол<strong>е</strong> n u m b e r o f P e o p l e .<br />

М<strong>е</strong>тоду записи N u m b e r O fP e o p le потр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная, которую он буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>давать<br />

в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра м<strong>е</strong>тоду C a l c u l a t e C o s t O f D e c o r a t i o n s ( ) . Добавьт<strong>е</strong> закрыто<strong>е</strong><br />

пол<strong>е</strong> типа b o o l с им<strong>е</strong>н<strong>е</strong>м f a n c y D e c o r a t i o n s , запись в которо<strong>е</strong> осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

при каждом вызов<strong>е</strong> м<strong>е</strong>тода C a l c u l a t e C o s t O f D e c o r a t i o n s ( ) .<br />

★ Чтобы добавить конструктор, вам нужны три парам<strong>е</strong>тра: колич<strong>е</strong>ство гост<strong>е</strong>й. Healthy<br />

Option и Fancy Decorations. В мом<strong>е</strong>нт инициализации объ<strong>е</strong>кта D i n n e r P a r t y форма<br />

вызыва<strong>е</strong>т два м<strong>е</strong>тода, пом<strong>е</strong>стит<strong>е</strong> их в конструктор:<br />

★<br />

d i n n e r P a r t y . C a l c u l a t e C o s t O f D e c o r a t i o n s ( f a n c y B o x . C h e c k e d ) ;<br />

d i n n e r P a r t y . S e t H e a l t h y O p t i o n ( h e a l t h y B o x . C h e c k e d ) ;<br />

Вот как выглядит конструктор для формы. Вс<strong>е</strong> остально<strong>е</strong> оста<strong>е</strong>тся б<strong>е</strong>з изм<strong>е</strong>н<strong>е</strong>ний:<br />

p u b l i c F o r m lО {<br />

I n it ia liz e C o m p o n e n t O ;<br />

d in n e r P a r ty = new D in n e r P a r t y ( (in t)n u m e r ic U p D o w n l.V a lu e ,<br />

h e a lth y B o x .C h e c k e d , fa n c y B o x .C h e c k e d );<br />

}<br />

D is p la y D in n e r P a r t y C o s t 0 ;<br />

дальш<strong>е</strong> > 229


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

Итак, вот как нужно было написать программу для расч<strong>е</strong>та стоимости<br />

м<strong>е</strong>роприятий:<br />

c l a s s D in n e r P a r ty {<br />

c o n s t i n t C o stO fF o o d P erP erso n = 25;<br />

p r i v a t e i n t n u m b ero fP eo p le;<br />

p u b l i c i n t Num berO fPeople {<br />

g e t<br />

s e t<br />

r e t u r n n u m berO fP eop le; }<br />

}<br />

n u m b ero fP eo p le = v a lu e ;<br />

C a lc u la te C o s tO fD e c o r a t i o n s (fa n c y D e c o r a t i o n s )<br />

p r i v a t e b o o l f a n c y D e c o r a t io n s ;<br />

p u b l i c d e c im a l C o stO fB e v e r a g e sP e r P e r so n ;<br />

p u b l i c d e c im a l C o s tO fD e c o r a tio n s = 0;<br />

Посл<strong>е</strong> закрытия поля<br />

num berof People форма н<strong>е</strong> мож<strong>е</strong>т<br />

вносить 6 н<strong>е</strong>го изм<strong>е</strong>н<strong>е</strong>ния до п<strong>е</strong>р<strong>е</strong>сч<strong>е</strong>та<br />

стоимости оформл<strong>е</strong>ния.<br />

Оилидка, которая чуть н<strong>е</strong> стоила<br />

К э тл и н <strong>е</strong><strong>е</strong> лучш<strong>е</strong>го кли<strong>е</strong>нта, ису^равл<strong>е</strong>на!<br />

i<br />

При помои^и свойства вы га-<br />

Р ^ ‘^иру<strong>е</strong>т <strong>е</strong>, что стоимость<br />

оформл<strong>е</strong>ния п<strong>е</strong>р<strong>е</strong>считыва<strong>е</strong>тся<br />

при каждом изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства<br />

гост<strong>е</strong>й.<br />

p u b l i c D in n e r P a r t y {i n t n u m berO fP eop le, b o o l h e a lt h y O p t io n , b o o l f a n c y D e c o r a tio n s )<br />

N um berO fPeople = n u m b erO fP eo p le;<br />

t h i s . fa n c y D e c o r a t io n s = f a n c y D e co r a t i o n s ; ^ будьт<strong>е</strong> внимат<strong>е</strong>льны c КЛЮ-<br />

S e t H e a lt h y O p t io n ( h e a lt h y O p t io n ) ; О ч<strong>е</strong>вым " словом this. Им <strong>е</strong>нно<br />

C a lc u la t e C o s t O f D e c o r a t io n s ( f a n c y D e c o r a t io n s ) ;<br />

оно помож<strong>е</strong>т различить<br />

}<br />

парам<strong>е</strong>тр и закрыто<strong>е</strong> пол<strong>е</strong><br />

numberOrPeople.<br />

p u b l i c v o i d S e t H e a lth y O p tio n (b o o l h e a lth y O p tio n ) {<br />

i f (h e a lth y O p tio n ) {<br />

\<br />

C o s tO fB e v e r a g e sP e r P e r so n = 5.00M;<br />

П<strong>е</strong>р<strong>е</strong>д fancyDecorations<br />

} e l s e {<br />

нужно пом<strong>е</strong>стить клю ­<br />

C o s tO fB e v e r a g e sP e r P e r so n = 20.00M;<br />

ч<strong>е</strong>во<strong>е</strong> слово tkis.j чтобы<br />

}<br />

отличить названи<strong>е</strong> за ­<br />

}<br />

крытого поля от названия<br />

p u b l i c v o i d C a lc u la t e C o s t O fD e c o r a tio n s ( b o o l fa n c y ) {<br />

парам<strong>е</strong>тра.<br />

f a n c y D e c o r a t io n s = fa n c y ;<br />

_____________<br />

_________ Информация об особом<br />

оформл<strong>е</strong>нии<br />

i f (fa n c y ) { ^<br />

C o s tO fD e c o r a tio n s = (Num berO fPeople 15.00М) + 50М;<br />

должна храниться<br />

} e l s e {<br />

в пол<strong>е</strong>, чтобы <strong>е</strong>ю<br />

C o s tO fD e c o r a tio n s = (Num berO fPeople 7.50М) + ЗОМ;<br />

смог воспользоваться<br />

м<strong>е</strong>тод записи<br />

}<br />

}<br />

NumberOfPeople.<br />

p u b l i c d e c im a l C a lc u la t e C o s t ( b o o l h e a lth y O p tio n ) {<br />

d e c im a l t o t a l C o s t = C o s tO fD e c o r a tio n s<br />

+ ( (C o stO fB e v e r a g e sP e r P e r so n + C o stO fF o o d P erP erso n ) * N u m b erO fP eo p le);<br />

i f (h e a lth y O p tio n ) {<br />

r e t u r n t o t a l C o s t ■<br />

} e l s e {<br />

r e t u r n t o t a l C o s t ;<br />

}<br />

.95M;<br />

230 глава 5


6 н а с Л <strong>е</strong> Д ‘^ ® а н и <strong>е</strong><br />

Г<strong>е</strong>н<strong>е</strong>алогич<strong>е</strong>ско<strong>е</strong> др<strong>е</strong>во<br />

объ<strong>е</strong>ктов<br />

Входя в крутой поворот, я вдруг<br />

понял, что унасл<strong>е</strong>довал свой<br />

в<strong>е</strong>лосип<strong>е</strong>д от Двухкол<strong>е</strong>сного,<br />

но забыл добавить м<strong>е</strong>тод Тормоза()...<br />

В итог<strong>е</strong> двадцать ш<strong>е</strong>сть и<br />

и лиш<strong>е</strong>ни<strong>е</strong> прогулок на ц<strong>е</strong>лый<br />

м<strong>е</strong>сяц.<br />

Иногда люди хотят быть похожим но своих родит<strong>е</strong>л<strong>е</strong>й.<br />

Вы встр<strong>е</strong>чали объ<strong>е</strong>кт, который д<strong>е</strong>йству<strong>е</strong>т почти так, как нужно? Думали ли<br />

вы о том, како<strong>е</strong> сов<strong>е</strong>рш<strong>е</strong>нство можно было бы получить, изм<strong>е</strong>нив вс<strong>е</strong>го<br />

н<strong>е</strong>сколько эл<strong>е</strong>м<strong>е</strong>нтов? Им<strong>е</strong>нно по этой причин<strong>е</strong> насл<strong>е</strong>довани<strong>е</strong> явля<strong>е</strong>тся<br />

одним из самых мощных инструм<strong>е</strong>нтов с#. В этой глав<strong>е</strong> вы узна<strong>е</strong>т<strong>е</strong>, как<br />

производный класс повторя<strong>е</strong>т пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> родит<strong>е</strong>льского, сохраняя при<br />

этом гибкость р<strong>е</strong>дактирования. Вы научит<strong>е</strong>сь изб<strong>е</strong>гать дублирования<br />

кода и обл<strong>е</strong>гчит<strong>е</strong> посл<strong>е</strong>дующ<strong>е</strong><strong>е</strong> р<strong>е</strong>дактировани<strong>е</strong> своих программ.


с дн<strong>е</strong>м рожд<strong>е</strong>ния, крошка<br />

Организация дн<strong>е</strong>й ро)кд<strong>е</strong>ния — э то то}к<strong>е</strong> работа Кэтлин<br />

Созданная нами программа работа<strong>е</strong>т, и Кэтлин с н<strong>е</strong>й н<strong>е</strong> расста<strong>е</strong>тся.<br />

Т<strong>е</strong>п<strong>е</strong>рь она организу<strong>е</strong>т н<strong>е</strong> только званы<strong>е</strong> об<strong>е</strong>ды, но<br />

и дни рожд<strong>е</strong>ния, а их стоимость рассчитыва<strong>е</strong>тся по другой<br />

сх<strong>е</strong>м<strong>е</strong>. Эту сх<strong>е</strong>му хот<strong>е</strong>лось бы добавить в программу.<br />

------<br />

Ваша программа смож<strong>е</strong>т<br />

посчитать стоимость дня<br />

рожд<strong>е</strong>ния?<br />

Эти пункты<br />

остались б<strong>е</strong>з<br />

изм<strong>е</strong>н<strong>е</strong>ний.<br />

О и<strong>е</strong>нка стоим ости дн<strong>е</strong>й рожд<strong>е</strong>ния<br />

• За каждого гостя оплата $25.<br />

• Обычно<strong>е</strong> оформл<strong>е</strong>ни<strong>е</strong> стоит $7.50 на ч<strong>е</strong>лов<strong>е</strong>ка плюс<br />

п<strong>е</strong>рвоначальный взнос $30. Стоимость особого оформл<strong>е</strong>ния<br />

ув<strong>е</strong>личива<strong>е</strong>тся до $15 на ч<strong>е</strong>лов<strong>е</strong>ка, а п<strong>е</strong>рвоначальный<br />

взнос — $50.<br />

• Если участников м<strong>е</strong>ньш<strong>е</strong> ч<strong>е</strong>тыр<strong>е</strong>х, готовим (8-дюймовый)<br />

торт ($40), бол<strong>е</strong><strong>е</strong> ч<strong>е</strong>тыр<strong>е</strong>х — (16-дюймовый) торт<br />

($75).<br />

• Надпись на торт<strong>е</strong> по $.25 за букву. На п<strong>е</strong>рвом торт<strong>е</strong> по-<br />

^ м<strong>е</strong>ша<strong>е</strong>тся до 16 букв, на втором — до 40.<br />

Прилож<strong>е</strong>ни<strong>е</strong> должно рассчитывать стоимость в<strong>е</strong>ч<strong>е</strong>ринок<br />

обоих типов. Каждую форму расч<strong>е</strong>та нужно пом<strong>е</strong>стить на<br />

свою вкладку.<br />

232 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Нам ну)к<strong>е</strong>н класс BirthdayParty<br />

Чтобы программа получила возможность рассчитывать<br />

стоимость в<strong>е</strong>ч<strong>е</strong>ринок другого типа, нам нужно<br />

пом<strong>е</strong>нять форму.<br />

Вы займ<strong>е</strong>т<strong>е</strong>сь<br />

этим оплим ч<strong>е</strong>р<strong>е</strong>з минуту, м у<br />

Вот как мы это буд<strong>е</strong>м д<strong>е</strong>лать:<br />

^ а пока пр<strong>е</strong>дст авим<br />

о6иА,ую картину.<br />

О<br />

Создани<strong>е</strong> класса BirthdayParty<br />

Новый класс буд<strong>е</strong>т подсчитывать стоимость, исходя из<br />

выбранного варианта оформл<strong>е</strong>ния, а такж<strong>е</strong> колич<strong>е</strong>ства<br />

букв на торт<strong>е</strong>.<br />

Добавл<strong>е</strong>ни<strong>е</strong> к форм<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нта TabControl<br />

Работать с вкладками просто. Выб<strong>е</strong>рит<strong>е</strong> нужную и п<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong><br />

на н<strong>е</strong><strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния.<br />

BirthdayParty<br />

NumberOfPeople<br />

CostOroecorations<br />

CakeSize<br />

CakeWriting<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

О П<strong>е</strong>р<strong>е</strong>таскивани<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния Dinner Party на п<strong>е</strong>рвую<br />

вкладку<br />

Посл<strong>е</strong> этого они будут работать точно так ж<strong>е</strong>, как и раньш<strong>е</strong>, просто чтобы<br />

их увид<strong>е</strong>ть, потр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>йти на нужную вкладку.<br />

О Добавл<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния Birthday Party на вторую<br />

вкладку<br />

Вы выб<strong>е</strong>р<strong>е</strong>т<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс для расч<strong>е</strong>та стоимости дн<strong>е</strong>й рожд<strong>е</strong>ния так ж<strong>е</strong>,<br />

как создавали в сво<strong>е</strong> вр<strong>е</strong>мя инт<strong>е</strong>рф<strong>е</strong>йс для расч<strong>е</strong>та стоимости званых об<strong>е</strong>дов.<br />

О Связывани<strong>е</strong> нового класса с эл<strong>е</strong>м<strong>е</strong>нтами управл<strong>е</strong>ния<br />

Вам потр<strong>е</strong>бу<strong>е</strong>тся добавить ссылку B ir th d a y P a rty на поля формы и код<br />

для новых эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния.<br />

_ Чаап°<br />

Поч<strong>е</strong>му н<strong>е</strong>льзя просто создать экз<strong>е</strong>мпляр DinnerParty,<br />

как это д<strong>е</strong>лал Майк, когда <strong>е</strong>му потр<strong>е</strong>бовалось сравнить три<br />

маршрута?<br />

^ ! Потому что новый экз<strong>е</strong>мпляр класса D in n e r P a r ty годится<br />

только для расч<strong>е</strong>та стоимости званых об<strong>е</strong>дов. Два экз<strong>е</strong>мпляра одного<br />

класса пол<strong>е</strong>зны, когда тр<strong>е</strong>бу<strong>е</strong>тся работать с данными одного типа.<br />

Но для хран<strong>е</strong>ния других данных, вам потр<strong>е</strong>бу<strong>е</strong>тся другой класс.<br />

О<br />

что ж<strong>е</strong> мн<strong>е</strong> пом<strong>е</strong>стить в этот новый класс?<br />

П<strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м как приступить к созданию класса, нужно понять,<br />

какую пробл<strong>е</strong>му он буд<strong>е</strong>т р<strong>е</strong>шать. В данном случа<strong>е</strong> вы должны<br />

поговорить с Кэтлин, в<strong>е</strong>дь это она буд<strong>е</strong>т пользоваться программой.<br />

Впроч<strong>е</strong>м, у вас <strong>е</strong>сть <strong>е</strong><strong>е</strong> зам<strong>е</strong>тки! Опр<strong>е</strong>д<strong>е</strong>лить поля, м<strong>е</strong>тоды<br />

и свойства класса можно, продумав <strong>е</strong>го пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> (что он долж<strong>е</strong>н<br />

д<strong>е</strong>лать) и <strong>е</strong>го состояни<strong>е</strong> (что он долж<strong>е</strong>н знать).<br />

дальш<strong>е</strong> > 233


другой тип в<strong>е</strong>ч<strong>е</strong>ринок<br />

Планиробщик м<strong>е</strong>роприятий, б<strong>е</strong>рсия 2.0<br />

Начнит<strong>е</strong> новый про<strong>е</strong>кт, мы сд<strong>е</strong>ла<strong>е</strong>м для Кэтлин в<strong>е</strong>рсию программы,<br />

которая смож<strong>е</strong>т рассчитать стоимость дн<strong>е</strong>й рожд<strong>е</strong>ния и званых об<strong>е</strong>дов.<br />

Начн<strong>е</strong>м с инкапсулированного класса B i r t h d a y P a r t y , который<br />

и буд<strong>е</strong>т выполнять вс<strong>е</strong> расч<strong>е</strong>ты.<br />

-ажн<strong>е</strong>ни<strong>е</strong>!<br />

Новый класс BirthdayParty<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что нужно д<strong>е</strong>лать со свойством N u m b e rO f­<br />

P e o p l e и м<strong>е</strong>тодом C o s t O f D e c o r a t i o n s , вы с ними встр<strong>е</strong>чались<br />

в класс<strong>е</strong> D i n n e r P a r t y . Добавим в новый класс сначала их.<br />

★<br />

c l a s s B ir th d a y P a r ty {<br />

Добавьт<strong>е</strong> пол<strong>е</strong> общ<strong>е</strong>го доступа типа int с им<strong>е</strong>н<strong>е</strong>м<br />

C a k e S iz e (Разм<strong>е</strong>р торта). Потом вы добавит<strong>е</strong> закрытый<br />

м<strong>е</strong>тод C a l c u l a t e C a k e S i z e () (Вычислить разм<strong>е</strong>р<br />

торта), присваивающий полю C a k e S iz e знач<strong>е</strong>ни<strong>е</strong> 8 или<br />

16 в зависимости от колич<strong>е</strong>ства гост<strong>е</strong>й. Но начн<strong>е</strong>м мы<br />

с конструктора и м<strong>е</strong>тода записи N u m b e r O fP e o p le .<br />

p u b l i c c o n s t i n t C o stO fF o o d P erP erso n = 25;<br />

p u b l i c d e c im a l C o s tO fD e c o r a tio n s = 0;<br />

p r i v a t e b o o l f a n c y D e c o r a t io n s ;<br />

p u b l i c i n t C a k eS ize;<br />

p u b l i c B ir t h d a y P a r t y ( in t nu m berO fP eop le,<br />

Уб<strong>е</strong>дит<strong>е</strong>сь в наличии оп<strong>е</strong>ратора using<br />

в в<strong>е</strong>рхн<strong>е</strong>й части класса, так как вам п о ­<br />

тр<strong>е</strong>бу<strong>е</strong>тся м<strong>е</strong>тод MessageBox. ShowQ.<br />

b o o l f a n c y D e c o r a t io n s , s t r i n g c a k e W ritin g )<br />

Поля и свойства, сод<strong>е</strong>ржащи<strong>е</strong><br />

информацию<br />

о д<strong>е</strong>н<strong>е</strong>жных<br />

суммах, должны<br />

^принадл<strong>е</strong>жать типу<br />

decimal.<br />

BirthdayParty<br />

NumberOfPeople<br />

CostOfDecorations<br />

CakeSize<br />

CakeWriting<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

Для инициализации объ<strong>е</strong>кта<br />

BirthdayParty н<strong>е</strong>обходимы данны<strong>е</strong><br />

о колич<strong>е</strong>ств<strong>е</strong> гост<strong>е</strong>й, вид<strong>е</strong><br />

оформл<strong>е</strong>ния и надписи на торт<strong>е</strong>.<br />

^ В этом случа<strong>е</strong> при вызов<strong>е</strong> м<strong>е</strong>тода<br />

/ CalculateCostO стоимость буд<strong>е</strong>т<br />

/ правильно рассчитана.<br />

th is.n u m b e r O fP e o p le = n u m b erO fP eo p le;<br />

t h i s . fa n c y D e c o r a t io n s = f a n c y D e c o r a t io n s ;<br />

C a lc u la t e C a k e S iz e ( );<br />

t h i s . C a k eW ritin g = c a k e W r itin g ;<br />

C a lc u la t e C o s t O f D e c o r a t io n s ( f a n c y D e c o r a t io n s ) ;<br />

Для подсч<strong>е</strong>та стоимости<br />

надписи на торт<strong>е</strong> конструктор<br />

вызыва<strong>е</strong>т м<strong>е</strong>тод записи.<br />

Чтобы понять, н<strong>е</strong> явля<strong>е</strong>тся ли<br />

эт от парам<strong>е</strong>тр слиилком<br />

большим, сначала нужно у з ­<br />

нать разм<strong>е</strong>р торта.<br />

Конст рукт ор зада<strong>е</strong>т свойства,<br />

а зат<strong>е</strong>м начина<strong>е</strong>т вычисл<strong>е</strong>ния.<br />

234 глава 6


★<br />

Для хран<strong>е</strong>ния информации о надписи на торт<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся свойство<br />

C a k e W r it in g типа string. Этот м<strong>е</strong>тод записи пров<strong>е</strong>ря<strong>е</strong>т парам<strong>е</strong>тр<br />

C a k e S iz e , так как максимально<strong>е</strong> колич<strong>е</strong>ство букв зависит от<br />

разм<strong>е</strong>ра торта. Зат<strong>е</strong>м при помощи м<strong>е</strong>тода v a l u e . L e n g t h пров<strong>е</strong>ря<strong>е</strong>тся<br />

длина строки. Если строка оказыва<strong>е</strong>тся слишком длинной, м<strong>е</strong>тод<br />

записи вызыва<strong>е</strong>т окно с т<strong>е</strong>кстом, «Слитком много букв для 16-дюймового<br />

торта» (или 8-дюймового).<br />

★ Кром<strong>е</strong> того, вам потр<strong>е</strong>бу<strong>е</strong>тся м<strong>е</strong>тод C a l c u l a t e C a k e S i z e ():<br />

p r i v a t e v o idi d C a lc u la t e C a k e S iz e ()<br />

}<br />

(Numbc^^w.^,.<br />

r’o’b-caC-i ryea —Q.<br />

i f (Num berO fPeople


кэтлин это понравится<br />

Продолжим работу над классом BirthdayParty.<br />

Зав<strong>е</strong>ршим создани<strong>е</strong> класса B irth d a y P a rty , добавив м<strong>е</strong>тод C a lc u la te C o s tO . Но<br />

<strong>е</strong>сли в класс<strong>е</strong> D in n e rP a rty вы брали стоимость оформл<strong>е</strong>ния и прибавляли к н<strong>е</strong>му<br />

стоимость напитков, т<strong>е</strong>п<strong>е</strong>рь нужно буд<strong>е</strong>т добавить <strong>е</strong>щ<strong>е</strong> и стоимость торта.<br />

Тип decimal выбран, плак как<br />

мы работа<strong>е</strong>м с д<strong>е</strong>ньгами.<br />

p u b l i c d e c im a l C a lc u la t e C o s t O {<br />

}<br />

d e c im a l T o ta lC o s t = C o s tO fD e c o r a tio n s<br />

d e c im a l C akeC ost;<br />

i f (C a k eS ize == 8)<br />

e l s e<br />

C akeC ost = 40M + C a k e W r itin g .L e n g th *<br />

C akeC ost = 75M<br />

r e t u r n T o ta lC o s t +<br />

+ C a k e W r itin g .L e n g th<br />

C ak eC ost;<br />

+ (C o stO fF o o d P erP erso n * N u m b erO fP eo p le);<br />

.25M;<br />

.25М;<br />

8 данном случа<strong>е</strong> м<strong>е</strong>тод<br />

CalculateCostQ вм<strong>е</strong>сто<br />

стоимости напитков<br />

прибавля<strong>е</strong>т стоимость<br />

торта.<br />

p r i v a t e i n t num berO fP eople;<br />

p u b l i c i n t N um berO fPeople {<br />

g e t { r e t u r n n u m berO fP eop le; } ^<br />

s e t {<br />

num berO fP eople = v a lu e ;<br />

C a lc u la t e C o s t O f D e c o r a t io n s ( f a n c y D e c o r a t io n s ) ;<br />

C a lc u la t e C a k e S iz e ( );<br />

th is - C a k e W r it in g - c a k e W r it in g ;<br />

^<br />

Подобный м<strong>е</strong>тод вы уж<strong>е</strong><br />

} использовали в класс<strong>е</strong><br />

DinnerParty.<br />

p u b l i c v o i d C a lc u la t e C o s t O fD e c o r a tio n s ( b o o l fa n c y ) {<br />

}<br />

fa n c y D e c o r a t io n s = fa n c y ;<br />

i f (fa n c y )<br />

e l s e<br />

C o s tO fD e c o r a tio n s = (Num berO fPeople * 15.00M) + SOM;<br />

C o s tO fD e c o r a tio n s = (Num berO fPeople * 7 .SOM) + 30M;<br />

^<br />

М<strong>е</strong>тод Сак<strong>е</strong>^гШ пд долж<strong>е</strong>н н<strong>е</strong><br />

только обр<strong>е</strong>зать строку, но<br />

и запускать м<strong>е</strong>тод записи п^и<br />

изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства гост<strong>е</strong>й.<br />

\<br />

При изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства<br />

гост<strong>е</strong>й класс<br />

сначала п<strong>е</strong>р<strong>е</strong>считыва<strong>е</strong>т<br />

разм<strong>е</strong>р торта и, используя<br />

м<strong>е</strong>тод записи,<br />

заставля<strong>е</strong>т м<strong>е</strong>тод<br />

CakeWriting обр<strong>е</strong>зать<br />

т<strong>е</strong>кст.<br />

236 глава 6<br />

%


насл<strong>е</strong>довани<strong>е</strong><br />

© Эл<strong>е</strong>м<strong>е</strong>нт упраал<strong>е</strong>ния TabControl<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> на форму эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния T abC ontrol<br />

и изм<strong>е</strong>нит<strong>е</strong> <strong>е</strong>го разм<strong>е</strong>р. Изм<strong>е</strong>нит<strong>е</strong> названи<strong>е</strong> каждой вкладки<br />

с помощью свойства TabPages. Р<strong>е</strong>дактировани<strong>е</strong> свойств<br />

каждой вкладки осущ<strong>е</strong>ствля<strong>е</strong>тся в отд<strong>е</strong>льном окн<strong>е</strong> диалога.<br />

При помощи свойства T ex t присвойт<strong>е</strong> вкладкам им<strong>е</strong>на<br />

Dinner Party и Birthday Party соотв<strong>е</strong>тств<strong>е</strong>нно.<br />

О Вставка эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния на вкладку Dinner<br />

Party<br />

Откройт<strong>е</strong> программу Party Planner (из главы 5) в отд<strong>е</strong>льном<br />

окн<strong>е</strong> ИСР. Выд<strong>е</strong>лит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния, скопируйт<strong>е</strong><br />

и вставьт<strong>е</strong> на вкладку Dinner Party. Щ<strong>е</strong>лкнит<strong>е</strong> внутри<br />

вкладки, чтобы гарантировать правильно<strong>е</strong> разм<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нтов (в противном случа<strong>е</strong> вы увидит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong><br />

о н<strong>е</strong>возможности добавить компон<strong>е</strong>нты в конт<strong>е</strong>йн<strong>е</strong>р типа<br />

T abC ontrol).<br />

Таким способом вы добавит<strong>е</strong> только эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния,<br />

а н<strong>е</strong> связанны<strong>е</strong> с ними обработчики событий. Нужно такж<strong>е</strong><br />

пров<strong>е</strong>рить свойство (Name) в окн<strong>е</strong> Properties для каждого<br />

эл<strong>е</strong>м<strong>е</strong>нта. Уб<strong>е</strong>дит<strong>е</strong>сь, что вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния<br />

сохранили им<strong>е</strong>на, а такж<strong>е</strong> произв<strong>е</strong>дит<strong>е</strong> двойной щ<strong>е</strong>лчок<br />

на каждом из них, чтобы добавить пустой обработчик событий.<br />

Д ды т<strong>е</strong> вкладкам<br />

названия при noMouju<br />

свойсплва TabCollection.<br />

Party banner 2 О<br />

Dinner Party ; Birthday PartTj ^ - ^<br />

Number of People<br />

[5 Щ<br />

ІУІ Fancy Decorations<br />

lII Healthy Option<br />

Cost i*<br />

/<br />

Эти эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния<br />

доступны только на окладк<strong>е</strong><br />

Dinner Party.<br />

^<br />

N<br />

Пользоват<strong>е</strong>льский инт<strong>е</strong>рц)<strong>е</strong>йс для вкладки Birtliday Party<br />

На вкладк<strong>е</strong> Birthday Party должны присутствовать эл<strong>е</strong>м<strong>е</strong>нт NumericUpDown для колич<strong>е</strong>ства<br />

гост<strong>е</strong>й, эл<strong>е</strong>м<strong>е</strong>нт CheckBox для особого оформл<strong>е</strong>ния и эл<strong>е</strong>м<strong>е</strong>нт L abel с тр<strong>е</strong>хм<strong>е</strong>рной рамкой<br />

для итоговой суммы. Кром<strong>е</strong> того, потр<strong>е</strong>бу<strong>е</strong>тся эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния TextBox для ввода надписи<br />

на торт<strong>е</strong>.<br />

ЭИ.<br />

■i* Party Planner 2.0<br />

anner Party<br />

Number cf People<br />

iv<br />

Birthday Party.<br />

4» | 2 ! Fmcy Decorations<br />

Cake W i№ g<br />

Happy Birthday<br />

$<br />

J<br />

П<strong>е</strong>р<strong>е</strong>йдит<strong>е</strong> на вкладку<br />

Birthday Party и добавьт<strong>е</strong><br />

новы<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния.<br />

Добавьт<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

TextBox с им<strong>е</strong>н<strong>е</strong>м<br />

cai


закончим создани<strong>е</strong> формы<br />

Продолжим работу над формой...<br />

О Со<strong>е</strong>диня<strong>е</strong>м вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong><br />

Вс<strong>е</strong> отд<strong>е</strong>льны<strong>е</strong> части уж<strong>е</strong> готовы, осталось только написать код, который заставит форму работать.<br />

★<br />

★<br />

Вам потр<strong>е</strong>буются поля со ссылками на объ<strong>е</strong>кты B i r t h d a y P a r t y и D i n n e r P a r t y , которым<br />

будут присво<strong>е</strong>ны начальны<strong>е</strong> знач<strong>е</strong>ния при помощи конструктора.<br />

Код для обработчиков событий, связанных с различными эл<strong>е</strong>м<strong>е</strong>нтами управл<strong>е</strong>ния<br />

с вкладки Dinner Party, возьмит<strong>е</strong> из главы 5. Вот как долж<strong>е</strong>н выгляд<strong>е</strong>ть код для формы:<br />

Связанный с формой конструктор приp<br />

u b l i c p a r t i a l c l a s s Form l : Form { сваива<strong>е</strong>т экз<strong>е</strong>мпляру BirthdayParty н а -<br />

D in n e r P a r ty d in n e r P a r ty ;<br />

чальны<strong>е</strong> знач<strong>е</strong>ния подобно тому, как это<br />

5ьіло сд<strong>е</strong>лано для экз<strong>е</strong>мпляра Dinnerparty.<br />

B ir th d a y P a r ty b ir t h d a y P a r t y ;<br />

p u b lic F o r m lО {<br />

I n it i a l iz e C o m p o n e n t () ;<br />

М /<br />

d in n e r P a r t y = new D in n e r P a r t y ( ( i n t ) num ericU pDow nl’. V a lu e ,<br />

D is p la y D in n e r P a r t y C o s t 0 ;<br />

h e a lth y B o x .C h e c k e d , fa n c y B o x .C h e c k e d );<br />

}<br />

b ir t h d a y P a r t y = new B ir t h d a y P a r t y ( (in t)n u m b e r B ir th d a y .V a lu e ,<br />

D is p la y B ir t h d a y P a r t y C o s t ( );<br />

fa n c y B ir th d a y .C h e c k e d , c a k e W r i t in g .T e x t ) ;<br />

// Обработчики событий для fancyBox, healthyBox и numericUpDownl<br />

// a такж<strong>е</strong> м<strong>е</strong>тод DisplayDlnnerCost() аналогичны показанным<br />

/ / в упражн<strong>е</strong>нии Dinner Party в конц<strong>е</strong> главы 5.<br />

★<br />

Добавьт<strong>е</strong> код к обработчику событий эл<strong>е</strong>м<strong>е</strong>нта NumericUpDown, чтобы задать свойство<br />

Num berOfPeople и заставить функционировать флажок Fancy Decorations.<br />

p r i v a t e v o i d n u m b e rB ir th d a y _ V a lu eC h a n g ed (o b je ct s e n d e r , E ven tA rgs e) {<br />

b ir th d a y P a r ty .N u m b e r O fP e o p le = (in t)n u m b e r B ir th d a y .V a lu e ;<br />

D is p la y B ir th d a y P a r ty C o s t () ; Обработчики событий эл<strong>е</strong>м<strong>е</strong>нтов CheckBox<br />

} и NumericUpDown таки<strong>е</strong> ж<strong>е</strong>, как и для<br />

/ вкладки dinner party.<br />

p r i v a t e v o id fa n c y B ir th d a y _ C h e c k e d C h a n g e d (o b je c t s e n d e r , E ven tA rgs e) {<br />

}<br />

b ir t h d a y P a r t y .C a lc u la t e C o s t O f D e c o r a t io n s ( f a n c y B ir t h d a y . C h e c k e d );<br />

D is p la y B ir t h d a y P a r t y C o s t ( );<br />

238 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Откройт<strong>е</strong> страницу Events в окн<strong>е</strong> Properties и добавьт<strong>е</strong> к т<strong>е</strong>кстовому полю c a k e W r i t i n g<br />

новый обработчик событий T e x t C h a n g ed .<br />

jPfoperties I-- П x |<br />

1 cakeWriting System.Wmdows.Forms.TextBox<br />

7 extAlignChanged<br />

T«9stCh3nqed HHcateW ritm g_iextChaii9e


работа<strong>е</strong>т!<br />

О ТТрогроААма готова!<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что программа работа<strong>е</strong>т корр<strong>е</strong>ктно. Если надпись на торт<strong>е</strong><br />

слишком длинная, должно появляться окно с сообщ<strong>е</strong>ни<strong>е</strong>м. Пров<strong>е</strong>рьт<strong>е</strong><br />

правильность расч<strong>е</strong>та кон<strong>е</strong>чной суммы. Если вс<strong>е</strong> функциониру<strong>е</strong>т,<br />

значит, работа сд<strong>е</strong>лана!<br />

DmerPaty [ ftrthday Pariy.l<br />

Nuntw erf People<br />

12<br />

Запустит<strong>е</strong> программу и откройт<strong>е</strong><br />

вкладку Pinner Party. Уб<strong>е</strong>дит<strong>е</strong>сь, что<br />

она работа<strong>е</strong>т точно так ж<strong>е</strong>, как<br />

и старая программа Party Planner.<br />

|ÿ| FancyDecorations<br />

В Н<strong>е</strong>аИту Option<br />

Q m * I $770.00<br />

П<strong>е</strong>р<strong>е</strong>йдит<strong>е</strong> на вкладку<br />

Birthday Party.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь^ ч т о знач<strong>е</strong>ни<strong>е</strong><br />

поля Cost м<strong>е</strong>ня<strong>е</strong>тся при<br />

изм<strong>е</strong>н<strong>е</strong>нии колич<strong>е</strong>ства<br />

гост<strong>е</strong>й и установк<strong>е</strong><br />

флажка Fancy Pecorations.<br />

Party pTanneJli<br />

1Dimer Paify p Brthday Paity<br />

NtnteofPeopte<br />

[s fel;<br />

Fancy Décorions<br />

Cdîe Wiîing<br />

Happy Brthday<br />

Cost 1$328.50<br />

...........J<br />

Пров<strong>е</strong>рим правильность<br />

расч<strong>е</strong>тов для й-О гост<strong>е</strong>й.<br />

Еда $2.5 X й-О =<br />

^ 6 -дюймовый т орт стоит<br />

$75, обычно<strong>е</strong> оформл<strong>е</strong>ни<strong>е</strong>:<br />

$7.50 Х'Ю - $75,<br />

<strong>е</strong>диновр<strong>е</strong>м<strong>е</strong>нный взнос: $30,<br />

буква на торт<strong>е</strong> по ц<strong>е</strong>н<strong>е</strong><br />

$.7.5 за букву = $5.25.<br />

Итого $250 +<br />

$75 + $75 + $30 +<br />

$5.25 = $435.25.<br />

Вс<strong>е</strong> правильно!<br />

При ввод<strong>е</strong> информации<br />

в пол<strong>е</strong> Сак<strong>е</strong> Writing<br />

обработчик событий __<br />

TextChanged долж<strong>е</strong>н<br />

обновлять знач<strong>е</strong>ни<strong>е</strong><br />

поля Cost.<br />

Dinner<br />

Bithday Party<br />

Nwtoerof Р<strong>е</strong>


насл<strong>е</strong>довани<strong>е</strong><br />

Дополнит<strong>е</strong>льный Взнос за м<strong>е</strong>роприятия с большим<br />

колич<strong>е</strong>ством гост<strong>е</strong>й<br />

Благодаря программ<strong>е</strong> д<strong>е</strong>ла Кэтлин пошли в гору, и т<strong>е</strong>п<strong>е</strong>рь она мож<strong>е</strong>т<br />

с<strong>е</strong>б<strong>е</strong> позволить брать дополнит<strong>е</strong>льную плату за м<strong>е</strong>роприятия<br />

с оч<strong>е</strong>нь большим колич<strong>е</strong>ством гост<strong>е</strong>й (бол<strong>е</strong><strong>е</strong> 12 ч<strong>е</strong>лов<strong>е</strong>к). Как ж<strong>е</strong> добавить<br />

к программ<strong>е</strong> <strong>е</strong>щ<strong>е</strong> один плат<strong>е</strong>ж?<br />

★<br />

М<strong>е</strong>тод D i n n e r P a r t y . C a l c u l a t e C o s t () долж<strong>е</strong>н пров<strong>е</strong>рять<br />

знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной N u m b e r O fP e o p le , и <strong>е</strong>сли возвраща<strong>е</strong>мо<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> пр<strong>е</strong>выша<strong>е</strong>т 12, добавлять $100.<br />

★ Аналогично для м<strong>е</strong>тода B i r t h d a y P a r t y . C a l c u l a t e C o s t ( ) .<br />

Подумайт<strong>е</strong>, как добавить <strong>е</strong>щ<strong>е</strong> один плат<strong>е</strong>ж к классам D i n n e r P a r t y<br />

и B i r t h d a y P a r t y . Какой код сл<strong>е</strong>ду<strong>е</strong>т написать? С какими эл<strong>е</strong>м<strong>е</strong>нтами<br />

этот код долж<strong>е</strong>н быть связан?<br />

Каж<strong>е</strong>тся, что это просто... но что мож<strong>е</strong>т случиться при сосущ<strong>е</strong>ствовании<br />

тр<strong>е</strong>х одинаковых классов? А ч<strong>е</strong>тыр<strong>е</strong>х? А дв<strong>е</strong>надцати? А что<br />

<strong>е</strong>сли в будущ<strong>е</strong>м вам потр<strong>е</strong>бу<strong>е</strong>тся отр<strong>е</strong>дактировать код? Вы пр<strong>е</strong>дставля<strong>е</strong>т<strong>е</strong><br />

с<strong>е</strong>б<strong>е</strong>, как трудно м<strong>е</strong>нять одшшковьш образом множ<strong>е</strong>ство родств<strong>е</strong>нных<br />

классов?<br />

То <strong>е</strong>сть мн<strong>е</strong> прид<strong>е</strong>тся снова и<br />

снова писать один и тот ж<strong>е</strong> код?<br />

Вот спасибо! Мож<strong>е</strong>т быть, <strong>е</strong>сть<br />

какой-то другой способ?<br />

Вы правы ! П овтор<strong>е</strong>ни<strong>е</strong> одного и того ж <strong>е</strong> кода<br />

в разны х классах н<strong>е</strong>эф ф <strong>е</strong>ктивно. И к том у ж<strong>е</strong><br />

ув<strong>е</strong>личива<strong>е</strong>тся в<strong>е</strong>роятность ош ибок.<br />

К счастью, в <strong>C#</strong> сущ<strong>е</strong>ству<strong>е</strong>т бол<strong>е</strong><strong>е</strong> продуктивный<br />

способ создания связанных друг с другом классов:<br />

насл<strong>е</strong>довани<strong>е</strong> (inheritance).<br />

дальш<strong>е</strong> ► 241


н<strong>е</strong> тратьт<strong>е</strong> золото, <strong>е</strong>сли нуж<strong>е</strong>н только бл<strong>е</strong>ск<br />

Насл<strong>е</strong>довани<strong>е</strong><br />

Классы D i n n e r P a r t y и B i r t h d a y P a r t y н<strong>е</strong> случайно им<strong>е</strong>ют одинаковый код. При написании программ<br />

<strong>C#</strong> часто создаются классы, соотв<strong>е</strong>тствующи<strong>е</strong> проц<strong>е</strong>ссам из р<strong>е</strong>ального мира, и эти проц<strong>е</strong>ссы, как правило,<br />

связаны друг с другом. Ваши классы им<strong>е</strong>ют одинаковый код, так как проц<strong>е</strong>ссы, взяты<strong>е</strong> за их основу<br />

(дни рожд<strong>е</strong>ния и званы<strong>е</strong> об<strong>е</strong>ды), им<strong>е</strong>ют одинаковы<strong>е</strong> признаки.<br />

рассчитать<br />

стоимость<br />

м<strong>е</strong>роприятия<br />

DinnerParty<br />

NumberOfPeople ^<br />

CostOTOecorations .........<br />

HealthyOption<br />

CostOffieveragesPerPerson<br />

К э т л и н в обоих<br />

случаях нужно Ч CalcuiateCostOTOecorationsO ^<br />

( _CalculateCost() ^<br />

SetHealthyOptionO<br />

BirthdayParty<br />

►МитЬ<strong>е</strong>ЮГР<strong>е</strong>орІ<strong>е</strong><br />

►СозЮГО<strong>е</strong>согаІіопз<br />

CakeSize<br />

CakeWriting<br />

►CalculateCostOTOecorationsO<br />

►CalculateCostO<br />

Колич<strong>е</strong>ство<br />

гост<strong>е</strong>й и ст ой-<br />

Mocmi? оформл<strong>е</strong>ния<br />

для дн<strong>е</strong>й<br />

рожд<strong>е</strong>ния обрабатываются<br />

п о ч -<br />

•VI« так ж<strong>е</strong>, как<br />

званы<strong>е</strong> об<strong>е</strong>ды.<br />

Збаны<strong>е</strong> об<strong>е</strong>ды u дни |)о;кд<strong>е</strong>ния о тн о с я тся к п|>и<strong>е</strong>мам<br />

Если сущ<strong>е</strong>ствуют н<strong>е</strong>сколько классов, являющихся частными случаями другого, бол<strong>е</strong><strong>е</strong> общ<strong>е</strong>го класса,<br />

можно заставить их насл<strong>е</strong>довать от этого класса. При этом они становятся классами, производными<br />

(subclass) от базового (base class).<br />

Колич<strong>е</strong>ство приглаш<strong>е</strong>н- ,<br />

ных и стоимость оформл<strong>е</strong>ния<br />

нужно знать для<br />

при<strong>е</strong>ма любого типа, поэтому<br />

данны<strong>е</strong> парм<strong>е</strong>тры<br />

нужно пом<strong>е</strong>стить в базовый<br />

класс.<br />

Party<br />

Numl)eЮfPeople<br />

CostOTOecorations<br />

CalculateCostOTOecorationsO<br />

CalculateCostO _______<br />

Н<strong>е</strong>смотря на сходство,<br />

окончат<strong>е</strong>льная стоимость<br />

каждого при<strong>е</strong>ма<br />

рассчитыва<strong>е</strong>тся<br />

у^-разноми. Поэтому<br />

сходны<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ния логично<br />

пом<strong>е</strong>стить в базовый<br />

класс, а отличны<strong>е</strong> —<br />

в производны<strong>е</strong> классы.<br />

С<br />

Стр<strong>е</strong>лка в диаграмм<strong>е</strong><br />

указыва<strong>е</strong>т,<br />

что класс<br />

DinnerParty<br />

унасл<strong>е</strong>дован<br />

от класса Party.<br />

Оба производных<br />

класса насл<strong>е</strong>Эуют<br />

проц<strong>е</strong>дуру<br />

DinnerParty расч<strong>е</strong>та стои­ BirthdayParty<br />

NumberOfPeople мости оформ­ NumberOfPeople<br />

HealthyOption л<strong>е</strong>ния от ба­ CakeSize<br />

CostOffieveragesPerPerson зового класса, CakeWriting<br />

поэтому<br />

О,, /?<br />

она<br />

CalculateCostQ 0 них н<strong>е</strong> вклю ­ CalculateCostQ 6z-----------------<br />

SetHealthyOptionO ч<strong>е</strong>на.<br />

242 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Мод<strong>е</strong>ль классов: о т общ<strong>е</strong>го к частному<br />

Насл<strong>е</strong>довани<strong>е</strong> в С# явля<strong>е</strong>тся копи<strong>е</strong>й проц<strong>е</strong>ссов, происходящих в р<strong>е</strong>альном мир<strong>е</strong>. И <strong>е</strong>рархия присутству<strong>е</strong>т<br />

в вид<strong>е</strong> п<strong>е</strong>р<strong>е</strong>хода от общих в<strong>е</strong>щ<strong>е</strong>й к частностям. В мод<strong>е</strong>ли классов классы, располож<strong>е</strong>нны<strong>е</strong> ниж<strong>е</strong><br />

в и<strong>е</strong>рархии, насл<strong>е</strong>дуют от выш<strong>е</strong>стоящих.<br />

О бщ <strong>е</strong><strong>е</strong><br />

А<br />

8 мод<strong>е</strong>ли классов Сыр<br />

м о ж <strong>е</strong>т насл<strong>е</strong>довать<br />

от Еж<strong>е</strong>дн<strong>е</strong>вного<br />

продукта, который,<br />

в свою оч<strong>е</strong>р<strong>е</strong>дь,<br />

насл<strong>е</strong>ду<strong>е</strong>т от класса Еда.<br />

Лю5ая<br />

птица —■<br />

животно<strong>е</strong>,<br />

но н<strong>е</strong> любо<strong>е</strong><br />

животно<strong>е</strong> —<br />

птица.<br />

^<br />

( Ж ивотно<strong>е</strong><br />

Общ <strong>е</strong><strong>е</strong><br />

Еж <strong>е</strong>дн<strong>е</strong>вны й продукт<br />

Птица<br />

Сы р<br />

Ч<strong>е</strong>дд<strong>е</strong>р<br />

Вы д<strong>е</strong>ржанны й<br />

в<strong>е</strong>рм онтский ч<strong>е</strong>дд<strong>е</strong>р<br />

Для домашн<strong>е</strong>го<br />

питомца достаточно<br />

Класса П<strong>е</strong>вчая<br />

птица, а вот для<br />

орнитолога, изучающ<strong>е</strong>го<br />

с<strong>е</strong>м<strong>е</strong>йство т,т[с1а<strong>е</strong><br />

н<strong>е</strong>допустимо пут ат ь<br />

с<strong>е</strong>в<strong>е</strong>рного и ю ж ^го<br />

п<strong>е</strong>р<strong>е</strong>см<strong>е</strong>шников.<br />

П<strong>е</strong>вчая птица<br />

П<strong>е</strong>р<strong>е</strong>см <strong>е</strong>ш ник<br />

С <strong>е</strong>в<strong>е</strong>рны й п<strong>е</strong>р<strong>е</strong>см <strong>е</strong>ш ник<br />

Частно<strong>е</strong><br />

Если в р<strong>е</strong>ц<strong>е</strong>пт<strong>е</strong> указан ч<strong>е</strong>дд<strong>е</strong>р,<br />

можно использовать и выд<strong>е</strong>ржанный<br />

в<strong>е</strong>рмонтский ч<strong>е</strong>дд<strong>е</strong>р.<br />

Но <strong>е</strong>сли вам тр<strong>е</strong>бу<strong>е</strong>тся им <strong>е</strong>нно<br />

«В<strong>е</strong>рмонт», н<strong>е</strong>допустимо<br />

использовать простой «ч<strong>е</strong>дд<strong>е</strong>р<br />

вообщ<strong>е</strong>».<br />

^<br />

У<br />

Нижни<strong>е</strong> чл<strong>е</strong>ны и<strong>е</strong>рархии много<strong>е</strong><br />

о т высших. П<strong>е</strong>р<strong>е</strong>см<strong>е</strong>шники<br />

Г м т й ^ т с я и размнож ают ся, как<br />

и вс<strong>е</strong> животны<strong>е</strong>.<br />

Частно<strong>е</strong><br />

Нас-л<strong>е</strong>-до-вать, глаг.<br />

им<strong>е</strong>ть признаки родит<strong>е</strong>ля<br />

или пр<strong>е</strong>дка. Она хоч<strong>е</strong>т, чтобы<br />

р<strong>е</strong>б<strong>е</strong>нок унасл<strong>е</strong>довал <strong>е</strong><strong>е</strong> больши<strong>е</strong><br />

кари<strong>е</strong> глаза.<br />

дальш<strong>е</strong> > 243


прогуляємся в джунгли<br />

Симулятор зоопарка<br />

Львы, тигры и м<strong>е</strong>дв<strong>е</strong>ди... о, бож<strong>е</strong>! А <strong>е</strong>щ<strong>е</strong> б<strong>е</strong>г<strong>е</strong>моты, волки и случайно<br />

зат<strong>е</strong>савшаяся кошка. Вам нужно написать симулятор зоопарка.<br />

(Н<strong>е</strong> бойт<strong>е</strong>сь, сам код писать н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся, на данном этап<strong>е</strong> достаточно<br />

создать диаграмму классов, пр<strong>е</strong>дставляющую вс<strong>е</strong>х животных).<br />

Мы получили н<strong>е</strong>большой список животных, которы<strong>е</strong> должны попасть<br />

в программу. Каждому животному буд<strong>е</strong>т соотв<strong>е</strong>тствовать объ<strong>е</strong>кт<br />

со сп<strong>е</strong>цифич<strong>е</strong>скими свойствами.<br />

Программа должна л<strong>е</strong>гко читаться и р<strong>е</strong>дактироваться другими программистами,<br />

<strong>е</strong>сли поздн<strong>е</strong><strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся добавить други<strong>е</strong> классы или<br />

других животных.<br />

с ч<strong>е</strong>го ж<strong>е</strong> начать? П<strong>е</strong>р<strong>е</strong>д обсужд<strong>е</strong>ни<strong>е</strong>м отд<strong>е</strong>льных животных нужно<br />

понять, что они им<strong>е</strong>ют общ<strong>е</strong>го —выд<strong>е</strong>лить характ<strong>е</strong>ристики, подходящи<strong>е</strong><br />

вс<strong>е</strong>м видам. Им<strong>е</strong>нно на их основ<strong>е</strong> буд<strong>е</strong>т постро<strong>е</strong>н класс, от которого<br />

будут насл<strong>е</strong>довать други<strong>е</strong> классы.<br />

Что у животных общ<strong>е</strong>го<br />

Посмотрит<strong>е</strong> на ш<strong>е</strong>сть животных. Как связаны л<strong>е</strong>в, б<strong>е</strong>г<strong>е</strong>мот,<br />

тигр, кошка, волк и далматин? Им<strong>е</strong>нно эти общи<strong>е</strong><br />

для вс<strong>е</strong>х свойства лягут в основу базового класса.<br />

244 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Насл<strong>е</strong>довани<strong>е</strong> позВоля<strong>е</strong>т изб<strong>е</strong>)кать<br />

дублирования кода В произВодных классах<br />

О<br />

Так как дублирующийся код сложно р<strong>е</strong>дактировать и <strong>е</strong>щ<strong>е</strong> сложн<strong>е</strong><strong>е</strong><br />

читать, выб<strong>е</strong>р<strong>е</strong>м м<strong>е</strong>тоды и поля для базового класса Animal, которы<strong>е</strong><br />

будут написаны только од и н раз и которы<strong>е</strong> будут унасл<strong>е</strong>дованы<br />

вс<strong>е</strong>ми производными классами. Начн<strong>е</strong>м с пол<strong>е</strong>й общ<strong>е</strong>го доступа:<br />

★ P ic tu r e : картинка, которую можно пом<strong>е</strong>стить в PictureBox.<br />

★ Food: тип пищи. Пока у этого поля только два знач<strong>е</strong>ния: meat<br />

(мясо) и grass (трава).<br />

★ Hunger: п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная типа i n t , показывающая, насколько животно<strong>е</strong><br />

хоч<strong>е</strong>т <strong>е</strong>сть. Она м<strong>е</strong>ня<strong>е</strong>тся в зависимости от колич<strong>е</strong>ства<br />

выданного корма.<br />

★ B o u n d aries: ссылка на класс, в котором хранится информация<br />

о высот<strong>е</strong>, длин<strong>е</strong> и располож<strong>е</strong>нии воль<strong>е</strong>ра.<br />

★ L o c a tio n : координаты X и Y, описывающи<strong>е</strong> м<strong>е</strong>стополож<strong>е</strong>ни<strong>е</strong><br />

животного.<br />

Кром<strong>е</strong> того, в класс<strong>е</strong> Animal присутствуют ч<strong>е</strong>тыр<strong>е</strong> м<strong>е</strong>тода, которы<strong>е</strong><br />

могут быть унасл<strong>е</strong>дованы:<br />

★ M akeNoise ( ) : м<strong>е</strong>тод, позволяющий издавать звуки.<br />

★ E at {) : пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> при получ<strong>е</strong>нии пр<strong>е</strong>дпочита<strong>е</strong>мого корма.<br />

★ S le e p ( ) : м<strong>е</strong>тод, заставляющий животно<strong>е</strong> спать.<br />

★ Roam ( ) : м<strong>е</strong>тод, учитывающий п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ния по воль<strong>е</strong>ру.<br />

Постро<strong>е</strong>ни<strong>е</strong> базового<br />

класса<br />

Поля, свойства и м<strong>е</strong>тоды базового<br />

класса дадут вс<strong>е</strong>м животным<br />

возможность насл<strong>е</strong>довать<br />

общ<strong>е</strong><strong>е</strong> состояни<strong>е</strong> и пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>.<br />

Логично, что этот класс долж<strong>е</strong>н<br />

называться Animal (Животно<strong>е</strong>).<br />

Anim al<br />

Picture<br />

Food<br />

Hunger<br />

Boundaries<br />

Location<br />

Можно было сд<strong>е</strong>лать<br />

u другой выбор- Наприм<strong>е</strong>р,<br />

написать класс<br />

Z o o O c c u p a n tj учыты -<br />

вающий расходы на сод<strong>е</strong>ржани<strong>е</strong><br />

животных,<br />

или класс A t t r a c t i o n ,<br />

показываюш,ий привл<strong>е</strong>кат<strong>е</strong>льность<br />

для<br />

пос<strong>е</strong>тит<strong>е</strong>л<strong>е</strong>й. Но МИ<br />

остановились на класс<strong>е</strong><br />

Animal. Вы согласны?<br />

дальш<strong>е</strong> > 245


программистов н<strong>е</strong> кормить<br />

Ж ивотны<strong>е</strong> издают звуки<br />

Львы рычат, собаки лают, а б<strong>е</strong>г<strong>е</strong>моты, насколько<br />

мы зна<strong>е</strong>м, вообщ<strong>е</strong> н<strong>е</strong> издают конкр<strong>е</strong>тных звуков.<br />

Каждый класс, производный от Animal, унасл<strong>е</strong>ду<strong>е</strong>т<br />

м<strong>е</strong>тод M akeNoise О , но коды этих м<strong>е</strong>тодов будут<br />

различаться. Когда производный класс м<strong>е</strong>ня<strong>е</strong>т пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

унасл<strong>е</strong>дованного м<strong>е</strong>тода, говорят о п<strong>е</strong>р<strong>е</strong>кры<br />

тии (override).<br />

Что Вам ну)кно п<strong>е</strong>р<strong>е</strong>крыть?<br />

Вс<strong>е</strong> животны<strong>е</strong> <strong>е</strong>дят. Но <strong>е</strong>сли собака любит мясо,<br />

то б<strong>е</strong>г<strong>е</strong>моту подавай воз травы. Как мож<strong>е</strong>т выгляд<strong>е</strong>ть<br />

код подобного пов<strong>е</strong>д<strong>е</strong>ния? Как собака, так<br />

и б<strong>е</strong>г<strong>е</strong>мот п<strong>е</strong>р<strong>е</strong>кроют м<strong>е</strong>тод E at (). Б<strong>е</strong>г<strong>е</strong>мота этот<br />

м<strong>е</strong>тод заставить потр<strong>е</strong>блять, скаж<strong>е</strong>м, 10 кг травы<br />

за раз. В то вр<strong>е</strong>мя как вызванный для собаки м<strong>е</strong>тод<br />

E at () ум<strong>е</strong>ньшит запасы пищи в зоопарк<strong>е</strong> на одну<br />

банку собачь<strong>е</strong>го корма в<strong>е</strong>сом 300 г.<br />

Г<br />

Производный класс насл<strong>е</strong>ду<strong>е</strong>м<br />

от базового<br />

вс<strong>е</strong> <strong>е</strong>го пов<strong>е</strong>д<strong>е</strong>ния, но вы<br />

мож<strong>е</strong>т<strong>е</strong> их отр<strong>е</strong>дактировать.<br />

( С<strong>е</strong>но — это вкусно!<br />

^ Я бы съ<strong>е</strong>л стог-<br />

V. другой прямо с<strong>е</strong>йчас.<br />

_<br />

W<br />

Свойства и м<strong>е</strong>тоды из базового<br />

класса Ат'та! н<strong>е</strong> обязат<strong>е</strong>льно<br />

использовать<br />

в производных классах в н<strong>е</strong>-<br />

/ изм<strong>е</strong>нном вид<strong>е</strong>. Вы мож<strong>е</strong>т<strong>е</strong><br />

{ вообш,<strong>е</strong> их н<strong>е</strong> использовать!<br />

'V<br />

Что каждо<strong>е</strong> животно<strong>е</strong> из класса<br />

iAnimal д<strong>е</strong>ла<strong>е</strong>т по-сво<strong>е</strong>му<br />

или н<strong>е</strong> д<strong>е</strong>ла<strong>е</strong>т вообщ<strong>е</strong>?<br />

Что животно<strong>е</strong> из каждого производного<br />

класса д<strong>е</strong>ла<strong>е</strong>т такого, ч<strong>е</strong>го остальны<strong>е</strong><br />

животны<strong>е</strong> н<strong>е</strong> д<strong>е</strong>лают? Если собака<br />

<strong>е</strong>ст собачью <strong>е</strong>ду, то <strong>е</strong><strong>е</strong> м<strong>е</strong>тод E at ( ) долж<strong>е</strong>н<br />

п<strong>е</strong>р<strong>е</strong>крыть м<strong>е</strong>тод A n im al. E at ( ).<br />

Б<strong>е</strong>г<strong>е</strong>моты ум<strong>е</strong>ют плавать, поэтому для<br />

них опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>н м<strong>е</strong>тод Swim ( ), который<br />

в класс<strong>е</strong> Animal вообщ<strong>е</strong> отсутству<strong>е</strong>т.<br />

О<br />

С<strong>е</strong>но?! Н<strong>е</strong>т, мн<strong>е</strong><br />

хоч<strong>е</strong>тся мяса!<br />

A nim al<br />

Picture<br />

Food<br />

Hunger<br />

Boundaries<br />

Location<br />

Mal^eNoiseO<br />

Eat()<br />

SleepO<br />

Roam()<br />

W T V P M<br />

Для н<strong>е</strong>которых животных тр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>крыть м<strong>е</strong>тоды<br />

MakeNoise () и Eat (). А для кого нужно п<strong>е</strong>р<strong>е</strong>крыть м<strong>е</strong>тод<br />

Sleep О или RoamO ? И нужно ли это д<strong>е</strong>лать вообщ<strong>е</strong>? Подумаі^т<strong>е</strong><br />

такж<strong>е</strong>, для каких животных будут п<strong>е</strong>р<strong>е</strong>крываться свойства.<br />

246 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Разбива<strong>е</strong>м )кивотных на группы<br />

«Выд<strong>е</strong>ржанный в<strong>е</strong>рмонтский ч<strong>е</strong>дд<strong>е</strong>р» —это вид сыра, который относится к <strong>е</strong>ж<strong>е</strong>дн<strong>е</strong>вно<br />

потр<strong>е</strong>бля<strong>е</strong>мым продуктам и в свою оч<strong>е</strong>р<strong>е</strong>дь входит в кат<strong>е</strong>горию «<strong>е</strong>да». Эта посл<strong>е</strong>доват<strong>е</strong>льность<br />

пр<strong>е</strong>дставл<strong>е</strong>на наглядной мод<strong>е</strong>лью классов. К счастью для нас, в C # таки<strong>е</strong><br />

в<strong>е</strong>щи л<strong>е</strong>гко сд<strong>е</strong>лать. Можно создать ц<strong>е</strong>почку классов, насл<strong>е</strong>дующих друг от друга. И вы<br />

получит<strong>е</strong> бс130вый класс F o o d с производным классом D a i r y P r o d u c t , который, в свою<br />

оч<strong>е</strong>р<strong>е</strong>дь, явля<strong>е</strong>тся базовым для класса C h e e s e , сод<strong>е</strong>ржащ<strong>е</strong>го в с<strong>е</strong>б<strong>е</strong> производный класс<br />

C h e d d a r , п<strong>е</strong>р<strong>е</strong>дающий свои признаки классу A g e d V e r m o n tC h e d d a r .<br />

Поиск классов, им<strong>е</strong>ющих ллного<br />

общ<strong>е</strong>го<br />

Вам н<strong>е</strong> каж<strong>е</strong>тся, что волки и собаки во<br />

многом похожи? Они относятся к с<strong>е</strong>м<strong>е</strong>йству<br />

псовых и им<strong>е</strong>ют сходно<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>.<br />

Скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го, им прид<strong>е</strong>тся по вкусу одна и<br />

та ж<strong>е</strong> <strong>е</strong>да. И спят они одинаковым способом.<br />

Т<strong>е</strong>п<strong>е</strong>рь рассмотрим домашних кош<strong>е</strong>к,<br />

тигров и львов? Они одинаково п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щаются<br />

по м<strong>е</strong>сту сво<strong>е</strong>го обитания. Нав<strong>е</strong>рно<strong>е</strong>,<br />

им<strong>е</strong><strong>е</strong>т смысл создать для них базовый<br />

класс F e l i n e (Кошачьи), который буд<strong>е</strong>т<br />

производным от класса A n im a l. Это позволит<br />

изб<strong>е</strong>жать дублирования кода.<br />

A nim al<br />

Picture<br />

Food<br />

Hunger<br />

Boundaries<br />

Location<br />

IVIal


расширя<strong>е</strong>м объ<strong>е</strong>кты<br />

и<strong>е</strong>рархия классов<br />

Конструкция, в которой под базовым классом располагаются производны<strong>е</strong><br />

классы, которы<strong>е</strong>, в свою оч<strong>е</strong>р<strong>е</strong>дь, являются базовыми<br />

для других классов, называ<strong>е</strong>тся и<strong>е</strong>рархи<strong>е</strong>й (class hierarchy). Подобный<br />

подход н<strong>е</strong> только позволя<strong>е</strong>т изб<strong>е</strong>жать многократного дублирования<br />

кода, но и д<strong>е</strong>ла<strong>е</strong>т код намного бол<strong>е</strong><strong>е</strong> читаб<strong>е</strong>льным. Наприм<strong>е</strong>р,<br />

при просмотр<strong>е</strong> кода симулятора зоопарка, наткнувшись<br />

на м<strong>е</strong>тод или свойство из класса Feline, вы сразу пойм<strong>е</strong>т<strong>е</strong>, что они<br />

им<strong>е</strong>ют отнош<strong>е</strong>ни<strong>е</strong> к кошкам. И<strong>е</strong>рархия становится картой, позволяющ<strong>е</strong>й<br />

отсл<strong>е</strong>дить происходящ<strong>е</strong><strong>е</strong> в программ<strong>е</strong>.<br />

Зав<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> постро<strong>е</strong>ния и<strong>е</strong>рархии<br />

Вам осталось добавить классы Feline и Canine,<br />

и и<strong>е</strong>рархия буд<strong>е</strong>т готова.<br />

Animal<br />

Picture<br />

Food<br />

Hunger<br />

Boundaries<br />

Location<br />

IVIakeNoiseO<br />

Eat()<br />

SleepO<br />

Roam()<br />

Класс Fefine п<strong>е</strong>р<strong>е</strong>крыва<strong>е</strong>т<br />

м<strong>е</strong>тод RoamQ, поэтому<br />

вс<strong>е</strong> унасл<strong>е</strong>дованны<strong>е</strong><br />

свойства будут им<strong>е</strong>ть<br />

д<strong>е</strong>ло с новым м<strong>е</strong>тодом,<br />

а н<strong>е</strong> с т<strong>е</strong>м, который дыл<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>н в класс<strong>е</strong> Animal.<br />

V.<br />

Feline<br />

sce KOIMKU двигаются<br />

п о э т а !<br />

м<strong>е</strong>тод RoamO дляны^<br />

общий. Но они п Т<br />

разному питаются <<br />

издают разны<strong>е</strong> s S y i^<br />

^оэтому м<strong>е</strong>тоды ^ ^<br />

и MakeNoiseO<br />

Унасл<strong>е</strong>дованны<strong>е</strong><br />

от класса Animai<br />

^^Р<strong>е</strong>крываются.<br />

'<br />

MakeNoiseO<br />

Eat()<br />

MakeNoiseO<br />

Eat()<br />

Волки и собаки<br />

пит аю т ­<br />

ся одинаково,<br />

поэтому ик "<br />

общий м<strong>е</strong>тод<br />

EatQ пом<strong>е</strong>щ<strong>е</strong>н<br />

в класс Canine<br />

Wolf<br />

MakeNoiseO<br />

MakeNoiseO<br />

248 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Производны<strong>е</strong> классы расширяют<br />

базовый<br />

'<br />

Вы н<strong>е</strong> огранич<strong>е</strong>ны м<strong>е</strong>тодами, которы<strong>е</strong> производный<br />

класс насл<strong>е</strong>ду<strong>е</strong>т от базового... впроч<strong>е</strong>м, вы это<br />

уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>! В конц<strong>е</strong> концов, вы ж<strong>е</strong> уж<strong>е</strong> создавали<br />

классы. А при насл<strong>е</strong>довании класс просто расширя<strong>е</strong>тся<br />

за сч<strong>е</strong>т добавл<strong>е</strong>ния к базовому классу пол<strong>е</strong>й,<br />

свойств и м<strong>е</strong>тодов. Можно л<strong>е</strong>гко добавить собакам<br />

м<strong>е</strong>тод F e tc h О (Прин<strong>е</strong>сти дичь). Новый м<strong>е</strong>тод<br />

н<strong>е</strong> буд<strong>е</strong>т нич<strong>е</strong>го насл<strong>е</strong>довать и нич<strong>е</strong>го п<strong>е</strong>р<strong>е</strong>крывать<br />

—в<strong>е</strong>дь он опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>н только для псовых и никак<br />

н<strong>е</strong> повлия<strong>е</strong>т на классы Wolf, Canine, Animal,<br />

Hippo и любы<strong>е</strong> други<strong>е</strong>.<br />

созда<strong>е</strong>м новый обь<strong>е</strong>км Род<br />

вызыва<strong>е</strong>м м<strong>е</strong>мод класса Род<br />

Dog s p o t = new D o g ( ) ;<br />

s p o t . M a k e N o is e ( ) ;<br />

вызыва<strong>е</strong>м м<strong>е</strong>мод класса Animal s p o t . Roam ( ) ;<br />

вызыва<strong>е</strong>м м<strong>е</strong>мод класса Canine s p o t . E a t {) ;<br />

и-<strong>е</strong>-рар-^-я, сущ.<br />

расп олож <strong>е</strong>н и <strong>е</strong> групп одна<br />

ПОД другой в соотв<strong>е</strong>тстви и<br />

с и х рангом . Пр<strong>е</strong>зид<strong>е</strong>нт компании<br />

прош<strong>е</strong>л в<strong>е</strong>сь путь от<br />

курь<strong>е</strong>ра до в<strong>е</strong>рхов корпоративной<br />

и<strong>е</strong>рархии.<br />

Anim al<br />

Picture<br />

Food<br />

Hunger<br />

Boundaries<br />

Location<br />

IVIakeNoiseO<br />

Eat()<br />

SleepO<br />

Roam()<br />

вызыва<strong>е</strong>м м<strong>е</strong>мод класса Canine<br />

s p o t . S l e e p ( ) ;<br />

Canine<br />

вызыва<strong>е</strong>м м<strong>е</strong>мод класса Род<br />

s p o t . F e tc h<br />

Eat()<br />

SleepO<br />

C # Вс<strong>е</strong>гда начина<strong>е</strong>т с наибол<strong>е</strong><strong>е</strong> индивидуального м<strong>е</strong>тода<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щаться собаку заставля<strong>е</strong>т вс<strong>е</strong>го один м<strong>е</strong>тод из класса A n im a l. А вот<br />

какой из м<strong>е</strong>тодов M a k e N o is e ( ) нужно вызвать, чтобы собака залаяла?<br />

Понять это н<strong>е</strong>сложно. М<strong>е</strong>тоды класса D o g пр<strong>е</strong>дставляют собой д<strong>е</strong>йствия<br />

вс<strong>е</strong>х собак. А м<strong>е</strong>тоды класса C a n in e —д<strong>е</strong>йствия вс<strong>е</strong>х псовых. М<strong>е</strong>тоды класса<br />

A n im a l являются описани<strong>е</strong>м пов<strong>е</strong>д<strong>е</strong>ния, общ<strong>е</strong>го для вс<strong>е</strong>х животных. Поэтому<br />

<strong>е</strong>сли нужно заставить собаку лаять, <strong>C#</strong> сначала «заглян<strong>е</strong>т» в класс D og,<br />

чтобы найти пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>, присущ<strong>е</strong><strong>е</strong> им<strong>е</strong>нно собакам. Если таково<strong>е</strong> отсутству<strong>е</strong>т,<br />

буд<strong>е</strong>т пров<strong>е</strong>р<strong>е</strong>н класс C a n in e , а потом класс A n im a l.<br />

Dog<br />

IVIai


как низко вы мож<strong>е</strong>т<strong>е</strong> паст ь?<br />

Синтаксис насл<strong>е</strong>добания<br />

При насл<strong>е</strong>довании им<strong>е</strong>на производного и базового классов разд<strong>е</strong>ляются<br />

дво<strong>е</strong>точи<strong>е</strong>м (:). Производный класс получа<strong>е</strong>т вс<strong>е</strong> поля, свойства<br />

и м<strong>е</strong>тоды базового класса.<br />

Vertebrate<br />

NumberOlegs<br />

Eat()<br />

Bird<br />

Wingspan<br />

FlyO<br />

c l a s s V e r t e b r a t e<br />

{<br />

}<br />

p u b l i c i n t Num berO fL egs;<br />

p u b l i c v o id E a tO {<br />

}<br />

// код, заставляющий <strong>е</strong>сть<br />

Класс Bird (Птица) насл<strong>е</strong>ду<strong>е</strong>т от<br />

класса vertebrate (Позвоношо<strong>е</strong>).<br />

c l a s s B i r d : '^ T e r t e b r ^ t ^<br />

{<br />

p u b l i c d o u b le W ingspan;<br />

p u b l i c v o id F ly O {<br />

}<br />

// код, заставляющий л<strong>е</strong>тать<br />

При насл<strong>е</strong>довании<br />

вс<strong>е</strong> поля,<br />

свойства и м<strong>е</strong>тоды<br />

базового<br />

класса автоматич<strong>е</strong>ски<br />

добавля<br />

ются в производ<br />

ный класс.<br />

расш иря<strong>е</strong>т <strong>е</strong> класс,<br />

добавив в кон<strong>е</strong>ц <strong>е</strong>го<br />

обьявл<strong>е</strong>ния дво<strong>е</strong>точи<strong>е</strong><br />

и имя базового класса.<br />

Так как tw eety —<br />

э т о экз<strong>е</strong>мпляр<br />

обь<strong>е</strong>кта Bird, он<br />

им<strong>е</strong><strong>е</strong>т вс<strong>е</strong> м<strong>е</strong>тоды<br />

и поля этого обь<strong>е</strong>кта.<br />

Часто<br />

p u b lic b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

B ir d t w e e t y = new B i r d () ;<br />

C tw e e ty .W in g sp a n = 7 .5 ;<br />

t w e e t y . F l y ( );<br />

tw e ety .N u m b e ro fL e g s = 2<br />

t w e e t y . E a t {);<br />

^ а Д а В а <strong>е</strong> М ы <strong>е</strong> ______________________________<br />

Бо11р»ос;ь1<br />

}<br />

У<br />

тшк как класс Bird<br />

производный по о^нош<strong>е</strong>ни^о<br />

к классу Vertebrate, вс<strong>е</strong> эк<br />

з<strong>е</strong>мпляры Bird им<strong>е</strong>иут поля<br />

и м<strong>е</strong>тоды, опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong><br />

в класс<strong>е</strong> Vertebrate.<br />

Поч<strong>е</strong>му стр<strong>е</strong>лка указыва<strong>е</strong>т от производного класса к базовому?<br />

Н<strong>е</strong> логичн<strong>е</strong>й было бы рисовать <strong>е</strong><strong>е</strong> наоборот?<br />

0 ; Это было бы н<strong>е</strong> совс<strong>е</strong>м точно. Заставляя один класс насл<strong>е</strong>довать<br />

от другого, вы встраива<strong>е</strong>т<strong>е</strong> это отнош<strong>е</strong>ни<strong>е</strong> в производный<br />

класс, а базовый оста<strong>е</strong>тся б<strong>е</strong>з изм<strong>е</strong>н<strong>е</strong>ний. Это им<strong>е</strong><strong>е</strong>т смысл,<br />

<strong>е</strong>сли подумать о происходящ<strong>е</strong>м с точки зр<strong>е</strong>ния базового класса.<br />

Пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> базового класса н<strong>е</strong> только никак н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся, он даж<strong>е</strong><br />

н<strong>е</strong> зна<strong>е</strong>т о появл<strong>е</strong>нии производных классов. М<strong>е</strong>тоды класса, поля<br />

и свойства никак н<strong>е</strong> затрагиваются. А вот производный класс сво<strong>е</strong><br />

пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>т. Вс<strong>е</strong> <strong>е</strong>го вновь создава<strong>е</strong>мы<strong>е</strong> экз<strong>е</strong>мпляры получают<br />

свойства, поля и м<strong>е</strong>тоды базового класса. И вс<strong>е</strong> это происходит<br />

благодаря <strong>е</strong>динств<strong>е</strong>нному дво<strong>е</strong>точию! Стр<strong>е</strong>лка на диаграмм<strong>е</strong><br />

явля<strong>е</strong>тся частью производного класса и поэтому она нац<strong>е</strong>л<strong>е</strong>на<br />

на базовый класс.<br />

250 глава 6


в руку карандаш<br />

насл<strong>е</strong>довани<strong>е</strong><br />

Посмотрит<strong>е</strong> на эти мод<strong>е</strong>ли и объявл<strong>е</strong>ния классов и обв<strong>е</strong>дит<strong>е</strong><br />

н<strong>е</strong>корр<strong>е</strong>ктны<strong>е</strong> оп<strong>е</strong>раторы.<br />

Aircraft<br />

AirSpeed<br />

Altitude<br />

Tal


я знаю, как заставить л<strong>е</strong>тать пингвина...<br />

Возьми в руку карандаш_ _ _ _<br />

5 „ Вот каки<strong>е</strong> оп<strong>е</strong>раторы сл<strong>е</strong>довало обв<strong>е</strong>сти как н<strong>е</strong>работающи<strong>е</strong>.<br />

6Ш6НИ6<br />

Aircraft<br />

AirSpeed<br />

Altitude<br />

Tal<strong>е</strong>Р1ли.<strong>е</strong>.<br />

Sandwich<br />

Toasted<br />

SlicesOfBread<br />

СоипЮа1оп<strong>е</strong>8()<br />

BLT<br />

SlicesOffiacon<br />

AmountOfLettuce<br />

AddSideOfFriesO<br />

c l a s s S an dw ich {<br />

}<br />

p u b l i c b o o le a n T o a ste d ;<br />

p u b l i c i n t S lic e s O fB r e a d ;<br />

p iib lic i n t C o u n tC a lo r ie s O<br />

c l a s s BLT : San dw ich {<br />

p u b l i c i n t S lic e s O fB a c o n ;<br />

}<br />

p u b l i c i n t A m ou ntO fL ettu ce;<br />

p u b l i c i n t A d d S id e O fF r ie sO<br />

p u b l i c BLT OrderMyBLTO {<br />

^ L T ,jm^San d w ich = new BLT () ;<br />

B L T .T o a sted = t r u e ;<br />

^ S a n d w ic h .S lic e sO fB r e a d = 3<br />

rrySandw ich. AddSideO'f b'r le s ' ()<br />

mySandw i c h . S l i c esO fB a co n += 5;<br />

M ess"ageBox.Show("B мо<strong>е</strong>м сэн двич<strong>е</strong><br />

+ m y S a n d w ic h .C o u n tC a lo rie s + "калорий".)<br />

Э т и свойства п р и ­<br />

надл<strong>е</strong>жат экз<strong>е</strong>мпляру,<br />

в то вр<strong>е</strong>мя как оп<strong>е</strong>раторы<br />

пытаются<br />

вызыоать их по им<strong>е</strong>ни<br />

классов.<br />

andwich,---------- ----------------------------------- — J '<br />

скобки (f<br />

\<br />

252 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

При насл<strong>е</strong>добании поля cßoücmßa и м<strong>е</strong>тоды базового класса<br />

добавляются к производному...<br />

Насл<strong>е</strong>довани<strong>е</strong> явля<strong>е</strong>тся простым, <strong>е</strong>сли производному<br />

классу нужны вс<strong>е</strong> м<strong>е</strong>тоды, свойства и поля базового<br />

класса.<br />

Pigeon<br />

СооО<br />

...н<strong>е</strong> н<strong>е</strong> вс<strong>е</strong> птицы л <strong>е</strong> таю т!<br />

Зд<strong>е</strong>сь Pigeon (го-^<br />

лубь) производный<br />

класс от ßird, поэтому<br />

<strong>е</strong>му принабл<br />

<strong>е</strong> ж а т вс<strong>е</strong> м<strong>е</strong>тоды<br />

этого класса — FlyO<br />

(л<strong>е</strong>тать?),<br />

(откладывать яйца),<br />

Preenfeatkers (чм -<br />

стить п<strong>е</strong>рья),<br />

а такж<strong>е</strong> <strong>е</strong>го содств<strong>е</strong>нный<br />

м<strong>е</strong>тод соо()<br />

(ворковать).<br />

Что д<strong>е</strong>лать, <strong>е</strong>сли базовый класс им<strong>е</strong><strong>е</strong>т м<strong>е</strong>тод, который<br />

в производном класс<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся отр<strong>е</strong>дактировать}<br />

У ЗКЗ<strong>е</strong>МУ1АЯр<br />

обь<strong>е</strong>кта Penguin<br />

(пингвин). Он<br />

унасл<strong>е</strong>довал м <strong>е</strong>-<br />

FlyO, и т <strong>е</strong> ­<br />

п<strong>е</strong>рь ничто н<strong>е</strong><br />

Уд<strong>е</strong>ржива<strong>е</strong>т <strong>е</strong>го<br />

от пол<strong>е</strong>та!<br />

Pigeon<br />

Соо()<br />

Penguin<br />

Swlm()<br />

c l a s s B i r d {<br />

p u b l i c v o id F ly O {<br />

/ / код, заставляющий птицу л<strong>е</strong>тать<br />

}<br />

}<br />

p u b l i c v o id L a y E g g sО { . . . };<br />

p u b l i c v o i d P r e e n F e a t h e r s 0 { . . . };<br />

c l a s s P i g e o n : B i r d {<br />

p u b l i c v o id Coo 0 { .<br />

}<br />

c l a s s P e n g u in ; B i r d {<br />

p u b l i c v o id SwimO { . . . }<br />

}<br />

p u b l i c v o id B ir d S im u la t o r 0 {<br />

Но f l<br />

P ig e o n H a r r ie t = new P ig e o n ();<br />

P en g u in I z z y = new P e n g u in 0 ;<br />

H a r r ie t . F ly O ;<br />

H a r r ie t .C o o 0<br />

I z z y . F l y ( );<br />

Как класс Pigeon, так<br />

и класс Penguin насл<strong>е</strong>дуют<br />

у класса<br />

Bird, так что оба<br />

они получают м <strong>е</strong>-<br />

тоды Fly(), LayEggsQ<br />

и PreenFeathersQ.<br />

л<strong>е</strong>тать!<br />

нйслсЭу<strong>е</strong>т о т класса Bird,<br />

У д<strong>е</strong>дняг просто н<strong>е</strong>т выбора'<br />

Гола«“<br />

em.<br />

ШТУРМ<br />

Если бы этот код писали вы, как бы вы избавили пингвина<br />

от н<strong>е</strong>обходимости л<strong>е</strong>тать?<br />

дальш<strong>е</strong> ^ 253


п<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> вручную<br />

П<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> Ал<strong>е</strong>то0о6<br />

Иногда нужно, чтобы производный класс унасл<strong>е</strong>довал н<strong>е</strong> вс<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ния базового,<br />

а только часть их. Чтобы изм<strong>е</strong>нить унасл<strong>е</strong>дованно<strong>е</strong> н<strong>е</strong>нужно<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>,<br />

достаточно п<strong>е</strong>р<strong>е</strong>кры ть (override) м<strong>е</strong>тод.<br />

Клю ч<strong>е</strong>во<strong>е</strong> слово virtual<br />

Чтобы производный класс получил возможность п<strong>е</strong>р<strong>е</strong>крывать м<strong>е</strong>тоды, используйт<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong><br />

слово virtual.<br />

class Bird {<br />

Э т о ключ<strong>е</strong>во<strong>е</strong> слово<br />

public virtual void FlyO {<br />

поклзыва<strong>е</strong>м, ч т о п р о ­<br />

изводный класс мож<strong>е</strong>т<br />

п<strong>е</strong>р<strong>е</strong>крыт ь м <strong>е</strong>т од Р1у().<br />

// КОД, заставл$по1Щ 1Й птрщу л<strong>е</strong>тать<br />

}<br />

}<br />

о Добавл<strong>е</strong>ни<strong>е</strong> одноим <strong>е</strong>нного м<strong>е</strong>тода в производный класс<br />

П<strong>е</strong>р<strong>е</strong>опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нный м<strong>е</strong>тод долж<strong>е</strong>н им<strong>е</strong>ть такую ж<strong>е</strong> сигнатуру, то <strong>е</strong>сть то ж<strong>е</strong> само<strong>е</strong> возвраща<strong>е</strong>мо<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> и парам<strong>е</strong>тры. В <strong>е</strong>го объявл<strong>е</strong>нии использу<strong>е</strong>тся ключ<strong>е</strong>во<strong>е</strong> слово o v e rrid e .<br />

class Penguin : Bird {<br />

public override void Flyf) {<br />

м<strong>е</strong>т од<br />

S e c<br />

^ производный<br />

класс ид<strong>е</strong>нтичный м<strong>е</strong>т од<br />

/ MessageBox.Show("Пингвины н<strong>е</strong> л<strong>е</strong>тают!")<br />

}<br />

При п<strong>е</strong>р<strong>е</strong>крытии сигнат у­<br />

ра нового м<strong>е</strong>тода должна<br />

совпадать с сигнатурой<br />

исходного м<strong>е</strong>тода из базового<br />

класса. В случа<strong>е</strong> с м<strong>е</strong>тодом<br />

Fly это означа<strong>е</strong>т о т с ут ­<br />

стви<strong>е</strong> возвраш,а<strong>е</strong>мого знач<strong>е</strong>ния<br />

и парам<strong>е</strong>тров.<br />

Используйт<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong> слово<br />

override для добавл<strong>е</strong>ния в производный<br />

класс м<strong>е</strong>тодов, зам<strong>е</strong>щающих<br />

м<strong>е</strong>тоды унасл<strong>е</strong>дованны<strong>е</strong>. П<strong>е</strong>р<strong>е</strong>крывать<br />

можно м<strong>е</strong>тоды, пом<strong>е</strong>ч<strong>е</strong>нны<strong>е</strong><br />

в базовом класс<strong>е</strong> словом virtual.<br />

254 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Вм<strong>е</strong>сто базового класса мо)кно в зя ть один из производных<br />

Насл<strong>е</strong>довани<strong>е</strong> позволя<strong>е</strong>т использовать производный класс вм<strong>е</strong>сто базового.<br />

К прим<strong>е</strong>ру, <strong>е</strong>сли м<strong>е</strong>тод R e c i p e ( ) б<strong>е</strong>р<strong>е</strong>т объ<strong>е</strong>кт C h e e s e , в то вр<strong>е</strong>мя как класс<br />

A g e d V e r m o n tC h e d d a r насл<strong>е</strong>ду<strong>е</strong>т от класса C h e e s e , м<strong>е</strong>тоду R e c i p e () можно<br />

п<strong>е</strong>р<strong>е</strong>дать экз<strong>е</strong>мпляр A g e d V e r m o n tC h e d d a r . В р<strong>е</strong>зультат<strong>е</strong> м<strong>е</strong>тод R e c i p e () буд<strong>е</strong>т<br />

им<strong>е</strong>ть доступ только к полям, м<strong>е</strong>тодам и свойствам класса C h e e s e , но н<strong>е</strong> «увидит»<br />

эл<strong>е</strong>м<strong>е</strong>нты класса A g e d V e r m o n tC h e d d a r .<br />

Допустим, у нас им<strong>е</strong><strong>е</strong>тся м<strong>е</strong>тод, анализирующий объ<strong>е</strong>кты S a n d w ic h :<br />

p u b l i c v o id S a n d w ic h A n a ly ze r(S a n d w ich sp ecim en ) {<br />

)<br />

i n t c a l o r i e s = s p e c im e n .C o u n t C a lo r ie s 0 ;<br />

U p d a t e D i e t P l a n ( c a l o r i e s ) ;<br />

P e r fo r m B r e a d C a lc u la tio n s(sp e c im e n .S lic e sO fB r e a d , s p e c im e n .T o a s te d ) ;<br />

Sandwich<br />

Toasted<br />

SlicesOfBread<br />

CountCaloriesO<br />

BLT<br />

SlicesOfBacon<br />

AmountOfLettuce<br />

AddSideOfFriesO<br />

© М<strong>е</strong>тоду можно п<strong>е</strong>р<strong>е</strong>дать объ<strong>е</strong>кт сэндвич, а можно с б<strong>е</strong>коном, салатом и помидорами<br />

BLT (сэндвич). Свойства этого сп<strong>е</strong>циального мы насл<strong>е</strong>ду<strong>е</strong>м от класса<br />

S a n d w ic h :<br />

p u b l i c b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v en tA rg s e) {<br />

}<br />

BLT myBLT = new BLT() ;<br />

S a n d w ich A n alyzer(m yB L T );<br />

Подробно oS э т о м<br />

Mt>i поговорим<br />

6 сл<strong>е</strong>дующ<strong>е</strong>й гллб<strong>е</strong>!<br />

По диаграмм<strong>е</strong> классов вс<strong>е</strong>гда можно спуститься вниз — ссылочной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

можно присвоить экз<strong>е</strong>мпляр одного из производных классов. Но движ<strong>е</strong>ни<strong>е</strong> вв<strong>е</strong>рх<br />

по диаграмм<strong>е</strong> классов запр<strong>е</strong>щ<strong>е</strong>но.<br />

p u b l i c b u t t o n 2 _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

S an dw ich m ySandwich = new S a n d w ic h ( );<br />

BLT myBLT = new BLT();<br />

S an dw ich som eRandomSandwich = myBLT;<br />

Знач<strong>е</strong>ни<strong>е</strong> myBLT м о ж ­<br />

но присвоить люоои<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной класса<br />

Sandw chj т ак как<br />

0LT — э т о подвид<br />

сэндвича.<br />

}<br />

BLT anotherB L T = m ySandwich; / / < - - - ЭТО HE КСЙЯ1ИЛИРУЕТСЯ! ! !<br />

ка компилироват ься н<strong>е</strong>^дуд<strong>е</strong>т<br />

дальш<strong>е</strong> ► 255


н<strong>е</strong>много практики<br />

с ъ л <strong>е</strong> с ь „<br />

т н т с О О ё щ г и и а<br />

а = б<br />

Ь = 5<br />

а = 5<br />

И нструкции:<br />

1. Заполнит<strong>е</strong> ч<strong>е</strong>ты р<strong>е</strong> проб<strong>е</strong>ла в код<strong>е</strong>.<br />

2. С овм <strong>е</strong>стит<strong>е</strong> ф рагм <strong>е</strong>нты и р<strong>е</strong>зультаты .<br />

5 6<br />

11<br />

6 5<br />

Ниж<strong>е</strong> показана короткая программа, у которой<br />

отсутству<strong>е</strong>т фрагм<strong>е</strong>нт кода! Вам нужно сопоставить<br />

фрагм<strong>е</strong>нты кода (сл<strong>е</strong>ва) с возможными<br />

р<strong>е</strong>зультатами. Н<strong>е</strong> вс<strong>е</strong> строчки, прив<strong>е</strong>д<strong>е</strong>нны<strong>е</strong><br />

под заголовком «Р<strong>е</strong>зультат», должны использоваться,<br />

хотя н<strong>е</strong>которы<strong>е</strong> могут использоваться<br />

больш<strong>е</strong> одного раза.<br />

c la s s А {<br />

}<br />

p u b lic i n t iv a r = 7;<br />

p u b lic ______________ s t r in g m l() {<br />

retu rn "A's ml,<br />

}<br />

p u b lic s t r in g m2() {<br />

}<br />

retu rn "A's m2,<br />

p u b lic ______________ s t r in g m3() {<br />

}<br />

retu rn "A's m3,<br />

c l a s s В ; A {<br />

}<br />

p u b lic _____________ s t r in g m l() {<br />

retu rn "B's ml,<br />

}<br />

Фрагм<strong>е</strong>нты<br />

кода:<br />

q += b .m l O ;<br />

q += c.m 2 0 ;<br />

q += a . m3 ( ) ;<br />

q += c .m l O ;<br />

q += c.m 2 0 ;<br />

q += c.m 3 0 ;<br />

q += a . m lO ;<br />

q += b.m 2 0 ;<br />

q += c.m S 0 ;<br />

q += a 2 .m l ( )<br />

q += a 2 .m 2()<br />

q += a 2 .m 3 ()<br />

}<br />

}<br />

}<br />

}<br />

c la s s С : В {<br />

^<br />

pxjblic ______ s t r in g m3() {<br />

retu rn "C's m3, " + (iv a r + 6 );<br />

} ^о ч к а входа в програм м у, иона<br />

н<strong>е</strong> покйзы ба<strong>е</strong>т формы, а только<br />

вызыва<strong>е</strong>т окно с сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

c la s s MixedS {<br />

}<br />

Р<strong>е</strong>зультат:<br />

^<br />

p u b lic s t a t i c v o id M a in (str in g [] args) {<br />

A a = new A O ;<br />

в Ь = new ВО<br />

с с = new С()<br />

А а2 = new С О,-4/<br />

s t r in g q =<br />

Подсказка: Как<br />

сл<strong>е</strong>ду<strong>е</strong>т подумайт<strong>е</strong>,<br />

что им<strong>е</strong>нно это<br />

t<br />

означа<strong>е</strong>т.<br />

Вставьт<strong>е</strong> сюда<br />

фрагм<strong>е</strong>нт (три<br />

строчки)<br />

System.W indows. Forms. M essageBox. Show (q);<br />

A 's m l. A 's m2, C 's m3. 6<br />

B 's m l. A 's m2. A 's m3.<br />

A 's m l. B 's m2. A 's m3.<br />

B 's m l. A 's m2. C 's m3, 13<br />

B 's m l. C 's m2. A 's m3.<br />

B 's m l. A 's m2. C 's m 3, 6<br />

A 's m l. A 's m2. C 's m 3, 13<br />

(Н<strong>е</strong> пользуйт<strong>е</strong>сь ср<strong>е</strong>дствам и ИСР, нам ного<br />

пол<strong>е</strong>зн<strong>е</strong><strong>е</strong> буд<strong>е</strong>т р<strong>е</strong>ш ить задачу на бумаг<strong>е</strong>!)<br />

256 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна и пом<strong>е</strong>стит<strong>е</strong> их на пусты<strong>е</strong> строки. Каждый<br />

фрагм<strong>е</strong>нт можно использовать н<strong>е</strong>сколько раз. В басс<strong>е</strong>йн<strong>е</strong> <strong>е</strong>сть и лишни<strong>е</strong><br />

фрагм<strong>е</strong>нты. Вам нужно создать набор классов, которы<strong>е</strong> будут компилироваться<br />

и работать как <strong>е</strong>диная программа. Н<strong>е</strong> обольщайт<strong>е</strong>сь, задача сложн<strong>е</strong>й, ч<strong>е</strong>м<br />

каж<strong>е</strong>тся на п<strong>е</strong>рвый взгляд!.<br />

c l a s s R ow boat ........................................ {<br />

public ........... rowTheBoatO {<br />

r e t u r n " s t r o k e n a t a s h a " ;<br />

}<br />

class ........... {<br />

private int<br />

........... void ........<br />

length = len;<br />

}<br />

public int getLengthO {<br />

}<br />

public<br />

move() {<br />

return<br />

.) {<br />

class TestBoats {<br />

........................ Main () { X<br />

}<br />

.............. Подсказка:<br />

........ Ы - new BoatO ; ЭИЛО М О Ч ~<br />

Sailboat b2 - new () ; входа<br />

Rowboat ....... =-M6WK0WBcat() ; програм ­<br />

му.<br />

b2.setLength(32) ;<br />

xyz = bl. ....... () ;<br />

xyz += b3. ....... 0 ;<br />

xyz += ...... .moveO;<br />

System.Windows .Forms .MessageBox.Show (xyz);<br />

}<br />

class ............... : Boat {<br />

}<br />

public ..................... 0 {<br />

)<br />

return " ................ " ;<br />

дальш<strong>е</strong> > 257


н<strong>е</strong>много практики<br />

А<br />

ажн<strong>е</strong>ш<strong>е</strong><br />

)^<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

c la s s А {<br />

p u b lic<br />

с ъ л <strong>е</strong> с ь „<br />

с О О <strong>е</strong> г г ^ <strong>е</strong> Н и й<br />

а = 6<br />

Ь = 5<br />

а = 5<br />

56<br />

11<br />

65<br />

c la s s В : А {<br />

virtual s t r in g ml О { p u b lic override s t r in g ml 0 {<br />

p u b lic virtual s t r in g m3() { c la s s С : В {<br />

}<br />

p u b lic override s t r in g m3() {<br />

Вы вс<strong>е</strong>гда мож<strong>е</strong>т<strong>е</strong> использовать конкр<strong>е</strong>тно<strong>е</strong> вм<strong>е</strong>сто q += b . m l ( ) ;<br />

общ<strong>е</strong>го, при наличии строчки кода, в которой тр<strong>е</strong>- q += c.m 2 () ;<br />

бу<strong>е</strong>тся класс C a n in e , можно создать ссылку на класс q += а .т З О ;<br />

A 's m l. A 's m2, C 's m 3, 6<br />

Dog. Поэтому строчка: -------------<br />

А а2 = new С О ; q += c .m l ( )<br />

B 's m l. A 's m2. A 's m3.<br />

q += с . m2 О<br />

означа<strong>е</strong>т, что вы созда<strong>е</strong>т<strong>е</strong> экз<strong>е</strong>мпляр С и ссылку из q += с .т З ()<br />

A 's m l. B ' s m2. C 's m3, 6<br />

класса А с им<strong>е</strong>н<strong>е</strong>м а 2 указывающую на н<strong>е</strong>го. Впроч<strong>е</strong>м,<br />

им<strong>е</strong>на А, а 2 и С н<strong>е</strong> оч<strong>е</strong>нь наглядны, поэтому при­<br />

B 's m l. A 's m2. C 's m3. 13<br />

q += a .m lO<br />

в<strong>е</strong>д<strong>е</strong>м н<strong>е</strong>сколько прим<strong>е</strong>ров со значимыми им<strong>е</strong>нами:<br />

B ' s m l. C 's m2, A 's m3.<br />

q += b.m2 0<br />

San dw ich m ySandwich = new B L T ();<br />

q += c.m3 0<br />

A 'S m l. B ' s m2, A 's m3.<br />

C h eese in g r e d ie n t = new A gedV erm ontC heddar( );<br />

S o n g b ir d t w e e t y = new N o r th e r n M o c k in g b ir d ( );<br />

q += a2 .m l( ) ;<br />

q += a 2 .m 2 ( ) ;<br />

q += a 2 .m 3{);<br />

B 's m l. A 's m2, C 's m3. 6<br />

A 'S m l. A 's m2, C 's m3. 13<br />

258<br />

eiHeHue j=*e^ca Б басс<strong>е</strong>йн<strong>е</strong><br />

class Rowboat^ 8oat {<br />

public string rowTheBoatO {<br />

return "stroke natasha";<br />

)<br />

)<br />

class Boat {<br />

{<br />

private int length ;<br />

public void setLength ( in t len ><br />

}<br />

length = len;<br />

public int getLengthO {<br />

return length<br />

)<br />

public virtual string move{) {<br />

return " d rift<br />

)<br />

class TestBoats {<br />

}<br />

public static void Main(){<br />

}<br />

xyz =<br />

Boat bl = new Boat();<br />

Sailboat b2 = new . .SAlXfeftat... () ;<br />

Rowboat ...l?3......= new Rowboat ();<br />

b2. setLength(32);<br />

xyz = bl. M0Ve_ 0 ;<br />

xyz += b3. .mp.V'2.. 0;<br />

xyz += b2 _.move () ;<br />

System.Windows. Forms.MessageBox.Show(xyz) ,<br />

class ..SAlib.Oat...'- Boat {<br />

)<br />

public .override string 0 {<br />

}<br />

return " hoist sail ";


насл<strong>е</strong>довани<strong>е</strong><br />

_ Часто<br />

ЧаДаБа<strong>е</strong>Мы<strong>е</strong><br />

В р<strong>е</strong>бус<strong>е</strong> в басс<strong>е</strong>йн<strong>е</strong> точка входа<br />

указывала наружу, означа<strong>е</strong>т ли это,<br />

что в программ<strong>е</strong> отсутству<strong>е</strong>т форма<br />

Forml?<br />

^ ; Для нового про<strong>е</strong>кта Windows<br />

Application, ИСР созда<strong>е</strong>т вс<strong>е</strong> н<strong>е</strong>обходимы<strong>е</strong><br />

файлы, включая файл Program.cs (сод<strong>е</strong>ржащий<br />

статич<strong>е</strong>ский класс с точкой входа),<br />

и файл Forml.CS (сод<strong>е</strong>ржащий пустую<br />

форму Forml).<br />

Попробуйт<strong>е</strong> при создании нового про<strong>е</strong>кта<br />

выбрать вариант Empty Project вм<strong>е</strong>сто<br />

Windows Application. Добавьт<strong>е</strong> файл<br />

с классами ч<strong>е</strong>р<strong>е</strong>з окно Solution Explorer<br />

и вв<strong>е</strong>дит<strong>е</strong> код из р<strong>е</strong>ш<strong>е</strong>ния р<strong>е</strong>буса в<br />

басс<strong>е</strong>йн<strong>е</strong>. Так как в программ<strong>е</strong> должно появляться<br />

окно диалога, н<strong>е</strong>обходимо добавить<br />

ссылку на форму. Щ<strong>е</strong>лкнит<strong>е</strong> правой<br />

кнопкой мыши на строчк<strong>е</strong> References в<br />

окн<strong>е</strong> Solution Explorer, выб<strong>е</strong>рит<strong>е</strong> команду<br />

Add Reference, в открывш<strong>е</strong>мся окн<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>йдит<strong>е</strong> на вкладку .NET и выб<strong>е</strong>рит<strong>е</strong><br />

строчку System.Windows.Forms. Зат<strong>е</strong>м выб<strong>е</strong>рит<strong>е</strong><br />

команду Properties в м<strong>е</strong>ню Project<br />

и укажит<strong>е</strong> в списк<strong>е</strong> output type вариант<br />

Windows Application.<br />

Запустит<strong>е</strong> программу и посмотрит<strong>е</strong> на<br />

р<strong>е</strong>зультат! Поздравля<strong>е</strong>м, вы только что<br />

создали программу с нуля!<br />

Если бллл нужно вспомнить,<br />

цто тако<strong>е</strong> м<strong>е</strong>тод Maii^O<br />

и точка входа, п<strong>е</strong>р<strong>е</strong>читайт<strong>е</strong><br />

начало главы Z.<br />

Можно ли насл<strong>е</strong>довать от класса,<br />

сод<strong>е</strong>ржащ<strong>е</strong>го точку входа?<br />

^ ! Да. Точка входа должна быть<br />

статич<strong>е</strong>ским м<strong>е</strong>тодом, но этот м<strong>е</strong>тод<br />

мож<strong>е</strong>т и н<strong>е</strong> принадл<strong>е</strong>жать к статич<strong>е</strong>скому<br />

классу. (Ключ<strong>е</strong>во<strong>е</strong> слово s t a t i c<br />

означа<strong>е</strong>т н<strong>е</strong>возможность создания экз<strong>е</strong>мпляров<br />

класса, но <strong>е</strong>го м<strong>е</strong>тоды доступны с<br />

мом<strong>е</strong>нта запуска программы. В р<strong>е</strong>бус<strong>е</strong> в<br />

басс<strong>е</strong>йн<strong>е</strong> м<strong>е</strong>тод T e s t B o a t s . M ain {)<br />

можно вызвать из любого другого м<strong>е</strong>тода<br />

б<strong>е</strong>з объявл<strong>е</strong>ния ссылочной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

или создания экз<strong>е</strong>мпляров при помощи<br />

оп<strong>е</strong>ратора new.)<br />

у» я н<strong>е</strong> понимаю, поч<strong>е</strong>му эти м<strong>е</strong>тоды<br />

называют «виртуальными», они вполн<strong>е</strong><br />

р<strong>е</strong>альны<strong>е</strong>!<br />

Q ; Ключ<strong>е</strong>во<strong>е</strong> слово virtual относится<br />

к способам обработки м<strong>е</strong>тодов в .NET.<br />

Использу<strong>е</strong>тся так называ<strong>е</strong>мая таблица<br />

виртуальных м<strong>е</strong>тодов, которая отсл<strong>е</strong>жива<strong>е</strong>т<br />

каки<strong>е</strong> м<strong>е</strong>тоды были унасл<strong>е</strong>дованы,<br />

а каки<strong>е</strong> п<strong>е</strong>р<strong>е</strong>крыты.<br />

1); Поч<strong>е</strong>му я могу двигаться по диаграмм<strong>е</strong><br />

классов только вв<strong>е</strong>рх?<br />

0 2 Классы, располож<strong>е</strong>нны<strong>е</strong> в диаграмм<strong>е</strong><br />

св<strong>е</strong>рху, являются бол<strong>е</strong><strong>е</strong> общими. Им<strong>е</strong>нно<br />

от них насл<strong>е</strong>дуют бол<strong>е</strong><strong>е</strong> д<strong>е</strong>тализированны<strong>е</strong><br />

классы (скаж<strong>е</strong>м Рубашка или<br />

Автомобиль могут насл<strong>е</strong>довать от<br />

классов Од<strong>е</strong>жда или Транспорт). Если<br />

вам нуж<strong>е</strong>н транспорт, вам подойд<strong>е</strong>т как<br />

автомобиль, так и мотоцикл или даж<strong>е</strong><br />

по<strong>е</strong>зд. Но <strong>е</strong>сли вам тр<strong>е</strong>бу<strong>е</strong>тся им<strong>е</strong>нно<br />

автомобиль, вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong> выбирать вс<strong>е</strong><br />

транспортны<strong>е</strong> ср<strong>е</strong>дства.<br />

Им<strong>е</strong>нно так работа<strong>е</strong>т насл<strong>е</strong>довани<strong>е</strong>. При<br />

наличии м<strong>е</strong>тода с парам<strong>е</strong>тром Транспорт<br />

и при условии, что класс мотоцикл<br />

насл<strong>е</strong>ду<strong>е</strong>т от класса Транспорт,<br />

вы мож<strong>е</strong>т<strong>е</strong> п<strong>е</strong>р<strong>е</strong>дать м<strong>е</strong>тоду экз<strong>е</strong>мпляр<br />

Мотоцикл. Если ж<strong>е</strong> парам<strong>е</strong>тром м<strong>е</strong>тода<br />

явля<strong>е</strong>тся Мотоцикл, вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>дать объ<strong>е</strong>кг Транспорт, так как это<br />

мож<strong>е</strong>т оказаться по<strong>е</strong>зд, и С# н<strong>е</strong> буд<strong>е</strong>т<br />

знать, что д<strong>е</strong>лать, при попытках м<strong>е</strong>тода<br />

получить доступ к свойству Руль.<br />

М<strong>е</strong>тодам, парам<strong>е</strong>тры<br />

которых работают<br />

<strong>е</strong> базовым<br />

классом, можно<br />

п<strong>е</strong>р<strong>е</strong>давать экз<strong>е</strong>мпляры<br />

производпо<br />

го класса.<br />

дальш<strong>е</strong> ► 259


они вам и в самом д<strong>е</strong>л<strong>е</strong> нужны<br />

А я н<strong>е</strong> понимаю, зач<strong>е</strong>м нужны ключ<strong>е</strong>вы<strong>е</strong> слова<br />

virtual и override. Если они отсутствуют, ИСР показыва<strong>е</strong>т<br />

пр<strong>е</strong>дупр<strong>е</strong>жд<strong>е</strong>ни<strong>е</strong>. Но программа вс<strong>е</strong> равно запуска<strong>е</strong>тся! Так какая<br />

разница? Н<strong>е</strong>т, я, кон<strong>е</strong>чно, могу писать эти слова, <strong>е</strong>сли так д<strong>е</strong>лать<br />

«правильно», но каж<strong>е</strong>тся, м<strong>е</strong>ня просто заставляют выполнять<br />

лишнюю работу.<br />

Есть важная причина!<br />

Ключ<strong>е</strong>вы<strong>е</strong> слова v i r t u a l и o v e r r id e н<strong>е</strong> являются формальностью. Они м<strong>е</strong>няют<br />

способ работы ваш<strong>е</strong>й программы. Впроч<strong>е</strong>м, мы н<strong>е</strong> заставля<strong>е</strong>м в<strong>е</strong>рить нам на<br />

слово, давайт<strong>е</strong> рассмотрим прим<strong>е</strong>р.<br />

О<br />

О<br />

На эт от раз вм<strong>е</strong>сто прилож<strong>е</strong>ния<br />

/ VJindows Forms буд<strong>е</strong>т создано<br />

f консольно<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong>! Оно н<strong>е</strong><br />

Лр^ажн<strong>е</strong>ни<strong>е</strong>!<br />

им<strong>е</strong><strong>е</strong>т формы.<br />

А/<br />

Создайт<strong>е</strong> консольно<strong>е</strong> прилож <strong>е</strong>ни<strong>е</strong>, выбрав вариант Console application.<br />

Добавьт<strong>е</strong> пять классов ч<strong>е</strong>р<strong>е</strong>з окно Solution Explorer: Je w e ls (Драгоц<strong>е</strong>нности), S a fe (С<strong>е</strong>йф),<br />

Owner (Влад<strong>е</strong>л<strong>е</strong>ц), L ocksm ith (Сл<strong>е</strong>сарь) и Je w e lT h ie f (Вор).<br />

Обратит<strong>е</strong><br />

внимани<strong>е</strong>,<br />

что слово<br />

private<br />

скрыва<strong>е</strong>т<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

contents<br />

и combination.<br />

Код для новых классов.<br />

Добавьт<strong>е</strong> сл<strong>е</strong>дующий код:<br />

c l a s s J e w e ls {<br />

p u b l i c s t r i n g S p a r k le 0 {<br />

r e t u r n " S p a r k le, s p a r k le ! " ;<br />

м<strong>е</strong>той<br />

c l a s s S a f e {<br />

p r i v a t e J e w e ls c o n t e n t s = new J e w e l s ( );<br />

p r i v a t e s t r i n g sa fe C o m b in a tio n = "12345";<br />

p u b l i c J e w e ls O p e n ( s t r in g c o m b in a tio n )<br />

{<br />

i f (c o m b in a tio n == sa fe C o m b in a tio n )<br />

}<br />

260 глава 6<br />

e l s e<br />

r e t u r n c o n t e n t s ;<br />

r e t u r n n u l l ;<br />

p u b l i c v o id P ic k L o c k (L o c k sm ith lo c k p ic k e r ) {<br />

Если при создании нового про-<br />

E n d o w s<br />

Forms application вы§р^ть вариант<br />

Console Application, ИСР c o sZ Z<br />

только новый класс с им<strong>е</strong>н<strong>е</strong>м<br />

Program, сод<strong>е</strong>ржаищй пустой м<strong>е</strong>~<br />

Z L T<br />

lo c k p ic k e r .W r ite D o w n C o m b in a tio n (sa fe C o m b in a tio n )<br />

%<br />

Лониий<br />

р м ь с я в сл<strong>е</strong>Л)н>и1их главах.<br />

Сл<strong>е</strong>сарь (Locksmith) м о­<br />

ж<strong>е</strong>т подобрать цифровую<br />

комбинацию, вызвав м<strong>е</strong>тод<br />

PickLockO и п<strong>е</strong>р<strong>е</strong>дав <strong>е</strong>му<br />

! ссылку на с<strong>е</strong>бя. При помощи<br />

это1л комбинации<br />

— с<strong>е</strong>йф вызыва<strong>е</strong>т свой м<strong>е</strong>тод<br />

VJriteDownCombination{).


c l a s s Owner {<br />

p r i v a t e J e w e ls r e tu r n e d C o n te n ts ;<br />

p u b l i c v o i d R e c e iv e C o n t e n t s ( J e w e ls s a f e C o n t e n t s )<br />

r e tu r n e d C o n te n ts = s a f e C o n t e n t s ;<br />

C o n s o le .W r it e L in e ( "Thank y o u f o r r e t u r n in g my j e w e l s !<br />

}<br />

}<br />

О Класс J e w e lT h ie f насл<strong>е</strong>ду<strong>е</strong>т от класса Locksm ith.<br />

Воры драгоц<strong>е</strong>нност<strong>е</strong>й —это бывши<strong>е</strong> сл<strong>е</strong>сари! Они могут подобрать код<br />

и открыть с<strong>е</strong>йф, но вм<strong>е</strong>сто того чтобы в<strong>е</strong>рнуть сод<strong>е</strong>ржимо<strong>е</strong> с<strong>е</strong>йфа влад<strong>е</strong>льцу,<br />

они крадут <strong>е</strong>го!<br />

c l a s s L o ck sm ith {<br />

}<br />

p u b l i c v o id O p e n S a fe (S a fe s a f e , Owner owner) {<br />

s a f e . P i c k L o c k ( t h i s ) ;<br />

J e w e ls s a f e C o n t e n t s = sa fe .O p e n (w r itte n D o w n C o r a b in a tio n );<br />

R e tu r n C o n te n ts ( s a f e C o n t e n t s , owner) ; М<strong>е</strong>тод OpenSafeQ из класса<br />

} Locksmith подбира<strong>е</strong>т ключ,<br />

открыва<strong>е</strong>т с<strong>е</strong>йф и возвраща<strong>е</strong>т<br />

<strong>е</strong>го сод<strong>е</strong>ржимо<strong>е</strong> влад<strong>е</strong>льца.<br />

p r i v a t e s t r i n g w ritten D o w n C o m b in a tio n = n u l l ;<br />

p u b l i c v o id W r ite D o w n C o m b in a tio n (str in g c o m b in a tio n ) {<br />

}<br />

w ritten D o w n C o m b in a tio n = c o m b in a tio n ;<br />

p u b l i c v o i d R e tu r n C o n te n ts (J e w e ls s a f e C o n t e n t s , Owner owner) {<br />

}<br />

o w n e r .R e c e iv e C o n t e n t s ( s a f e C o n t e n t s ) ;<br />

c l a s s J e w e lT h ie f : L o ck sm ith {<br />

p r i v a t e J e w e ls s t o l e n J e w e l s = n u l l ;<br />

p u b l i c v o i d R e tu r n C o n te n ts (J e w e ls s a f e C o n t e n t s , Owner owner) {<br />

s t o l e n J e w e l s = s a f e C o n t e n t s ;<br />

C o n s o le .W r it e L in e ( "I'm s t e a l i n g t h e c o n t e n t s !<br />

{<br />

'<br />

насл<strong>е</strong>довани<strong>е</strong><br />

+ s a f e C o n t e n t s . S p a r k l e ( ) ) ;<br />

Locksmith<br />

OpenSafeO<br />

WriteDownCombinationO<br />

Return ContentsO<br />

JewelThief<br />

private stolenJewels<br />

ReturnContentsO<br />

s t o l e n J e w e l s . S p a r k l e ( ) ) ;<br />

}<br />

Объ<strong>е</strong>кт JewelThief насл<strong>е</strong>ду<strong>е</strong>т<br />

м<strong>е</strong>тоды OpenSafeQ<br />

}<br />

и WriteDownCombinationQ. Ho<br />

О М <strong>е</strong>тод M ainO для класса Program.<br />

когда м<strong>е</strong>тод OpenSafeQ вызы-<br />

П^и<strong>е</strong>затгуасайт<strong>е</strong>про<strong>е</strong>ражчуШолробуйт<strong>е</strong>угадать, что буд<strong>е</strong>т<br />

написано в консоли. , блдЭ<strong>е</strong>л<strong>е</strong>?цу> вор их забира<strong>е</strong>т с<strong>е</strong>б<strong>е</strong>!<br />

c l a s s Program {<br />

s t a t i c v o id M a i n ( s t r i n g [] a r g s)<br />

М<strong>е</strong>тод „ ^<br />

ReadKeyQ н<strong>е</strong> Owner () ;<br />

допуска<strong>е</strong>т S a fe s a f e = new S a f e O ;<br />

зав<strong>е</strong>рш<strong>е</strong>ния<br />

программы<br />

пока пользоват<strong>е</strong>ль<br />

н<strong>е</strong> нажм<strong>е</strong>т C o n so le.R ea d K ey O ;<br />

клавиилу. }<br />

}<br />

J e w e lT h ie f j e w e lT h ie f = new J e w e l T h i e f О<br />

j e w e lT h ie f .O p e n S a f e ( s a f e , o v m e r );<br />

{ возьми 6 руку карандаш<br />

Внимат<strong>е</strong>льно посмотрит<strong>е</strong> код программы<br />

и запишит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong>, которо<strong>е</strong> появится<br />

в консоли. (Подсказка: Опр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong>, каки<strong>е</strong><br />

свойства класс J e w e lT h ie f насл<strong>е</strong>ду<strong>е</strong>т от<br />

класса L ocksm ith!)<br />

%<br />

дальш<strong>е</strong> k 261


скры т ь и обнаружит ь<br />

Произбодный класс ум<strong>е</strong><strong>е</strong>т скрыбать м<strong>е</strong>тоды<br />

Запустит<strong>е</strong> пpoгpaммyJewelThief. Так как это консольно<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong>, вывод р<strong>е</strong>зультатов осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

ч<strong>е</strong>р<strong>е</strong>з командно<strong>е</strong> окно. Вот как это выглядит:<br />

file;///C:/Usera/aftctraw/Dgcuwents/V№ttai Studio aaiO/Pfojerts/Chapttr 6 соё<strong>е</strong>/lawei<br />

rhank you for 3*etmining jew els! S p a rk le , sp a rk le !<br />

Вы ожидали, что программа напиш<strong>е</strong>т ко<strong>е</strong>-что друго<strong>е</strong>? Наприм<strong>е</strong>р:<br />

I'm s t e a l i n g t h e c o n t e n t s ! S p a r k le , s p a r k le ! (Я краду д р агоц <strong>е</strong>н н ости ! К руто!)<br />

Но каж<strong>е</strong>тся, наш вор JewelThief повторя<strong>е</strong>т д<strong>е</strong>йствия сл<strong>е</strong>саря Locksmith! Как это могло произойти?<br />

Сравн<strong>е</strong>ни<strong>е</strong> скрытия ип<strong>е</strong>р<strong>е</strong>крытия м<strong>е</strong>тодов<br />

Причиной, по которой объ<strong>е</strong>кт J e w e l T h i e f при вызов<strong>е</strong> м<strong>е</strong>тода R e t u r n C o n t e n t s {) в<strong>е</strong>д<strong>е</strong>т с<strong>е</strong>бя как объ<strong>е</strong>кт<br />

L o c k s m it h , явля<strong>е</strong>тся способ, которым класс J e w e l T h i e f объявил этот м<strong>е</strong>тод. Подсказка находится<br />

в пр<strong>е</strong>дупр<strong>е</strong>жд<strong>е</strong>ниях, которы<strong>е</strong> посыла<strong>е</strong>т прилож<strong>е</strong>ни<strong>е</strong>:<br />

О О Errors ji ^ 1 Warning О Messages [<br />

Description<br />

A 1<br />

'iewel_Thief J«ive(Thtef.ReturnContentsCJewel_Thief.Jewets, Jewel_Thief.Owner)‘ hides inherited member<br />

'ieweLThief.Locksmith.ReturnContents(jewel_Thief,Jewels, Jewel_Thief.Owner)'. To make the current member<br />

override that implementation, add the override keyword. Othenwise add the new keyword.<br />

Так как класс J e w e l T h i e f насл<strong>е</strong>ду<strong>е</strong>т от класса L o c k s m i t h<br />

и по ид<strong>е</strong><strong>е</strong> зам<strong>е</strong>ща<strong>е</strong>т м<strong>е</strong>тод R e t u r n C o n t e n t s () своим собств<strong>е</strong>нным,<br />

каж<strong>е</strong>тся, что этот м<strong>е</strong>тод п<strong>е</strong>р<strong>е</strong>крыва<strong>е</strong>тся. Но на<br />

самом д<strong>е</strong>л<strong>е</strong> это н<strong>е</strong> так. Объ<strong>е</strong>кт J e w e l T h i e f скрыва<strong>е</strong>т м<strong>е</strong>тод<br />

R e t u r n C o n t e n t s ().<br />

При скрытии производный класс зам<strong>е</strong>ща<strong>е</strong>т (т<strong>е</strong>хнич<strong>е</strong>ски<br />

он «п<strong>е</strong>р<strong>е</strong>объявля<strong>е</strong>т») одноим<strong>е</strong>нный м<strong>е</strong>тод базового класса.<br />

В итог<strong>е</strong> в производном класс<strong>е</strong> оказываются два м<strong>е</strong>тода<br />

с одинаковым им<strong>е</strong>н<strong>е</strong>м: один унасл<strong>е</strong>дованный и один опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нный<br />

самостоят<strong>е</strong>льно.<br />

Если имя и сигнатура создава<strong>е</strong>мого<br />

м<strong>е</strong>тода совпада<strong>е</strong>т<br />

с им<strong>е</strong>н<strong>е</strong>м и сигнатурой<br />

насл<strong>е</strong>ду<strong>е</strong>мых м<strong>е</strong>тодов, новый<br />

м<strong>е</strong>тод производного<br />

класса скрыва<strong>е</strong>т м<strong>е</strong>тод<br />

базового класса.<br />

262 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Для бызоВа скры ты х м<strong>е</strong>тодов используйт<strong>е</strong> различны<strong>е</strong> ссылки<br />

Объ<strong>е</strong>кт J e w e l T h i e f скрыва<strong>е</strong>т м<strong>е</strong>тод R e t u r n C o n t e n t s (), что заставля<strong>е</strong>т <strong>е</strong>го д<strong>е</strong>йствовать как объ<strong>е</strong>кт<br />

L o c k s m it h . Одну в<strong>е</strong>рсию данного м<strong>е</strong>тода объ<strong>е</strong>кт J e w e l T h i e f насл<strong>е</strong>ду<strong>е</strong>т от объ<strong>е</strong>кта L o c k s m it h , зат<strong>е</strong>м<br />

он опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т вторую собств<strong>е</strong>нную в<strong>е</strong>рсию, и в итог<strong>е</strong> мы им<strong>е</strong><strong>е</strong>м два разных м<strong>е</strong>тода с одинаковыми им<strong>е</strong>нами.<br />

Это означа<strong>е</strong>т, что нужны различны<strong>е</strong> способы их вызова.<br />

На самом д<strong>е</strong>л<strong>е</strong> при наличии экз<strong>е</strong>мпляра J e w e l T h i e f для вызова нового м<strong>е</strong>тода R e t u r n C o n t e n t s О<br />

можно использовать ссылочную п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную J e w e l T h i e f . А <strong>е</strong>сли для вызова использу<strong>е</strong>тся ссылочная<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная L o c k s m it h , буд<strong>е</strong>т вызван скрытый м<strong>е</strong>тод R e t u r n C o n t e n t s {).<br />

// Производный класс J e w e lT h ie f скрыва<strong>е</strong>т м<strong>е</strong>тод базового класса L o ck sm ith ,<br />

// поэтому вы мож<strong>е</strong>т<strong>е</strong> увид<strong>е</strong>ть пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> одного объ<strong>е</strong>кта<br />

// в зависимости от того, какой ссылкой он вызыва<strong>е</strong>тся!<br />

// При вызов<strong>е</strong> объ<strong>е</strong>кта J e w e lT h ie f ссылочной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной L o ck sm ith вызыва<strong>е</strong>т<br />

// м<strong>е</strong>тод R e tu r n C o n te n tsO из базового класса<br />

L o ck sm ith c a lle d A s L o c k s m ith = new J e w e l T h i e f ( );<br />

c a lle d A s L o c k s m it h .R e t u r n C o n t e n ts ( s a f e C o n t e n t s , o w n e r );<br />

// При вызов<strong>е</strong> объ<strong>е</strong>кта J e w e lT h ie f ссылочной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной J e w e lT h ie f вызыва<strong>е</strong>тся<br />

// <strong>е</strong>го собств<strong>е</strong>нный м<strong>е</strong>тод R e tu r n C o n te n ts ( ), а одноим<strong>е</strong>нный м<strong>е</strong>тод<br />

//из базового класса скрыва<strong>е</strong>тся.<br />

J e w e lT h ie f c a lle d A s J e w e lT h ie f = new J e w e l T h ie f О ;<br />

c a lle d A s J e w e lT h ie f .R e t u r n C o n t e n t s ( s a f e C o n t e n t s , o w n e r );<br />

Скрывая м<strong>е</strong>тоды, пользуйт<strong>е</strong>сь ключ<strong>е</strong>вым словом new<br />

Внимат<strong>е</strong>льно прочитайт<strong>е</strong> это пр<strong>е</strong>дупр<strong>е</strong>жд<strong>е</strong>ни<strong>е</strong>. Мы зна<strong>е</strong>м, что пр<strong>е</strong>дупр<strong>е</strong>жд<strong>е</strong>ния никто н<strong>е</strong> чита<strong>е</strong>т, но на<br />

этот раз сд<strong>е</strong>лайт<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong>. Чтобы осущ<strong>е</strong>ствить т<strong>е</strong>кугцую р<strong>е</strong>ализацию, добавьт<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong> слово<br />

override. Если пр<strong>е</strong>дполага<strong>е</strong>тся сокрыти<strong>е</strong>, используйт<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong> слово new.<br />

В<strong>е</strong>рн<strong>е</strong>мся в программу и добавим ключ<strong>е</strong>во<strong>е</strong> слово new.<br />

new p u b l i c v o id R e tu r n C o n te n ts (J e w e ls s a f e C o n t e n t s , Owner ow ner) {<br />

Сразу ж<strong>е</strong> посл<strong>е</strong> этого сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong> исч<strong>е</strong>зн<strong>е</strong>т. Хотя программа вс<strong>е</strong> равно н<strong>е</strong> стан<strong>е</strong>т работать так,<br />

как нужно! По-пр<strong>е</strong>жн<strong>е</strong>мувызыва<strong>е</strong>тся м<strong>е</strong>тод R e t u r n C o n t e n t s ( ) , опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нный для объ<strong>е</strong>кта L o c k s m it h .<br />

Поч<strong>е</strong>му так происходит? Д<strong>е</strong>ло в том, что вызов этого м<strong>е</strong>тода осущ<strong>е</strong>ствля<strong>е</strong>тся ч<strong>е</strong>р<strong>е</strong>з м<strong>е</strong>тод, опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нный<br />

в класс<strong>е</strong> Locksmith, а им<strong>е</strong>нно ч<strong>е</strong>р<strong>е</strong>з L o c k s m i t h . O p e n S a f e (), н<strong>е</strong>смотря на то, что <strong>е</strong>го начальны<strong>е</strong> знач<strong>е</strong>ния<br />

были заданы в класс<strong>е</strong> J e w e l T h i e f . Если бы J e w e l T h i e f просто скрывал м<strong>е</strong>тод R e t u r n C o n t e n t s () из<br />

базового класса, <strong>е</strong>го собств<strong>е</strong>нный м<strong>е</strong>тод R e t u r n C o n t e n t s () никогда бы н<strong>е</strong> был вызван.<br />

П о д у м а й т <strong>е</strong> , к а к з а с т а в и т ь о б ъ <strong>е</strong> к т J e w e lT h ie f п <strong>е</strong> р <strong>е</strong> к р ы т ь , а н <strong>е</strong> с к р ы т ь м <strong>е</strong> т о д<br />

R e tu rn C o n te n ts O ? С м о ж <strong>е</strong> т <strong>е</strong> д о г а д а т ь с я д о т о го , к а к п <strong>е</strong> р <strong>е</strong> в <strong>е</strong> р н <strong>е</strong> т <strong>е</strong> с т р а н и ц у ?<br />

дальш<strong>е</strong> > 263


так вот зач<strong>е</strong>м нуж ны эт и клю ч<strong>е</strong>вы <strong>е</strong> слова<br />

Ключ<strong>е</strong>бы<strong>е</strong> сдоба override и virtual<br />

Нам тр<strong>е</strong>бу<strong>е</strong>тся, чтобы класс J e w e l T h i e f вс<strong>е</strong>гда использовал свой собств<strong>е</strong>нный м<strong>е</strong>тод R e t u r n ­<br />

C o n t e n t s О , вн<strong>е</strong> зависимости от способа вызова. Им<strong>е</strong>нно так долж<strong>е</strong>н работать м<strong>е</strong>ханизм насл<strong>е</strong>дования,<br />

и им<strong>е</strong>нно это называ<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong>м. Вы мож<strong>е</strong>т<strong>е</strong> л<strong>е</strong>гко заставить класс это сд<strong>е</strong>лать. Для начала<br />

воспользуйт<strong>е</strong>сь ключ<strong>е</strong>вым словом o v e r r id e при объявл<strong>е</strong>нии м<strong>е</strong>тода R e t u r n C o n t e n t s ():<br />

class JewelThief {<br />

override public void ReturnContents<br />

(Jewels safeContents, Owner owner)<br />

Ho этого н<strong>е</strong>достаточно. Попытавшись скомпилировать программу, вы получит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>:<br />

Error List<br />

O 1 Error I j \ 0 Warntngs j ij) 0 Messages<br />

П X<br />

O 1<br />

, Description<br />

.... . . , .. ..............<br />

'ieweLThief.JewelThief.ReturnCor?tetitsPewel_Thief.JwelSi Jewel_Thief,Owner}'; cannot override irtherited member<br />

'Jewel_Thief.Locksmith,ReturnContentsOewetThief Jewete, iewel_Thief.Owner)’ because it is not marked virtual, abstract, or override<br />

Сообщ<strong>е</strong>ни<strong>е</strong> пр<strong>е</strong>дупр<strong>е</strong>жда<strong>е</strong>т, что объ<strong>е</strong>кт J e v ^ e lT h ie f н<strong>е</strong> мож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>крыть унасл<strong>е</strong>дованный м<strong>е</strong>тод<br />

R e t u r n C o n t e n t s {) из-за отсутствия ключ<strong>е</strong>вых слов v i r t u a l , a b s t r a c t или o v e r r i d e в объявл<strong>е</strong>нии<br />

класса L o c k s m it h . Эту ошибку л<strong>е</strong>гко исправить! Используйт<strong>е</strong> в объявл<strong>е</strong>нии м<strong>е</strong>тода R e t u r n C o n t e n t s ()<br />

в класс<strong>е</strong> L o c k s m i t h ключ<strong>е</strong>во<strong>е</strong> слово v i r t u a l .<br />

class Locksmith {<br />

virtual public void ReturnContents<br />

(Jewels safeContents, Owner owner)<br />

Т<strong>е</strong>п<strong>е</strong>рь, запустив программу, вы увидит<strong>е</strong> сл<strong>е</strong>дующ<strong>е</strong><strong>е</strong>:<br />

ijifile;///C;/Users/andrew/Documents,/V'suat Studio 2010/Projects/Chepter 6 code/Jewel Thief/bin/De... Г сз^Г<br />

ing the c o n te n ts! Spas'kle, s p a r k le ?<br />

Этого мы и добивались!<br />

264 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

Им<strong>е</strong>нно так. В большинств<strong>е</strong> случа<strong>е</strong>в<br />

м<strong>е</strong>тоды тр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>крывать,<br />

но им<strong>е</strong><strong>е</strong>тся и возможность скрыть их.<br />

Работая с производным классом, который явля<strong>е</strong>тся<br />

расшир<strong>е</strong>ни<strong>е</strong>м базового, вы, скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го,<br />

буд<strong>е</strong>т<strong>е</strong> использовать п<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> м<strong>е</strong>тодов. Поэтому,<br />

<strong>е</strong>сли вы зам<strong>е</strong>тили, что компилятор пр<strong>е</strong>дупр<strong>е</strong>жда<strong>е</strong>т<br />

о скрытии м<strong>е</strong>тодов, н<strong>е</strong> оставляйт<strong>е</strong><br />

это б<strong>е</strong>з внимания! Подумайт<strong>е</strong>, д<strong>е</strong>йствит<strong>е</strong>льно<br />

ли вы хотит<strong>е</strong> скрыть м<strong>е</strong>тод или, мож<strong>е</strong>т быть,<br />

вы просто забыли написать ключ<strong>е</strong>вы<strong>е</strong> слова<br />

v i r t u a l и o v e rrid e . Корр<strong>е</strong>ктно<strong>е</strong> использовани<strong>е</strong><br />

ключ<strong>е</strong>вых слов v i r t u a l , o v e r r id e и new<br />

позволя<strong>е</strong>т изб<strong>е</strong>жать пробл<strong>е</strong>м, с которыми вы<br />

столкнулись в посл<strong>е</strong>дн<strong>е</strong>й программ<strong>е</strong>!<br />

Чтобы п<strong>е</strong>р<strong>е</strong>крыть м<strong>е</strong>тод<br />

базового класса, вс<strong>е</strong>гда<br />

пом<strong>е</strong>чайт<strong>е</strong> <strong>е</strong>го ключ<strong>е</strong>вым<br />

словом virtual.<br />

И вс<strong>е</strong>гда используйт<strong>е</strong><br />

ключ<strong>е</strong>во<strong>е</strong> слово<br />

override, когда хотит<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>крыть м<strong>е</strong>тод в<br />

производном класс<strong>е</strong>.<br />

Если это н<strong>е</strong> сд<strong>е</strong>лать,<br />

н<strong>е</strong>которы<strong>е</strong> м<strong>е</strong>тоды вн<strong>е</strong>запно<br />

могут оказаться<br />

скрытыми.<br />

дальш<strong>е</strong> ► 265


обходнойпуть<br />

Ключ<strong>е</strong>бо<strong>е</strong> сдобо base<br />

Иногда возника<strong>е</strong>т н<strong>е</strong>обходимость доступа к п<strong>е</strong>р<strong>е</strong>крытым м<strong>е</strong>тодам или свойствам<br />

базового класса. К счастью, сущ<strong>е</strong>ству<strong>е</strong>т ключ<strong>е</strong>во<strong>е</strong> слово b a se, дающ<strong>е</strong><strong>е</strong><br />

доступ к любым м<strong>е</strong>тодам базового класса.<br />

Vertebrate<br />

МитЬ<strong>е</strong>ЮЯ-<strong>е</strong>дз<br />

Q<br />

Вс<strong>е</strong> животны<strong>е</strong> <strong>е</strong>дят, поэтом класс V e r te b r a te (Позвоночны<strong>е</strong>) долж<strong>е</strong>н<br />

им<strong>е</strong>ть м<strong>е</strong>тод E at (), в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра которого использу<strong>е</strong>тся<br />

объ<strong>е</strong>кт Food (Еда).<br />

c l a s s V e r t e b r a t e {<br />

p u b l i c v i r t u a l v o i d E a t(F o o d m o r se l) {<br />

S w a llo w ( m o r s e l) ;<br />

D i g e s t ( );<br />

Eat(j<br />

SwallowO<br />

DigestO<br />

©<br />

О<br />

Хам<strong>е</strong>л<strong>е</strong>оны ловят пищу языком. Поэтому класс Cham eleon насл<strong>е</strong>ду<strong>е</strong>т от класса V e r te b r a te ,<br />

п<strong>е</strong>р<strong>е</strong>писывая при этом м<strong>е</strong>тод E at ().<br />

c l a s s Cham eleon : V e r t e b r a t e {<br />

}<br />

p u b l i c o v e r r id e v o i d E a t(F o o d m o r se l) {<br />

C a tc h W ith T o n g u e (m o r se l);<br />

S w a llo w (m o r se l)<br />

}<br />

D i g e s t ( );<br />

Воспользуйт<strong>е</strong>сь ключ<strong>е</strong>вым словом b a s e для вызова п<strong>е</strong>р<strong>е</strong>крытого м<strong>е</strong>тода и вы получит<strong>е</strong> доступ<br />

как к новой, так и к старой в<strong>е</strong>рсии м<strong>е</strong>тода E at ().<br />

c l a s s Cham eleon : V e r t e b r a t e {<br />

}<br />

p u b l i c o v e r r id e v o i d E a t(F o o d m o r se l) {<br />

C atchW ithT ongue (m o rsel) ; строчка вызыва<strong>е</strong>т м <strong>е</strong>-<br />

b a s e .E a t( m o r s e l); -------" mod Eat 0 w3 базового класса,<br />

^ om которого ипгАРМ<strong>е</strong>т насл<strong>е</strong>ду<strong>е</strong>т объ<strong>е</strong>кт<br />

Chameleon.<br />

Вы получили н<strong>е</strong>которо<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> о проц<strong>е</strong>дур<strong>е</strong> насл<strong>е</strong>дования, но мож<strong>е</strong>т<strong>е</strong> ли вы рассказать,<br />

каким образом насл<strong>е</strong>довани<strong>е</strong> обл<strong>е</strong>гча<strong>е</strong>т р<strong>е</strong>дактировани<strong>е</strong> кода в будущ<strong>е</strong>м?<br />

266 глава 6


Если В базоВом класс<strong>е</strong> присутству<strong>е</strong>т конструктор, он дол)к<strong>е</strong>н остаться<br />

U В производном класс<strong>е</strong><br />

добавь^<br />

Если в класс<strong>е</strong> присутствуют конструкторы, то вс<strong>е</strong> классы, кото- н<strong>е</strong>ц обьявл<strong>е</strong>ш^ ‘^‘^Року в коры<strong>е</strong><br />

от н<strong>е</strong>го насл<strong>е</strong>дуют, д о л ж н ы в ы з ы в а т ь х о т я б ы о д и н и з э т и х ра npj}u36adH ozo°i^^^'^‘^ ° ~<br />

к о н с т р у к т о р о в . При этом конструктор производного класса мо- "б д <strong>е</strong>^<br />

ж<strong>е</strong>т им<strong>е</strong>ть свои собств<strong>е</strong>нны<strong>е</strong> парам<strong>е</strong>тры. т о в Т а л консплоиь'<br />

Р « 3 оазового класса<br />

class Subclass : BaseClass {<br />

ч<br />

-^public Subclass(список парам<strong>е</strong>тров)<br />

Это кон- : base(список парам<strong>е</strong>тров базового класса) {<br />

структор<br />

производного I I сначала вьшолня<strong>е</strong>тся конструктор базового классса<br />

класса.<br />

/ / а потом вс<strong>е</strong> остальны<strong>е</strong> оп<strong>е</strong>раторы<br />

насл<strong>е</strong>довани<strong>е</strong><br />

Конструктор базового класса Вы зы ва<strong>е</strong>тся п<strong>е</strong>рвым ^ У п р а ж н <strong>е</strong> н и <strong>е</strong> !<br />

Уб<strong>е</strong>дит<strong>е</strong>сь в этом сами!<br />

О Создайт<strong>е</strong> базовый класс с конструктором, вызывающим окно д иалога<br />

Добавьт<strong>е</strong> к форм<strong>е</strong> кнопку, которая инициализиру<strong>е</strong>т базовый класс и вызыва<strong>е</strong>т окно диалога:<br />

©<br />

_<br />

c l a s s M yB aseC lass {<br />

p u b l i c M y B a s e C la s s (s tr in g b a s e C la s s N e e d s T h is ) {<br />

M essa g eB o x .S h o w (" T h is i s t h e b a s e c l a s s : " + b a s e C la s s N e e d s T h is ) ;<br />

,<br />

}<br />

Этот парам<strong>е</strong>тр нуж<strong>е</strong>н<br />

'<br />

базовому конструктору.<br />

_ „ ч- Эта ошибка<br />

Добавьт<strong>е</strong> производиыи класс, но н<strong>е</strong> вызывайт<strong>е</strong> конструктор<br />

означа<strong>е</strong>т, что<br />

Добавьт<strong>е</strong> к форм<strong>е</strong> кнопку, которая д<strong>е</strong>ла<strong>е</strong>т то ж<strong>е</strong> само<strong>е</strong> для производного класса: производный<br />

ґ ^ с і а з з M ySub class<br />

: M y B a seC la ss{<br />

Выб<strong>е</strong>рит<strong>е</strong> К О - p u b l i c M y S u b c la s s ( s t r in g b a s e C la s s N e e d s T h is , i n t a n o th e r V a lu e ) { ^ о б в<br />

манду Build » M essageB ox. show (" T h is i s t h e s u b c la s s : " + b a s e C la s s N e e d s T h is ^^/^^acca<br />

Build Solution, + « and " + a n o th e r V a lu e ) ; ч<br />

u Ш получи- ________________________ ____________________________ )<br />

Me сообіц<strong>е</strong>ни<strong>е</strong> a 1 No overload for m ethod 'MyBaseClass' takes 'O' argum ents ^ -------------------- -—<br />

об ошибк<strong>е</strong>. }<br />

© Заставьт<strong>е</strong> сначала вызывать конструктор из базового класса<br />

Зат<strong>е</strong>м инициализируйт<strong>е</strong> производный класс и посмотрит<strong>е</strong>, в каком порядк<strong>е</strong> появятся<br />

два окна диалога!<br />

c l a s s M y S u b cla ss<br />

: M y B a seC la ss{<br />

Так МЫ послали p u b l i c M y S u b c la s s ( s t r in g b a s e C la s s N e e d s T h is , i n t a n o th e r V a lu e ) базовобазовому<br />

классу ; b a s e (b a s e C la s s N e e d s T h is ) с т р о к а вызов<strong>е</strong>т. ошибк<strong>е</strong><br />

парам<strong>е</strong>тр, ко- ^ го класса, ^ о г о сооОЩ работать,<br />

торыи т р<strong>е</strong>бу<strong>е</strong>т - ц „<strong>е</strong> изм<strong>е</strong>нился исч<strong>е</strong>зн<strong>е</strong>т, и программ<br />

ся <strong>е</strong>го конструктору.<br />

д а л ь ш <strong>е</strong> * 2 6 7


кэтлин вс<strong>е</strong> <strong>е</strong>щ<strong>е</strong> нужна ваша помощь<br />

Т<strong>е</strong>п<strong>е</strong>рь мы готовы зав<strong>е</strong>ршить программу для Кэтлин!<br />

Посл<strong>е</strong> посл<strong>е</strong>дн<strong>е</strong>го обновл<strong>е</strong>ния программа Кэтлин<br />

получила возможность рассчитывать стоимость<br />

дн<strong>е</strong>й рожд<strong>е</strong>ния. Т<strong>е</strong>п<strong>е</strong>рь Кэтлин хоч<strong>е</strong>т<br />

брать <strong>е</strong>щ<strong>е</strong> по $100 за в<strong>е</strong>ч<strong>е</strong>ринки с колич<strong>е</strong>ством<br />

гост<strong>е</strong>й больш<strong>е</strong> 12. Сначала казалось, что вам<br />

прид<strong>е</strong>тся набирать в<strong>е</strong>сь код заново, но т<strong>е</strong>п<strong>е</strong>рь,<br />

познакомившись с проц<strong>е</strong>дурой насл<strong>е</strong>дования,<br />

вы зна<strong>е</strong>т<strong>е</strong>, как этого изб<strong>е</strong>жать.<br />

DinnerParty<br />

NumberOfPeople<br />

CostOfDecorations<br />

CostOfBeveragesPerPerson<br />

HealthyOption<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

SetHealthyOptionO<br />

BirthdayParty<br />

NumberOfPeople<br />

CostOroecorations<br />

CakeSize<br />

CakeWriting<br />

CalculateCostOroecorationsO<br />

CalculateCostO<br />

йражн<strong>е</strong>ни<strong>е</strong><br />

Е с л и в с <strong>е</strong> с д <strong>е</strong> л а т ь п р а в и л ь н о , д о с т а т о ч н о б у д <strong>е</strong> т<br />

о т р <strong>е</strong> д а к т и р о в а т ь д в а к л а с с а , н <strong>е</strong> з а т р а ги в а я с а м у ф о р м у !<br />

О Новая мод<strong>е</strong>ль классов<br />

У нас останутся классы D i n n e r P a r t y и B i r t h d a y P a r t y , но т<strong>е</strong>п<strong>е</strong>рь они будут насл<strong>е</strong>довать от<br />

<strong>е</strong>диного класса P a r t y . Так как эти м<strong>е</strong>тоды должны им<strong>е</strong>ть одинаковы<strong>е</strong> свойства, м<strong>е</strong>тоды и поля,<br />

р<strong>е</strong>дактировать форму н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся. Просто н<strong>е</strong>которы<strong>е</strong> парам<strong>е</strong>тры п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>стятся в базовый<br />

класс P a r t y , и мы буд<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>крывать их по м<strong>е</strong>р<strong>е</strong> н<strong>е</strong>обходимости.<br />

Party<br />

NumberOfPeople<br />

CostOfDecorations<br />

CalculateCostOroecorationsO<br />

CalculateCostO<br />

DinnerParty<br />

BirthdayParty<br />

NumberOfPeople к NumberOfPeople<br />

?■<br />

CostOroecorations<br />

CostOroecorations<br />

CostOfBeveragesPerPerson CakeSize<br />

HealthyOption t CakeWriting<br />

CalculateCostOroecorationsO CalculateCostOfDecorationsO<br />

CalculateCostO<br />

CalculateCostO<br />

SetHealthyOptionO<br />

268 глава б


о Б<br />

а з « .я й клосс P a rty<br />

Создайт<strong>е</strong> класс P a r ty и укажит<strong>е</strong> уров<strong>е</strong>нь доступа public. Рассмотрим диаграмму<br />

классов и р<strong>е</strong>шим, каки<strong>е</strong> свойства и м<strong>е</strong>тоды сл<strong>е</strong>ду<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>н<strong>е</strong>сти из классов<br />

D in n e rP a rty и B ir th d a y P a r ty в класс P a rty .<br />

★<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>стит<strong>е</strong> свойства Num berO fPeople и C o stO fD e c o ra tio n s, так как<br />

они опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ны как для D in n e rP a rty , так и для B irth d a y P a rty .<br />

★ Прод<strong>е</strong>лайт<strong>е</strong> то ж<strong>е</strong> само<strong>е</strong> с м<strong>е</strong>тодами C a lc u la te C o stO fD e c o ra tio n sO<br />

и C a lc u la te C o st (). Н<strong>е</strong> забудьт<strong>е</strong> п<strong>е</strong>р<strong>е</strong>н<strong>е</strong>сти и закрыты<strong>е</strong> поля, н<strong>е</strong>обходи-<br />

Вскор<strong>е</strong> вы по-<br />

м<strong>е</strong>тодов. (Помнит<strong>е</strong>, что производны<strong>е</strong> классы видят только<br />

знакомит <strong>е</strong>сь------ 3 ^ „ г. ^<br />

с ключ<strong>е</strong>вым ПОЛЯ общ<strong>е</strong>го доступа. Посл<strong>е</strong> п<strong>е</strong>р<strong>е</strong>носа закрытого поля в класс P a rty , классловом<br />

protected. D in n e rP a rty и B irth d a y P a rty пот<strong>е</strong>ряют к н<strong>е</strong>му доступ.)<br />

п о л <strong>е</strong> °^я^п р о и ^ ^<br />

потр<strong>е</strong>бу<strong>е</strong>тся конструктор. Внимат<strong>е</strong>льно посмотрит<strong>е</strong> на конводного<br />

класса, структоры B ir th d a y P a r ty и D in n e rP a rty : н<strong>е</strong> им<strong>е</strong>ют ли они что-нибудь<br />

осмавляя <strong>е</strong>го общ<strong>е</strong><strong>е</strong>.<br />

закрытым для<br />

вс<strong>е</strong>го осталь- Т<strong>е</strong>п<strong>е</strong>рь добавим плат<strong>е</strong>ж $100 к м<strong>е</strong>роприятиям с колич<strong>е</strong>ством гост<strong>е</strong>й боного.<br />

л<strong>е</strong><strong>е</strong> 12. Это каса<strong>е</strong>тся как званых об<strong>е</strong>дов, так и дн<strong>е</strong>й рожд<strong>е</strong>ния, поэтому<br />

пом<strong>е</strong>стим этот плат<strong>е</strong>ж в класс Party.<br />

О П усть класс D innerP arty насл<strong>е</strong>ду<strong>е</strong>т от класса P a rty<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда класс P a r ty взял на с<strong>е</strong>бя часть функций класса D in n e rP a rty , в посл<strong>е</strong>дн<strong>е</strong>м<br />

можно оставить только функции, связанны<strong>е</strong> с об<strong>е</strong>дами.<br />

★<br />

★<br />

★<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что конструктор работа<strong>е</strong>т. Он д<strong>е</strong>ла<strong>е</strong>т что-то, ч<strong>е</strong>го н<strong>е</strong> д<strong>е</strong>ла<strong>е</strong>т<br />

конструктор класса P a rty ? Оставьт<strong>е</strong> только эти функции.<br />

Вс<strong>е</strong> парам<strong>е</strong>тры и м<strong>е</strong>тоды варианта Healthy Option должны остаться в класс<strong>е</strong><br />

D in n e rP arty .<br />

Если мы хотим сохранить код формы, то н<strong>е</strong> смож<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>крыть м<strong>е</strong>тод Эта проц<strong>е</strong>дура<br />

C a lc u la te C o s t (), так как форма должна п<strong>е</strong>р<strong>е</strong>дать в н<strong>е</strong>го логич<strong>е</strong>скую п<strong>е</strong>- называ<strong>е</strong>тся^^^<br />

р<strong>е</strong>м<strong>е</strong>нную h e a lth y O p tio n . Поэтому мы просто добавим в класс <strong>е</strong>щ<strong>е</strong> один<br />

м<strong>е</strong>тод C a lc u la te C o s t О , работающий с другими парам<strong>е</strong>трами. Исполь- Д^^сддотр<strong>е</strong>нй<br />

зуйт<strong>е</strong> для <strong>е</strong>го объявл<strong>е</strong>ния код из начала данной главы. Т<strong>е</strong>п<strong>е</strong>рь запись b a s e . ^ глав<strong>е</strong> 8.<br />

C a lc u la te C o s tO дастдоступ к м<strong>е</strong>тоду C a lc u la te C o s t () в класс<strong>е</strong> P a rty .<br />

О Пусть класс B irth d ayP arty такж <strong>е</strong> насл<strong>е</strong>ду<strong>е</strong>т от класса P a rty<br />

Для класса B ir th d a y P a r ty пров<strong>е</strong>дит<strong>е</strong> аналогичную проц<strong>е</strong>дуру, п<strong>е</strong>р<strong>е</strong>н<strong>е</strong>ся вс<strong>е</strong> общи<strong>е</strong><br />

признаки в базовый класс.<br />

★<br />

Каки<strong>е</strong> д<strong>е</strong>йствия конструктора B ir th d a y P a r ty н<strong>е</strong> являются частью класса<br />

P arty ?<br />

★ Вам нужно посчитать стоимость торта внутри класса B irth d a y P a rty .<br />

Это затрагива<strong>е</strong>т м<strong>е</strong>тод и свойства, поэтому их потр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>крыть.<br />

★<br />

Свойства тож<strong>е</strong> можно п<strong>е</strong>р<strong>е</strong>крывать! Присваивая знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

b a s e .Numberof P eople, вы обраща<strong>е</strong>т<strong>е</strong>сь к м<strong>е</strong>тоду записи в базовом класс<strong>е</strong>.<br />

Ключ<strong>е</strong>во<strong>е</strong> слово b a s e потр<strong>е</strong>бу<strong>е</strong>тся вам как для чт<strong>е</strong>ния, так и для записи.<br />

дальш<strong>е</strong> > 269


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

•ЗЖНбНИб<br />

cLlcnrlc<br />

Вот как сл<strong>е</strong>довало отр<strong>е</strong>дактировать классы DinnerParty и BirthdayParty, чтобы они<br />

унасл<strong>е</strong>довали свойства базового класса Party. Им<strong>е</strong>нно это позволило вам добавить<br />

новый плат<strong>е</strong>ж ($100), н<strong>е</strong> р<strong>е</strong>дактируя при этом форму!<br />

c l a s s P a r ty<br />

{<br />

c o n s t i n t C o stO fF o o d P erP erso n =<br />

p r i v a t e b o o l f a n c y D e c o r a t io n s ;<br />

25;<br />

p u b l i c d e c im a l C o s tO fD e c o r a tio n s =<br />

p u b l i c P a r t y ( i n t nutnberO fP eople, b o o l f a n c y D e c o r a tio n s )<br />

t h i s . fa n c y D e c o r a t io n s = f a n c y D e c o r a t io n s ;<br />

th is.N u m b e r O fP e o p le = n u m b erO fP eo p le;<br />

}<br />

p r i v a t e i n t num berO fP eople;<br />

p u b l i c v i r t u a l i n t N um berO fPeople {<br />

}<br />

g e t { r e t u r n n u m berO fP eop le; } «_«>:=:_________<br />

s e t {<br />

num berO fP eople = v a lu e ;<br />

C a lc u la t e C o s t O fD e c o r a tio n s ( f a n c y D e c o r a t io n s )<br />

p iib lic v o id C a lc u la t e C o s t O fD e c o r a tio n s ( b o o l fa n c y ) {<br />

f a n c y D e c o r a t io n s = fa n c y ;<br />

i f (fa n c y )<br />

}<br />

C o s tO fD e c o r a tio n s =<br />

e l s e<br />

C o s tO fD e c o r a tio n s =<br />

(Num berO fPeople<br />

(Num berO fPeople<br />

p u b l i c v i r t u a l d e c im a l C a lc u la t e C o s t O {<br />

d e c im a l T o t a lC o s t = C o s tO fD e c o r a tio n s +<br />

i f (Num berO fPeople > 12)<br />

{<br />

T o ta lC o s t += lOOM;<br />

}<br />

r e t u r n T o ta lC o s t;<br />

Э т о т код был п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>н<br />

из классов DinnerParty<br />

и BirthdayParty в класс<br />

Party.<br />

Конструктор класса<br />

Party сод<strong>е</strong>ржит функции,<br />

которы<strong>е</strong> раньш<strong>е</strong><br />

н<strong>е</strong>сли конструкторы<br />

классов DinnerParty<br />

и BirthdayParty.<br />

П<strong>е</strong>р<strong>е</strong>д парам<strong>е</strong>тром<br />

NumberOfPeople т р<strong>е</strong>бу<strong>е</strong>т ­<br />

ся вставить ключ<strong>е</strong>во<strong>е</strong> слово<br />

virtual, так как класс<br />

BirthdayParty долж<strong>е</strong>н <strong>е</strong>го п<strong>е</strong>р<strong>е</strong>крыть<br />

(в этом случа<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong><br />

колич<strong>е</strong>ства гост<strong>е</strong>й м<strong>е</strong>ня<strong>е</strong>т<br />

диам<strong>е</strong>тр торта).<br />

Стоимость оформл<strong>е</strong>ния<br />

для м<strong>е</strong>роприятий обоих<br />

\ типов рассчитыва<strong>е</strong>тся<br />

по одной и той ж<strong>е</strong> сх<strong>е</strong>м<strong>е</strong>,<br />

* 15.00М ) + БОМ; у х .о э т ому <strong>е</strong><strong>е</strong> логично пом<strong>е</strong>стить<br />

в класс Party.<br />

* 7.50М) + ЗОМ;<br />

(C o stO fF o o d P erP erso n * Num berO fPeople)<br />

^ М<strong>е</strong>тоЭ вычисл<strong>е</strong>ния стоимости<br />

пом<strong>е</strong>тить<br />

словом vlrtuaL так как <strong>е</strong>го по-<br />

270 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

c l a s s B ir th d a y P a r ty : P a r ty {<br />

p u b lic i n t C a k eS ize;<br />

p u b l i c B ir t h d a y P a r t y ( in t n u m berO fP eop le, b o o l f a n c y D e c o r a t io n s , s t r i n g c a k e W ritin g )<br />

: b a se(n u m b er O fP e o p le, f a n c y D e c o r a tio n s )<br />

}<br />

C a lc u la t e C a k e S iz e ( );<br />

t h is .C a k e W r itin g = c a k e W r itin g ;<br />

C a lc u la t e C o s t O fD e c o r a tio n s ( f a n c y D e c o r a t io n s )<br />

p r i v a t e v o id C a lc u la te C a k e S iz e !<br />

i f (Num berO fPeople m axLength) {<br />

M essageB ox.Sh ow ("T oo many l e t t e r s f o r a " + C a k eS iz e + " in c h cake")<br />

i f (m axLength > t h i s . c a k e W r it in g . L ength)<br />

m axLength = t h is .c a k e W r it in g .L e n g t h ;<br />

t h i s .c a k e W r i t in g = c a k e W r i t in g .S u b s t r in g (0, m axL ength);<br />

} e l s e<br />

t h i s . c a k e W r itin g = v a lu e ;<br />

М<strong>е</strong>тод CalculateCostQ и з ­<br />

да<strong>е</strong>тся в п <strong>е</strong>р <strong>е</strong>кр ы т и и ,, так<br />

^ к с т ч а л а ^ в ш и с л я <strong>е</strong> т <strong>е</strong><br />

p u b l i c o v e r r id e d e c im a l C a lc u la t e C o s t O 0 {<br />

d e c im a l C akeC ost;<br />

i f (C a k eS ize == 8)<br />

C akeC ost = 40M + C a k e W r itin g .L e n g th *<br />

}<br />

e l s e<br />

C akeC ost = 75M + C a k e W r itin g . L en g th *<br />

r e t u r n b a s e . C a l c u l a t e C o s t () + C akeC ost;<br />

p u b l i c o v e r r id e i n t N um berO fPeople {<br />

g e t { r e t u r n b a se.N u m b erO fP eo p le; }<br />

s e t {<br />

b a se.N u m b erO fP eo p le = v a lu e ;<br />

C a lc u la t e C a k e S iz e () ;<br />

t h i s . C a k eW ritin g = c a k e W r itin g ;<br />

.25M;<br />

.25M;<br />

cmouMocmt><br />

. т ом кот ит <strong>е</strong> добавить <strong>е</strong><strong>е</strong><br />

к сум м <strong>е</strong>,<br />

т а л м<strong>е</strong>тод CalculateCostQ<br />

из класса Party.<br />

3dect> свойство NumberOfPeople<br />

должно п<strong>е</strong>р<strong>е</strong>крывать одноим<strong>е</strong>нно<strong>е</strong><br />

свойство из класса P arty, т ак как<br />

м<strong>е</strong>т оду записи нужно п<strong>е</strong>р<strong>е</strong>счит ат ь<br />

^ разм<strong>е</strong>р т орта. При эт ом вызы-<br />

\ ва<strong>е</strong>тся base.NumberOfPeople, что<br />

провоциру<strong>е</strong>т выполн<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода<br />

записи из класса Party.<br />

--------- ► ||]=*оДоЛЖ<strong>е</strong>ни<strong>е</strong> н а с. 272-<br />

дальш<strong>е</strong> ► 271


отличная работа!<br />

— Э т о посл<strong>е</strong>дний к л а с с ,<br />

ажн<strong>е</strong>нк<strong>е</strong><br />

в программ<strong>е</strong> Кэтлин.<br />

'Код формы остался б<strong>е</strong>з<br />

х/у изм<strong>е</strong>н<strong>е</strong>ний.)<br />

V<br />

Это пол<strong>е</strong> общ<strong>е</strong>го доступа<br />

использу<strong>е</strong>тся только<br />

c l a s s D in n e r P a r ty : P a r ty<br />

р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong> {<br />

I / расч<strong>е</strong>т<strong>е</strong> стоимости званых<br />

(V. об<strong>е</strong>дов и поэтому оста<strong>е</strong>тся<br />

p u b l i c d e c im a l C o s tO fB e v e r a g e sP e r P e r so n ; в этом класс<strong>е</strong>.<br />

272 глава 6<br />

p u b l i c D in n e r P a r t y ( in t nu m berO fP eop le, b o o l h e a lth y O p tio n ,<br />

b o o l f a n c y D e c o r a tio n s )<br />

воспроизв<strong>е</strong>-<br />

}<br />

■ b a s e (n u m b e r o fP e o p le , f a n c y D e c o r a t io n s ) { emu функциональ<br />

S e t H e a lt h y O p t io n ( h e a lt h y O p t io n ) ;<br />

Homb старого класса<br />

C a lc u la t e C o s t O f D e c o r a t io n s ( f a n c y D e c o r a t io n s ) ; Dinnerparty, новый<br />

конструктор вызыва<strong>е</strong>т<br />

сначала конструктор<br />

Party,<br />

а зат<strong>е</strong>м м<strong>е</strong>тод<br />

SetHealthyOptionO-<br />

p u b l i c v o id S e t H e a lt h y O p t io n ( b o o l h e a lth y O p tio n ) {<br />

i f (h e a lth y O p tio n )<br />

}<br />

C o stO fB e v e r a g e sP e r P e r so n = 5.00M ;<br />

C o stO fB e v e r a g e sP e r P e r so n = 20.00M ;<br />

p u b l i c d e c im a l C a lc u la t e C o s t ( b o o l h e a lth y O p tio n )<br />

d e c im a l t o t a l C o s t = b a s e . C a l c u l a t e C o s t ()<br />

}<br />

i f (h e a lth y O p tio n )<br />

r e t u r n t o t a l C o s t '<br />

e l s e<br />

r e t u r n t o t a l C o s t ;<br />

Программа работа<strong>е</strong>т!<br />

Т<strong>е</strong>п<strong>е</strong>рь мой бизн<strong>е</strong>с пош<strong>е</strong>л в гору,<br />

спасибо огромно<strong>е</strong>!<br />

М<strong>е</strong>тод<br />

+ (C o stO fB e v e r a g e sP e r P e r so n * N u m b erO fP eo p le);<br />

•95М;<br />

Стойт<strong>е</strong>! В програм м <strong>е</strong> вс<strong>е</strong> <strong>е</strong>щ <strong>е</strong> осталась пот<strong>е</strong>нциальная ош ибка!<br />

{<br />

К Классу DinnerParty нуж<strong>е</strong>н другой м<strong>е</strong>-<br />

V . mod CalculateCostQ, поэтому вм<strong>е</strong>сто<br />

п<strong>е</strong>р<strong>е</strong>крытия МЫ <strong>е</strong>го п<strong>е</strong>р<strong>е</strong>грузим- При<br />

помощи ключ<strong>е</strong>вого слова base вызыва<strong>е</strong>тся<br />

м<strong>е</strong>тод CalculateCostQ из класса<br />

Party, зат<strong>е</strong>м к р<strong>е</strong>зультату прибавля<strong>е</strong>тся<br />

стоимость напитков и вычисля<strong>е</strong>тся<br />

скидка за «здоровый» вариант-<br />

О том, как им<strong>е</strong>нно р а ­<br />

бота<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>грузка, вы<br />

узна<strong>е</strong>т<strong>е</strong> в глав<strong>е</strong> 8.<br />

В класс<strong>е</strong> D i n n e r P a r t y с<strong>е</strong>йчас два м<strong>е</strong>тода C a l c u l a t e C o s t ( ) : один унасл<strong>е</strong>дованный от класса<br />

P a r t y , а другой созданный нами. Этот класс н<strong>е</strong> инкапсулирован, поэтому оста<strong>е</strong>тся возможность<br />

вызвать н<strong>е</strong>правильный м<strong>е</strong>тод C a l c u l a t e C o s t ():<br />

D in n e r P a r ty d in n e r = new D in n e r P a r t y (5, t r u e , t r u e ) ;<br />

d e c im a l c o s t l = d i n n e r . C a l c u l a t e C o s t ( t r u e ) ;<br />

d e c im a l c o s t 2 = d i n n e r . C a l c u l a t e C o s t ( );<br />

c o s t l получит знач<strong>е</strong>ни<strong>е</strong> 261.25, в то вр<strong>е</strong>мя как c o s t 2 - знач<strong>е</strong>ни<strong>е</strong> 250. Пробл<strong>е</strong>ма... Иногда в базовом<br />

класс<strong>е</strong> сущ<strong>е</strong>ству<strong>е</strong>т код, к которому вы н<strong>е</strong> хотит<strong>е</strong> обращаться напрямую. Или вы н<strong>е</strong> собирались создавать<br />

экз<strong>е</strong>мпляры класса P a r t y , но такая возможность сохранилась. А что буд<strong>е</strong>т, <strong>е</strong>сли ч<strong>е</strong>лов<strong>е</strong>к, р<strong>е</strong>дактирующий<br />

наш код, создаст экз<strong>е</strong>мпляр класса P a r t y ? Явно н<strong>е</strong> то, что мы планировали.<br />

О том, как р<strong>е</strong>шить эту пробл<strong>е</strong>му, вы узна<strong>е</strong>т<strong>е</strong> в сл<strong>е</strong>дующ<strong>е</strong>й глав<strong>е</strong>!


насл<strong>е</strong>довани<strong>е</strong><br />

Сист<strong>е</strong>ма управл<strong>е</strong>ния уль<strong>е</strong>м<br />

Т<strong>е</strong>п<strong>е</strong>рь ваша помош;ь нужна пч<strong>е</strong>линой матк<strong>е</strong>! У!л<strong>е</strong>й выш<strong>е</strong>л<br />

из-под контроля и <strong>е</strong>й нужна программа, которая<br />

помож<strong>е</strong>т им управлять. Ул<strong>е</strong>й полон рабочих пч<strong>е</strong>л, им<strong>е</strong><strong>е</strong>тся<br />

и список заданий. Нужно распр<strong>е</strong>д<strong>е</strong>лить задания<br />

м<strong>е</strong>жду пч<strong>е</strong>лами с уч<strong>е</strong>том их сп<strong>е</strong>циализации.<br />

Постройт<strong>е</strong> сист<strong>е</strong>му, управляющую пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>м рабочих<br />

пч<strong>е</strong>л. Вот как она должна функционировать:<br />

ШЗ<br />

т &<br />

М атка разда<strong>е</strong>т задания рабочим<br />

Сущ<strong>е</strong>ству<strong>е</strong>т ш<strong>е</strong>сть видов работ. Н<strong>е</strong>которы<strong>е</strong> пч<strong>е</strong>лы ум<strong>е</strong>ют<br />

собирать н<strong>е</strong>ктар и д<strong>е</strong>лать м<strong>е</strong>д, други<strong>е</strong> могут строить<br />

ул<strong>е</strong>й и защищать <strong>е</strong>го от врагов. Есть пч<strong>е</strong>лы, которы<strong>е</strong><br />

вообщ<strong>е</strong> могут выполнять любую работу. Вам нужно написать<br />

программу, дающую пч<strong>е</strong>л<strong>е</strong> задани<strong>е</strong>, которо<strong>е</strong> она<br />

в состоянии выполнить.<br />

Сущ<strong>е</strong>ству<strong>е</strong>м ш<strong>е</strong>смь видов рабом. М ам ­<br />

к<strong>е</strong> вс<strong>е</strong> равно, ч<strong>е</strong>м занима<strong>е</strong>тся отд<strong>е</strong>льная<br />

пч<strong>е</strong>ла. Она вс<strong>е</strong>го лишь указыва<strong>е</strong>т, что<br />

нужно сдслаиль, й провр/яммй опрсд<strong>е</strong>ляа^<br />

наличи<strong>е</strong> доступных рабочих и да<strong>е</strong>т им<br />

задани<strong>е</strong>.<br />

При наличии доступных<br />

пч<strong>е</strong>л программа<br />

да<strong>е</strong>т им<br />

задани<strong>е</strong> и отчиты~_<br />

ба<strong>е</strong>мся п<strong>е</strong>р<strong>е</strong>д м а м ­<br />

кой, выводя окно:<br />

Пр<strong>е</strong><br />

буд<strong>е</strong>м законч<strong>е</strong>но за<br />

мри см<strong>е</strong>ны».<br />

Вр<strong>е</strong>мя работать<br />

Раздав задания, матка заставля<strong>е</strong>т пч<strong>е</strong>л отрабатывать<br />

оч<strong>е</strong>р<strong>е</strong>дную см<strong>е</strong>ну щ<strong>е</strong>лчком на кнопк<strong>е</strong> «Работать! Сл<strong>е</strong>дующая<br />

см<strong>е</strong>на». Программа отчитыва<strong>е</strong>тся, каки<strong>е</strong> пч<strong>е</strong>лы<br />

работали в эту см<strong>е</strong>ну, какую работу они выполняли и<br />

сколько см<strong>е</strong>н им <strong>е</strong>щ<strong>е</strong> осталось трудиться им<strong>е</strong>нно над<br />

этим задани<strong>е</strong>м.<br />

Пч<strong>е</strong>лы трудятся<br />

посм<strong>е</strong>нно, а большинство<br />

рабом<br />

выполня<strong>е</strong>мся<br />

в н<strong>е</strong>сколько см<strong>е</strong>н.<br />

Мамка вводим<br />

число см<strong>е</strong>н в пол<strong>е</strong><br />

Shifts и щ<strong>е</strong>лка<strong>е</strong>м<br />

на кнопк<strong>е</strong> Assign<br />

this job, чтобы<br />

дать задани<strong>е</strong> свободным<br />

пч<strong>е</strong>лам.<br />

T h e jo b ‘H o n ey m a n u fsc tu rin g ' wilt b e d o n e in 3 shifts<br />

дальш<strong>е</strong> ► 273


помоги пч<strong>е</strong>линой матк<strong>е</strong><br />

Постро<strong>е</strong>ни<strong>е</strong> осноб<br />

Этот про<strong>е</strong>кт д<strong>е</strong>лится на дв<strong>е</strong> части. Начн<strong>е</strong>м с обзора сист<strong>е</strong>мы управл<strong>е</strong>ния<br />

уль<strong>е</strong>м. Вам потр<strong>е</strong>буются два класса - Queen (Матка) и W orker (Рабочий), -<br />

которы<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т инкапсулировать. Н<strong>е</strong> обойд<strong>е</strong>мся мы и б<strong>е</strong>з связанной с этими<br />

классами формы.<br />

Иногда в диаграмм<strong>е</strong> классов могут<br />

появиться закрыты<strong>е</strong> поля и типы.<br />

т<br />

Q u e e n<br />

private workers: WorkerQ j<br />

private shiftNumber: int<br />

AssignWorkO<br />

WorkTheNextShiftO<br />

-,-^ б ъ <strong>е</strong> к т Queen указыва<strong>е</strong>т, какую работу нужно сд<strong>е</strong>лать.<br />

Массив объ<strong>е</strong>ктов W o rk er отсл<strong>е</strong>жива<strong>е</strong>т т<strong>е</strong>кущую занятость<br />

каждой рабоч<strong>е</strong>й пч<strong>е</strong>лы. Эта информация хранится в закрытых<br />

полях W o r k e r [ ].<br />

Форма вызыва<strong>е</strong>т м<strong>е</strong>тод AssignW ork {) (Назначить задани<strong>е</strong>),<br />

п<strong>е</strong>р<strong>е</strong>давая строку с названи<strong>е</strong>м работы и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную типа int с<br />

колич<strong>е</strong>ством см<strong>е</strong>н. При наличии свободной пч<strong>е</strong>лы, которая в<br />

состоянии выполнять эту работу, возвраща<strong>е</strong>тся знач<strong>е</strong>ни<strong>е</strong> true.<br />

Свойства C um ntJob<br />

(Т<strong>е</strong>кущ<strong>е</strong><strong>е</strong>Задани<strong>е</strong>) и ShiftsLeft<br />

(Оставили<strong>е</strong>сяСм<strong>е</strong>ны)<br />

пр<strong>е</strong>дназнач<strong>е</strong>ны только для чт<strong>е</strong>ния.<br />

W o rk e r<br />

CurrentJob: string<br />

ShiftsLeft: int<br />

private jobslCanDo: string[]<br />

private shiftsToWork: int<br />

private shiftsWorked: int<br />

DoThisJobO<br />

WorkOneShiftO<br />

Кнопка Work the next shift вызыва<strong>е</strong>т м<strong>е</strong>тод W o r k T h e N e x t­<br />

S h i f t O , заставляющий каждый объ<strong>е</strong>кт Worker отработать<br />

одну см<strong>е</strong>ну и зат<strong>е</strong>м пров<strong>е</strong>ряющий <strong>е</strong>го состояни<strong>е</strong>, чтобы сформировать<br />

отч<strong>е</strong>т.<br />

Посмотрим на функции массива Worker.<br />

^<br />

Свойство C u rre n tJ o b да<strong>е</strong>т понять объ<strong>е</strong>кту Queen, какую работу<br />

выполня<strong>е</strong>т каждый рабочий. Если рабочий на мом<strong>е</strong>нт<br />

пров<strong>е</strong>рки нич<strong>е</strong>м н<strong>е</strong> занят, возвраща<strong>е</strong>тся пустая строка.<br />

Раздача заданий рабочим происходит при помощи м<strong>е</strong>тода<br />

D oT hisJob {). Если рабочий н<strong>е</strong> занят и в состоянии выполнять<br />

указанную работу, м<strong>е</strong>тод возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true.<br />

М<strong>е</strong>тод W orkO neShiftO заставля<strong>е</strong>т рабоч<strong>е</strong>го отработать<br />

одну см<strong>е</strong>ну, а такж<strong>е</strong> отсл<strong>е</strong>жива<strong>е</strong>т оставш<strong>е</strong><strong>е</strong>ся колич<strong>е</strong>ство<br />

см<strong>е</strong>н. Если работа законч<strong>е</strong>на, возвраща<strong>е</strong>тся пустая строка.<br />

Это означа<strong>е</strong>т, что он готов к выполн<strong>е</strong>нию сл<strong>е</strong>дующ<strong>е</strong>го задания.<br />

^ мом<strong>е</strong>нт вр<strong>е</strong>м<strong>е</strong>ни х т -<br />

U p o З Ц О , как<br />

уСоБ<strong>е</strong>рШ<strong>е</strong>НСЩБоБатпь<br />

сист<strong>е</strong>му угд^аБл<strong>е</strong>ния уЛь<strong>е</strong>М<br />

Tij^u поМоЩи насл<strong>е</strong>дования,<br />

Чшпаг<strong>е</strong>дг<strong>е</strong> на с.


насл<strong>е</strong>довани<strong>е</strong><br />

* ^ п р а ж н г н и г<br />

О<br />

Итак, приступим к постро<strong>е</strong>нию сист<strong>е</strong>мы управл<strong>е</strong>ния уль<strong>е</strong>м, которая обл<strong>е</strong>гчит<br />

жизнь пч<strong>е</strong>линой матк<strong>е</strong>.<br />

П остро<strong>е</strong>ни<strong>е</strong> qx>pMbi<br />

Форма буд<strong>е</strong>т оч<strong>е</strong>нь простой, всю работу пр<strong>е</strong>дстоит выполнить классам Q u e e n и W orker.<br />

Добавьт<strong>е</strong> закрыто<strong>е</strong> пол<strong>е</strong> Queen и дв<strong>е</strong> кнопки, вызывающи<strong>е</strong> м<strong>е</strong>тоды A s s ig n W o r k () и<br />

W o r k T h e N e x t S h if t О . Ещ<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся эл<strong>е</strong>м<strong>е</strong>нт C om boBox, управляющий работой<br />

пч<strong>е</strong>л (пункты этого раскрывающ<strong>е</strong>гося списка были п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ны на пр<strong>е</strong>дыдущ<strong>е</strong>й страниц<strong>е</strong>),<br />

эл<strong>е</strong>м<strong>е</strong>нт N u m ericU p D ow n , дв<strong>е</strong> кнопки и т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong> для отч<strong>е</strong>та о см<strong>е</strong>нах.<br />

Вид формы показан ниж<strong>е</strong>.<br />

Эл<strong>е</strong>м<strong>е</strong>нт ComboBox нд-<br />

^ Beehw« Menagement System<br />

зыва<strong>е</strong>тся workerBeeJob.<br />

Используйт<strong>е</strong> свойство . Wsika- Bee Assignma^s<br />

Items для формирования^ Wotka-beejsrfj<br />

списка. DropPownStyle<br />

присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

collector<br />

PropPownListj чтобы<br />

Assign toa bee<br />

пользоват<strong>е</strong>ль мог выбирать<br />

знач<strong>е</strong>ния только<br />

из раскрывающ<strong>е</strong>гося<br />

списка. Пол<strong>е</strong> Shifts<br />

явля<strong>е</strong>тся эл<strong>е</strong>м<strong>е</strong>нтом<br />

NumericUpPown с им <strong>е</strong>­<br />

н<strong>е</strong>м shifts.<br />

Дайт <strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нту<br />

TextBox имя report,<br />

а <strong>е</strong>го свойству MultiLine<br />

знач<strong>е</strong>ни<strong>е</strong> true.<br />

p u b l i c F o r m lо {<br />

I n it ia liz e C o m p o n e n t O ;<br />

W orker[]<br />

w o rk ers = new W orker[4]<br />

w o r k e r s [0] = new W orker(new s t r i n g []<br />

w o r k e r s [1] = new W orker(new s t r i n g []<br />

w o r k e r s [2] = new W orker(new s t r i n g []<br />

w o r k e r s [3] = new W orker(new s t r i n g []<br />

M s<br />

Reportforahft#12<br />

Woiker #1 !Sdoing'NectarcoSector'for1more difts<br />

Worker Й2 wi be done wth 'Egg care'sftertHsЙЛ<br />

Woike- #3 isdoing'aingрйго!’for1more shfts<br />

Woiker #4 firtshedthe job<br />

Woiker #4 isnotwraking<br />

Woittme<br />

neadshe<br />

Кнопка nextShift вызыва<strong>е</strong>т<br />

м<strong>е</strong>тод<br />

WorkTheNextShiftQ из<br />

класса Queen, возвращающий<br />

строку с отч<strong>е</strong>том<br />

о см<strong>е</strong>нах.<br />

Рассмотрим отч<strong>е</strong>т,<br />

созданный объ<strong>е</strong>ктом<br />

Queen. Он начина<strong>е</strong>тся<br />

с ном<strong>е</strong>ра см<strong>е</strong>ны, зат<strong>е</strong>м<br />

сл<strong>е</strong>ду<strong>е</strong>т спиi<br />

coK д<strong>е</strong>л работников.<br />

Используйт<strong>е</strong> escпосл<strong>е</strong>доёат<strong>е</strong>льности<br />

Конструктор каждого " объ<strong>е</strong>кта \г \п ’] чтобы доба­вить<br />

знак п<strong>е</strong>р<strong>е</strong>носа о том,<br />

ча<strong>е</strong>т массив строк с информаци<strong>е</strong>й<br />

каки<strong>е</strong> работы мож<strong>е</strong>т выполнять в строку. пч<strong>е</strong>ла.<br />

" N ecta r c o l l e c t o r " , "Honey m a n u fa ctu rin g " } ) ;<br />

"Egg c a r e " , "Baby b e e t u t o r in g " } ) ;<br />

"H ive m a in te n a n c e " , " S tin g p a t r o l" }) ;<br />

" N ecta r c o l l e c t o r " , "Honey m a n u fa ctu rin g " .<br />

"Egg c a r e " , "Baby b e e t u t o r i n g " , "H ive m a in te n a n c e " , " S tin g p a t r o l" } ) ;<br />

q u een = new Queen (w orkers) форм<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся пол<strong>е</strong> Queen с им<strong>е</strong>н<strong>е</strong>м queen. Массив<br />

} Worker нужно буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дать конструктору объ<strong>е</strong>кта Queen.<br />

0 Создани<strong>е</strong> классов W o rk e r и Q ueen<br />

М<strong>е</strong>тод Q u e e n . A s s ig n W o r k О циклич<strong>е</strong>ски просматрива<strong>е</strong>т массив w o r k e r и пыта<strong>е</strong>тся<br />

дать работу каждому oбъeктyworkerпpипoмoщи м<strong>е</strong>тода D o T h is J o b ( ) . Объ<strong>е</strong>кт W o rk er<br />

в массив<strong>е</strong> строк j o b s IC a n D o пров<strong>е</strong>ря<strong>е</strong>т свою способность выполнить пр<strong>е</strong>длож<strong>е</strong>нную работу.<br />

Если да, закрытому полю s h if t s T o W o r k присваива<strong>е</strong>тся колич<strong>е</strong>ство см<strong>е</strong>н, парам<strong>е</strong>тру<br />

C u r r e n t J o b —названи<strong>е</strong> работы, а п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной s h i f t s W o r k e d —знач<strong>е</strong>ни<strong>е</strong> «ноль».<br />

Отработанная см<strong>е</strong>на ув<strong>е</strong>личива<strong>е</strong>т эту п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную на 1. При помощи пр<strong>е</strong>дназнач<strong>е</strong>нного<br />

только для чт<strong>е</strong>ния свойства S h i f t s L e f t матка оц<strong>е</strong>нива<strong>е</strong>т, сколько см<strong>е</strong>н <strong>е</strong>щ<strong>е</strong> нужно отработать.


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

н<strong>е</strong>нк<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Свойство ShiftsLeftj<br />

пр<strong>е</strong>дназнач<strong>е</strong>но<strong>е</strong> только<br />

для чт<strong>е</strong>ния, показыва<strong>е</strong>т,<br />

сколько см<strong>е</strong>н осталось<br />

отработать до зав<strong>е</strong>рш<strong>е</strong>ния<br />

задания.<br />

Свойство CurrentJob<br />

(только для чт<strong>е</strong>ния)<br />

показыва<strong>е</strong>т мат к<strong>е</strong>,<br />

каки<strong>е</strong> работы сл<strong>е</strong>ду<br />

<strong>е</strong>т пров<strong>е</strong>сти.<br />

c l a s s Worker {<br />

p u b l i c W o r k e r ( s t r in g [] jobslC anD o)<br />

t h i s . jo b slC a n D o = jo b slC a n D o ;<br />

1<br />

p u b l i c i n t S h i f t s L e f t {<br />

f g e t {<br />

r e t u r n sh iftsT o W o rk -<br />

}<br />

}<br />

p r i v a t e s t r i n g c u r r e n tJ o b =<br />

p u b l i c s t r i n g C u rren tJ o b {<br />

g e t {<br />

r e t u r n c u r r e n tJ o b ;<br />

}<br />

}<br />

p r i v a t e s t r i n g [] jo b slC a n D o ;<br />

p r i v a t e i n t sh iftsT o W o rk ;<br />

p r i v a t e i n t sh ifts W o r k e d ;<br />

sh ifts W o r k e d ;<br />

' ^онст рукт ор зада<strong>е</strong>т<br />

свойство<br />

JobslCanDo, пр<strong>е</strong>дставляющ<strong>е</strong><strong>е</strong><br />

собой<br />

строковый массив.<br />

Он закрыт, так как<br />

пр<strong>е</strong>дполага<strong>е</strong>тся, что<br />

матка только просит<br />

рабоч<strong>е</strong>го выполнить<br />

работ у, но<br />

н<strong>е</strong> должна при этом<br />

пров<strong>е</strong>рять. Мож<strong>е</strong>т<br />

ли он это сд<strong>е</strong>лать.<br />

Матка использу<strong>е</strong>т м<strong>е</strong>тод<br />

PoThisJob() обь<strong>е</strong>кта worker<br />

для назнач<strong>е</strong>ния заданий р а -<br />

дочим, рабочий пров<strong>е</strong>ря<strong>е</strong>т<br />

свойство JobslCanDo, чтобы<br />

понять, мож<strong>е</strong>т ли он выполнять<br />

данную работу.<br />

Матка использу<strong>е</strong>т<br />

м<strong>е</strong>тод WorkOneShiftO<br />

обь<strong>е</strong>кта worker,<br />

чтобы заставить<br />

рабочих отработать<br />

сл<strong>е</strong>дующую см<strong>е</strong>ну.<br />

М<strong>е</strong>тод возвраща<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> true, <strong>е</strong>сли<br />

это посл<strong>е</strong>дняя см<strong>е</strong>на<br />

т<strong>е</strong>кущ<strong>е</strong>го работника.<br />

В отч<strong>е</strong>т<strong>е</strong> появля<strong>е</strong>тся<br />

строчка, что посл<strong>е</strong> }<br />

этой см<strong>е</strong>ны пч<strong>е</strong>ла<br />

свободна.<br />

p u b lic b o o l D o T h is J o b ( s t r in g jo b , i n t n u m b erO fS h ifts)<br />

i f (J^String. IsN ullO rE m p ty (c u r r e n tJ o b ) )<br />

r e t u r n f a l s e ;<br />

f o r ( i n t i = 0; i < jo b slC a n D o .L e n g th ; i++)<br />

i f (jo b s lC a n D o [i] == jo b ) {<br />

c u r r e n tJ o b = jo b ;<br />

}<br />

}<br />

r e t u r n f a l s e ;<br />

t h is .s h if t s T o W o r k = n u m b e r O fS h ifts;<br />

sh ifts W o r k e d = 0;<br />

Оп<strong>е</strong>ратор<br />

r e t u r n t r u e ;<br />

p u b l i c b o o l W o rkO neSh iftO {<br />

i f (S tr in g .I s N u llO r E m p t y ( c u r r e n t J o b ) )<br />

r e t u r n f a l s e ;<br />

sh ifts W o r k e d + + ;<br />

i f<br />

(sh ifts W o r k e d<br />

s h ifts W o r k e d<br />

sh iftsT o W o rk<br />

c u r r e n tJ o b =<br />

r e t u r n tr u e ;<br />

e l s e<br />

r e t u r n f a l s e ;<br />

> sh iftsT o W o rk ) {<br />

означающий<br />

НЕТ—- пров<strong>е</strong>ря<strong>е</strong>т, явля<strong>е</strong>тся<br />

ли строка пустой и им<strong>е</strong><strong>е</strong>т ли<br />

знач<strong>е</strong>ния null. Им<strong>е</strong>нно таким<br />

образом осущ<strong>е</strong>ствля<strong>е</strong>тся пров<strong>е</strong>рка<br />

н<strong>е</strong>соблюд<strong>е</strong>ния условия.<br />

= 0 Сначала пров<strong>е</strong>ря<strong>е</strong>тся пол<strong>е</strong><br />

и//.’ currentJob. Если рабочий нич<strong>е</strong>м<br />

н<strong>е</strong> занят, возвраща<strong>е</strong>тся знач<strong>е</strong>ни<strong>е</strong><br />

false, и м<strong>е</strong>тод пр<strong>е</strong>краща<strong>е</strong>т рабоп^У-В<br />

противном случа<strong>е</strong> парам<strong>е</strong>тр<br />

ShiftsWorked ув<strong>е</strong>личива<strong>е</strong>тся на 1 ,<br />

^ и пров<strong>е</strong>ря<strong>е</strong>тся, сд<strong>е</strong>лана ли работа<br />

сравн<strong>е</strong>ния с i^apaMo^poM<br />

ShiftsToWork). При положит<strong>е</strong>льном<br />

р<strong>е</strong>зультат<strong>е</strong> м<strong>е</strong>тод возвраща<strong>е</strong>т<br />

true.<br />

276 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

c l a s s Queen {<br />

p u b l i c Q ueen(W orker [] w o rk ers) {<br />

t h i s .w o r k e r s = w o rk ers;<br />

}<br />

p r i v a t e W ork er[] w o rk ers;<br />

p r i v a t e i n t S h iftN u m b er = 0;<br />

к о м /ткТ зн « ч <strong>е</strong>£ < <strong>е</strong> поля заЭа<strong>е</strong>т конструктор.<br />

p u b l i c b o o l A s s ig n W o r k (s tr in g jo b , i n t n u m b e rO fS h ifts) {<br />

f o r ( i n t i = 0; i < w o r k e r s .L e n g th ; i++)<br />

i f ( w o r k e r s [ i] .D o T h is J o b ( j o b , n u m b e r O fS h ifts))<br />

r e t u r n f a l s e r<br />

\ \ ум<strong>е</strong><strong>е</strong>т д<strong>е</strong>лать работы икЛаи-<br />

.Г"<br />

^ei^od<br />

" " " ' s h i ^ N ^ e r : : ; ^<br />

s t r i n g r e p o r t = "Отч<strong>е</strong>т для см<strong>е</strong>ны#" + sh iftN u m b e r +<br />

: ^ f o r ( i n t i = 0; i < w o r k e rs .L en g th ; i++)<br />

{<br />

‘'\r \n " ;<br />

x°'^f


вс<strong>е</strong> мы только пч<strong>е</strong>лы<br />

ж н т<br />

Работа <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> законч<strong>е</strong>на! 1\/1атк<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся сист<strong>е</strong>ма уч<strong>е</strong>та потр<strong>е</strong>бля<strong>е</strong>мого в уль<strong>е</strong> м<strong>е</strong>да.<br />

В<strong>е</strong>ликол<strong>е</strong>пный шанс прим<strong>е</strong>нить на практик<strong>е</strong> свои знания!<br />

Сколько ж<strong>е</strong> м <strong>е</strong>да потр<strong>е</strong>бля<strong>е</strong>т ул <strong>е</strong>й<br />

Матк<strong>е</strong> только что позвонила пч<strong>е</strong>ла-бухгалт<strong>е</strong>р и сказала, что в уль<strong>е</strong> н<strong>е</strong>достаточно м<strong>е</strong>да. Бухгалт<strong>е</strong>ру<br />

нужна информация о колич<strong>е</strong>ств<strong>е</strong> потр<strong>е</strong>бля<strong>е</strong>мого м<strong>е</strong>да, чтобы понять, н<strong>е</strong> нужно ли<br />

часть рабочих, занимающихся заботой о потомств<strong>е</strong>, п<strong>е</strong>р<strong>е</strong>в<strong>е</strong>сти на добычу м<strong>е</strong>да.<br />

о<br />

★<br />

★<br />

★<br />

★<br />

Вс<strong>е</strong> пч<strong>е</strong>лы потр<strong>е</strong>бляют м<strong>е</strong>д, поэтому <strong>е</strong>го должно быть много.<br />

Заняты<strong>е</strong> рабочи<strong>е</strong> потр<strong>е</strong>бляют больш<strong>е</strong> м<strong>е</strong>да. Больш<strong>е</strong> вс<strong>е</strong>го <strong>е</strong>го тр<strong>е</strong>бу<strong>е</strong>тся в мом<strong>е</strong>нт начала<br />

работы, потом потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> пада<strong>е</strong>т. В посл<strong>е</strong>днюю см<strong>е</strong>ну пч<strong>е</strong>ла съ<strong>е</strong>да<strong>е</strong>т 10 <strong>е</strong>диниц<br />

м<strong>е</strong>да; в пр<strong>е</strong>дпосл<strong>е</strong>днюю - 11; п<strong>е</strong>р<strong>е</strong>д этим - 12 и т. д. То <strong>е</strong>сть <strong>е</strong>сли пч<strong>е</strong>ла работа<strong>е</strong>т (<strong>е</strong><strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная S h i f t s L e f t больш<strong>е</strong> нуля), колич<strong>е</strong>ство потр<strong>е</strong>бля<strong>е</strong>мого м<strong>е</strong>да можно вычислить,<br />

прибавив 9 к S h i f t s L e f t .<br />

Н<strong>е</strong>работающая пч<strong>е</strong>ла ( S h if ts L e f t равно нулю) съ<strong>е</strong>да<strong>е</strong>т 7.5 <strong>е</strong>диниц м<strong>е</strong>да за всю см<strong>е</strong>ну<br />

Это данны<strong>е</strong> для обычных пч<strong>е</strong>л. Если в<strong>е</strong>с пч<strong>е</strong>лы пр<strong>е</strong>выша<strong>е</strong>т 150 мг, она <strong>е</strong>ст на 35%<br />

м<strong>е</strong>да больш<strong>е</strong>. (К матк<strong>е</strong> эта информация н<strong>е</strong> относится.)<br />

★ Ч<strong>е</strong>м больш<strong>е</strong> занятых рабочих, т<strong>е</strong>м больш<strong>е</strong> м<strong>е</strong>да потр<strong>е</strong>бля<strong>е</strong>т матка, так как больш<strong>е</strong><br />

сил тратится на управл<strong>е</strong>ни<strong>е</strong> уль<strong>е</strong>м. Колич<strong>е</strong>ство рабочих см<strong>е</strong>н матки равно колич<strong>е</strong>ству<br />

см<strong>е</strong>н пч<strong>е</strong>лы, которой осталось работать дольш<strong>е</strong> вс<strong>е</strong>го.<br />

★<br />

★<br />

Матка потр<strong>е</strong>бля<strong>е</strong>т в см<strong>е</strong>ну на 20 <strong>е</strong>диниц м<strong>е</strong>да больш<strong>е</strong>, <strong>е</strong>сли работа<strong>е</strong>т н<strong>е</strong> больш<strong>е</strong><br />

2 пч<strong>е</strong>л или м<strong>е</strong>ньш<strong>е</strong>, или на 30 <strong>е</strong>диниц больш<strong>е</strong>, <strong>е</strong>сли работают 3 пч<strong>е</strong>лы и бол<strong>е</strong><strong>е</strong>. Так<br />

как в<strong>е</strong>с матки составля<strong>е</strong>т 275 мг, к н<strong>е</strong>й н<strong>е</strong> относится правило 35%.<br />

Данны<strong>е</strong> о колич<strong>е</strong>ств<strong>е</strong> потр<strong>е</strong>бля<strong>е</strong>мого м<strong>е</strong>да нужно добавить в кон<strong>е</strong>ц отч<strong>е</strong>та об отработанных<br />

см<strong>е</strong>нах.<br />

Создайт<strong>е</strong> класс В<strong>е</strong><strong>е</strong> для уч<strong>е</strong>та потр<strong>е</strong>бл<strong>е</strong>ния м<strong>е</strong>да<br />

Пч<strong>е</strong>лы должны знать свой в<strong>е</strong>с, чтобы опр<strong>е</strong>д<strong>е</strong>лить, н<strong>е</strong> съ<strong>е</strong>дают ли они на 35% м<strong>е</strong>да больш<strong>е</strong>.<br />

★<br />

★<br />

Создайт<strong>е</strong> м<strong>е</strong>тод G e t H o n e y C o n s u m p t io n (), вычисляющий потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да. Этот<br />

м<strong>е</strong>тод понадобится как рабочим пч<strong>е</strong>лам, так и матк<strong>е</strong>, у которой, впроч<strong>е</strong>м, способ потр<strong>е</strong>бл<strong>е</strong>ния<br />

н<strong>е</strong>много отлича<strong>е</strong>тся, поэтому класс worker мож<strong>е</strong>т просто насл<strong>е</strong>довать данный<br />

м<strong>е</strong>тод, а класс queen буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>крывать <strong>е</strong>го.<br />

М<strong>е</strong>тоду G e tH o n e y C o n s u m p tio n О нужна информация о колич<strong>е</strong>ство см<strong>е</strong>н, которы<strong>е</strong><br />

осталось отработать, поэтому добавим свойство S h i f t s L e f t , пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> только<br />

для чт<strong>е</strong>ния, и пом<strong>е</strong>тим <strong>е</strong>го ключ<strong>е</strong>вым словом virtual, чтобы дать возможность п<strong>е</strong>р<strong>е</strong>крыть<br />

<strong>е</strong>го в класс<strong>е</strong> worker. Свойство это возвраща<strong>е</strong>т нул<strong>е</strong>во<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

Так как потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да зависит от в<strong>е</strong>са пч<strong>е</strong>лы, конструктор В <strong>е</strong> <strong>е</strong> долж<strong>е</strong>н им<strong>е</strong>ть<br />

пол<strong>е</strong> для хран<strong>е</strong>ния данной информации. Другим классам эти св<strong>е</strong>д<strong>е</strong>ния н<strong>е</strong> потр<strong>е</strong>буются,<br />

поэтому пом<strong>е</strong>тим их ключ<strong>е</strong>вым словом private.<br />

|)\. Поля и свойства сл<strong>е</strong>ду<strong>е</strong>т д<strong>е</strong>лать закрыты-<br />

\ — М ы по умолчанию и открывать, только когда<br />

к ним тр<strong>е</strong>ду<strong>е</strong>тся доступ из других классов.<br />

278 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

О<br />

Подсказка: Воспользуйт<strong>е</strong>сь появл<strong>е</strong>ни<strong>е</strong>м сообщ<strong>е</strong>ни<strong>е</strong>м<br />

об ошибк<strong>е</strong> «по overload'» Авпйипґ<br />

Класс W o rk e r долж<strong>е</strong>н насл<strong>е</strong>довать от класса В<strong>е</strong><strong>е</strong><br />

Конструктор класса W o r k e r долж<strong>е</strong>н брать в<strong>е</strong>с пч<strong>е</strong>лы и п<strong>е</strong>р<strong>е</strong>давать <strong>е</strong>го конструктору базового<br />

класса. Вам оста<strong>е</strong>тся только добавить ключ<strong>е</strong>во<strong>е</strong> слово o v e r r i d e к м<strong>е</strong>тоду S h i f t L e f t .<br />

Посл<strong>е</strong> этого каждая рабочая пч<strong>е</strong>ла получит возможность вычислить сво<strong>е</strong> потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong><br />

м<strong>е</strong>да, и ваша работа по р<strong>е</strong>дактированию класса W o r k e r буд<strong>е</strong>т зав<strong>е</strong>рш<strong>е</strong>на!<br />

т<br />

Класс Q ueen такж<strong>е</strong> долж<strong>е</strong>н насл<strong>е</strong>довать от класса В<strong>е</strong><strong>е</strong><br />

С классом Q u e e n п р и д <strong>е</strong>тся пов ози ться , так как и м <strong>е</strong>н н о зд<strong>е</strong>сь п р о и с х о д и т п о д с ч <strong>е</strong> т к ол ич <strong>е</strong>­<br />

ства м <strong>е</strong>да и ф о р м и р у <strong>е</strong>тся отч<strong>е</strong>т.<br />

★<br />

★<br />

П<strong>е</strong>р<strong>е</strong>кройт<strong>е</strong> м<strong>е</strong>тод В <strong>е</strong> <strong>е</strong> . G e t H o n e y C o n s u m p t io n о и добавьт<strong>е</strong> к н<strong>е</strong>му дополнит<strong>е</strong>льны<strong>е</strong><br />

вычисл<strong>е</strong>ния. Нужно опр<strong>е</strong>д<strong>е</strong>лить колич<strong>е</strong>ство рабочих пч<strong>е</strong>л, от этого зависит<br />

потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да маткой. Колич<strong>е</strong>ство см<strong>е</strong>н матки равно колич<strong>е</strong>ству см<strong>е</strong>н<br />

самой занятой рабоч<strong>е</strong>й пч<strong>е</strong>лы.<br />

Обновит<strong>е</strong> м<strong>е</strong>тод W o r k T h e N e x t S h if t (), добавив к отч<strong>е</strong>ту информацию о потр<strong>е</strong>бл<strong>е</strong>нии<br />

м<strong>е</strong>да. Вам потр<strong>е</strong>бу<strong>е</strong>тся цикл, который буд<strong>е</strong>т добавлять эти св<strong>е</strong>д<strong>е</strong>ния для<br />

каждого рабоч<strong>е</strong>го, а такж<strong>е</strong> вычислять пч<strong>е</strong>лу с самым высоким потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong>м, цикл<br />

долж<strong>е</strong>н располагаться до кода, отправляюш;<strong>е</strong>го пч<strong>е</strong>л на работу (тогда матка буд<strong>е</strong>т<br />

знать колич<strong>е</strong>ство м<strong>е</strong>да, съ<strong>е</strong>д<strong>е</strong>нно<strong>е</strong> во вр<strong>е</strong>мя т<strong>е</strong>кущ<strong>е</strong>й см<strong>е</strong>ны). Такж<strong>е</strong> нужно уч<strong>е</strong>сть<br />

потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да самой маткой и добавить в кон<strong>е</strong>ц отч<strong>е</strong>та строчку «Total Honey<br />

Consumption: ххх units» (Суммарно<strong>е</strong> потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да).<br />

★ Обновит<strong>е</strong> конструктор для класса Q u een , как вы это д<strong>е</strong>лали с конструктором для<br />

класса W orker.<br />

В класс<strong>е</strong> Queen наб<strong>е</strong>рит<strong>е</strong> public<br />

public override<br />

override и нажмит<strong>е</strong> проб<strong>е</strong>л.<br />

Появится список доступных<br />

Эля п<strong>е</strong>р<strong>е</strong>крытия м<strong>е</strong>тодов. По<strong>е</strong>л<strong>е</strong><br />

выбора нужного варианта<br />

названи<strong>е</strong> базового м<strong>е</strong>тода появится<br />

автоматич<strong>е</strong>ски.<br />

^<br />

Equafe(objectobj)<br />

♦ GetHeshCodeO<br />

■ ♦ IZ Z Z ir"<br />

S ’ ShiftsLeft { g e t }<br />

ToStringO<br />

Корр<strong>е</strong>ктный уч<strong>е</strong>т вс<strong>е</strong>х данны х о пч<strong>е</strong>лах<br />

Посл<strong>е</strong> р<strong>е</strong>дактирования конструкторов Q u e e n и W o rk er тр<strong>е</strong>бу<strong>е</strong>тся вн<strong>е</strong>сти изм<strong>е</strong>н<strong>е</strong>ния<br />

и в способ их вызова. В конструкторах появился новый парам<strong>е</strong>тр W e ig h t , который сл<strong>е</strong>ду<strong>е</strong>т<br />

указать:<br />

★<br />

Worker В<strong>е</strong><strong>е</strong> #1: 175mg; Worker Bee #2:114mg; Worker Bee #3: 149mg;<br />

Worker Bee #4: 155mg; Queen Bee: 275mg<br />

Это посл<strong>е</strong>дн<strong>е</strong><strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ний, которо<strong>е</strong> тр<strong>е</strong>бовалось вн<strong>е</strong>сти в форму!<br />

дальш<strong>е</strong> ► 279


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

І'^<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong><br />

c l a s s Bee {<br />

p u b l i c B e e (d o u b le w e ig h t) {<br />

t h i s . w e i g h t = w e ig h t;<br />

}<br />

П<strong>е</strong>р<strong>е</strong>д вами класс В<strong>е</strong><strong>е</strong>, в ко-<br />

^ ° р о м происходит основной<br />

•^°^сч<strong>е</strong>т потр<strong>е</strong>бл<strong>е</strong>ния лл<strong>е</strong>да З а -<br />

^ <strong>е</strong> м эти данш<strong>е</strong> и с п о ^ц ю т с я<br />

классами Worker и Queen.<br />

p u b l i c v i r t u a l i n t S h i f t s L e f t {<br />

g e t { r e t u r n 0; }<br />

}<br />

p r i v a t e d o u b le w e ig h t;<br />

Конструктор класса В<strong>е</strong><strong>е</strong><br />

зада<strong>е</strong>т пол<strong>е</strong> Weight и м <strong>е</strong>-<br />

п^од HoneyConsumptionO<br />

Рлссчитываюищй пот р<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong><br />

м<strong>е</strong>да рабоч<strong>е</strong>й пч<strong>е</strong>лой<br />

p u b l i c v i r t u a l d o u b le G etH on eyC on su m p tion () {<br />

d o u b le c o n su m p tio n ;<br />

П ч <strong>е</strong> л а , к о т о р о й<br />

i f ( S h i f t s L e f t == 0) ____о с т а л а с ь вс<strong>е</strong>го 3-<br />

c o n su m p tio n = 7 .5 ;<br />

см<strong>е</strong>нй^ потр<strong>е</strong>бля<strong>е</strong><br />

т 3-0 <strong>е</strong>динии, м<strong>е</strong>оа,<br />

e l s e<br />

co n su m p tio n = 9 + S h i f t s L e f t ;<br />

<strong>е</strong>сли см<strong>е</strong>н Я, т о 13-<br />

и т. д. Свободная<br />

i f (w e ig h t > 150)<br />

от работы пч<strong>е</strong>ла<br />

c o n su m p tio n *= 1 .3 5 ;<br />

(ShiftsLeft = О ) поr<br />

e t u r n co n su m p tio n ;<br />

щар<strong>е</strong>бля<strong>е</strong>т 7.5.<br />

} Пч<strong>е</strong>лы с в<strong>е</strong>сом бол<strong>е</strong><strong>е</strong><br />

p u b l i c FormlО<br />

I n it i a l iz e C o m p o n e n t ( і<br />

больш<strong>е</strong> м<strong>е</strong>да.<br />

В форм<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся только<br />

конструктор.<br />

Благодаря насл<strong>е</strong>дованию<br />

вы л<strong>е</strong>гко<br />

смогли добавить<br />

в классы Qjieen<br />

и Worker пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>,<br />

учитьшающ<strong>е</strong><strong>е</strong><br />

потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да.<br />

Только пр<strong>е</strong>дставьт<strong>е</strong>,<br />

что вм<strong>е</strong>сто<br />

этого вам пришлось<br />

бы вводить<br />

повторяющийся<br />

код вручщвд!<br />

W orker[] w o rk ers = new W orker[4 ];<br />

w o r k e r s [0] = new W orker(new s t r i n g [] {<br />

w o r k e r s [1] = new W orker(new s t r i n g [] {<br />

w o r k e r s [2] = new W orker(new s t r i n g [] {<br />

w o r k e r s [3] = new W orker(new s t r i n g [] {<br />

" N ecta r c o l l e c t o r " , "Honey m a n u fa c tu r in g<br />

"Egg c a r e " , "Baby b e e t u t o r in g " } , ( l l 4 )<br />

"H ive m a in te n a n c e " , " S tin g p a t r o l" ) T ^ 4 9<br />

" N ecta r c o l l e c t o r " "Honey m a n u fa ctu rin g "<br />

"Egg c a r e " , "Baby b e e t u t o r i n g " , "H ive m a in te n a n c e " , " S tin g p a t r o l" },<br />

q u een = new Q u e e n (w o r k e r s);<br />

8 конструкторы класса<br />

Worker добавля<strong>е</strong>тся информация<br />

о в<strong>е</strong>с<strong>е</strong> рабоч<strong>е</strong>й пч<strong>е</strong>лы.<br />

280 глава 6


насл<strong>е</strong>довани<strong>е</strong><br />

p u b l i c W o r k e r ( s t r in g [] jo b slC a n D o , i n t w e ig h t)<br />

: b a s e ( w e ig h t ) {<br />

}<br />

t h i s . jo b slC a n D o = jo b slC a n D o ;<br />

p u b l i c ..o v e r r id e i n t S h i f t s L e f t {<br />

/ / . . . t h e r e s t o f t h e c l a s s i s t h e same . .<br />

. Сначала мы д<strong>е</strong>ла<strong>е</strong>м класс Queen<br />

производным от класса В<strong>е</strong><strong>е</strong>.<br />

c l a s s Queen : B ee {<br />

Матка в<strong>е</strong>сит Z 7 S м г, им<strong>е</strong>нно эт от парам<strong>е</strong>т р<br />

p u b l i c Q ueen (W ork er[] w o rk ers) п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т конст рукт ор данного класса конст рукт<br />

ору класса В<strong>е</strong><strong>е</strong>.<br />

: b a s e (275) { ^<br />

}<br />

t h i s .w o r k e r s = w o rk ers;<br />

Ґ ---<br />

Эт от цикл<br />

опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

само<strong>е</strong> само<strong>е</strong><br />

высоко<strong>е</strong><br />

потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong><br />

м<strong>е</strong>да ср<strong>е</strong>ди<br />

рабочих пч<strong>е</strong>л.<br />

p u b lic .t r i „ g » o r k T h e N e « S h i f t ( ) " f " ' ’‘ '""О « ж З о г о<br />

double totalC onBum ptloi. - 0; Эанто“ “<br />

f o r ( i n t і = 0 ; і < w o r k e r s . L en g th ; i++ ) оощ<strong>е</strong><strong>е</strong> потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong>.<br />

to ta lC o n s u m p tio n += w o r k e r s [ і ] . G etH on eyC on su m p tion ();<br />

to ta lC o n s u m p tio n += G etH on eyC on su m p tion () ;<br />

// ... Зд<strong>е</strong>сь ид<strong>е</strong>т исходный код м<strong>е</strong>тода за исключ<strong>е</strong>ни<strong>е</strong>м оп<strong>е</strong>ратора re t u rn<br />

Сг r e p o r t += "Общ<strong>е</strong><strong>е</strong> п отр <strong>е</strong>бл <strong>е</strong>ни <strong>е</strong> м <strong>е</strong> д а : " + to ta lC o n s u m p tio n +<br />

м <strong>е</strong> т о д а W o r k ^ N e x t S h i f t Q<br />

‘ о с т а л а с ь б<strong>е</strong>з и зм <strong>е</strong>н <strong>е</strong>н и й , в ы т о л ь к о д<br />

в о т ч <strong>е</strong> т данны <strong>е</strong> о п о т р <strong>е</strong> о л <strong>е</strong> н и и м <strong>е</strong>о а .<br />

p u b l i c o v e r r id e d o u b le G etH on eyC on su m p tion ()<br />

d o u b le co n su m p tio n = 0;<br />

d o u b le la rg e stW o rk erC o n su m p tio n = 0;<br />

i n t w o rk ersD o in g J o b s = 0;<br />

^ f o r ( i n t i = 0; i < w o r k e r s . L en g th ; i++)<br />

}<br />

i f ( w o r k e r s [ i ] . G etH on eyC on su m p tion 0 > la rg estW o rk erC o n su m p tio n )<br />

la rg estW o rk erC o n su m p tio n<br />

i f (w ork ers [і] . S h i f t s L e f t > 0)<br />

w o r k e rsD o in g J o b s+ + ;<br />

co n su m p tio n += la rg estW o rk erC o n su m p tio n ;<br />

i f (w o rk ersD o in g J o b s >= 3)<br />

e l s e<br />

co n su m p tio n += 30;<br />

c o n su m p tio n += 20;<br />

r e t u r n co n su m p tio n ;<br />

Ч<br />

{<br />

{<br />

<strong>е</strong>диниц"<br />

8 эт ом класс<strong>е</strong> п<strong>е</strong>р<strong>е</strong>крыва<strong>е</strong>тся<br />

м<strong>е</strong>т од CietHoneyConsumptionQ<br />

класса В<strong>е</strong><strong>е</strong>. Чтобы уч<strong>е</strong>ст ь п о ­<br />

тр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да м ат кой, вы находит<strong>е</strong><br />

рабоч<strong>е</strong>го с самым высоким<br />

потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong>м и добавля<strong>е</strong>т<strong>е</strong><br />

2 0 или 3 0 (в зависимости от<br />

колич<strong>е</strong>ства занятых пч<strong>е</strong>л).<br />

w o r k e r s [ і ] .G etH o n ey C o n su m p tio n ();<br />

Если т рудят ся 3 пч<strong>е</strong>лы и бол<strong>е</strong><strong>е</strong>,<br />

м ат к<strong>е</strong> т р<strong>е</strong>бу<strong>е</strong>т ся 3 0 дополнит<strong>е</strong>льных<br />

<strong>е</strong>диниц м<strong>е</strong>да-, в прот и в­<br />

ном случа<strong>е</strong> <strong>е</strong>й нужны вс<strong>е</strong>го ЯО до -<br />

полни т<strong>е</strong>льных <strong>е</strong>диниц.<br />

дальш<strong>е</strong> > 281


вс<strong>е</strong> мы только пч<strong>е</strong>лы<br />

Сов<strong>е</strong>рш<strong>е</strong>нству<strong>е</strong>м сист<strong>е</strong>му управл<strong>е</strong>ния уль<strong>е</strong>м при noMouiu насл<strong>е</strong>дования<br />

Основа наш<strong>е</strong>й сист<strong>е</strong>мы готова, т<strong>е</strong>п<strong>е</strong>рь воспользу<strong>е</strong>мся насл<strong>е</strong>довани<strong>е</strong>м для уч<strong>е</strong>та колич<strong>е</strong>ства<br />

м<strong>е</strong>да, съ<strong>е</strong>да<strong>е</strong>мого пч<strong>е</strong>лами. Каждая пч<strong>е</strong>ла потр<strong>е</strong>бля<strong>е</strong>т м<strong>е</strong>д, а больш<strong>е</strong> вс<strong>е</strong>го <strong>е</strong>го нужно матк<strong>е</strong>.<br />

Поэтому создадим базовый класс В<strong>е</strong><strong>е</strong>, от которого будут насл<strong>е</strong>довать классы Queen и Worker.<br />

т<br />

Класс В<strong>е</strong><strong>е</strong> сод<strong>е</strong>ржит пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>,<br />

описывающ<strong>е</strong><strong>е</strong> потр<strong>е</strong>бл<strong>е</strong>- ''<br />

ни<strong>е</strong> м<strong>е</strong>да. Так как оно зависит<br />

от колич<strong>е</strong>ства оставшихся<br />

см<strong>е</strong>н, свойство ShiftsLeft было<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>но в этот класс и<br />

пом<strong>е</strong>ч<strong>е</strong>но ключ<strong>е</strong>вым словом<br />

virtual, чтобы в класс<strong>е</strong> Worker<br />

оно могло быть п<strong>е</strong>р<strong>е</strong>крыто.<br />

Вс<strong>е</strong> пч<strong>е</strong>лы потр<strong>е</strong>бляют м<strong>е</strong>д, п о - ^<br />

этому в базовый класс добавл<strong>е</strong>н<br />

м<strong>е</strong>тод C ie tH o n e y C o n su m p tio n Q ,<br />

который могут насл<strong>е</strong>довать<br />

классы q u e e n и w o r k e r . Но матка<br />

и рабочий потр<strong>е</strong>бляют м<strong>е</strong>д поразному,<br />

поэтому м<strong>е</strong>тод пом<strong>е</strong>ч<strong>е</strong>н<br />

словом v ir tu a l, чтобы <strong>е</strong>го можно<br />

было п<strong>е</strong>р<strong>е</strong>крывать<br />

В отч<strong>е</strong>т для м а т ­<br />

ки сл<strong>е</strong>ду<strong>е</strong>т добавить<br />

данны<strong>е</strong> о потр<strong>е</strong>бл<strong>е</strong>нии<br />

м<strong>е</strong>да. Так как м а т ­<br />

ка сама потр<strong>е</strong>бля<strong>е</strong>т<br />

м<strong>е</strong>д, она должна<br />

унасл<strong>е</strong>довать от<br />

класса В<strong>е</strong><strong>е</strong> м<strong>е</strong>тод<br />

QetИoneyConsumption()<br />

и п<strong>е</strong>р<strong>е</strong>крыть <strong>е</strong>го.<br />

В<strong>е</strong><strong>е</strong><br />

public ShiftsLeft: int<br />

virtual<br />

GetHoneyConsumptionQ:<br />

double<br />

------- Queen W orker<br />

private workers: Worker[]<br />

private shiftNumber: int<br />

CurrentJob: string<br />

ShiftsLeft: int<br />

AssignWorkO<br />

WorkTheNextShiftO<br />

^когда на диаграмм<strong>е</strong><br />

i^accoS показываются<br />

возвраща<strong>е</strong>мы<strong>е</strong> знач<strong>е</strong>ния<br />

и закрыты<strong>е</strong> чл<strong>е</strong>ны.<br />

private jobslCanDo: stringQ<br />

private shiftsToWork: int<br />

private shiftsWorked: int<br />

DoThisJobO<br />

WorkOneShiftO<br />

Классу worker нужно<br />

унасл<strong>е</strong>довать м<strong>е</strong>тоды от<br />

класса В<strong>е</strong><strong>е</strong> и п<strong>е</strong>р<strong>е</strong>крыть<br />

м<strong>е</strong>тод ShiftsLeft.<br />

шв<br />

ство им<strong>е</strong>н брумнуи?. -------


'о ^<br />

и а б с т р а т с ш н ы <strong>е</strong> К Л а с с ь !<br />

% Пусть классы<br />

д<strong>е</strong>ржат об<strong>е</strong>щания<br />

Д<strong>е</strong>йствия значат больш<strong>е</strong>, ч<strong>е</strong>м слова.<br />

Иногда возника<strong>е</strong>т н<strong>е</strong>обходимость сгруппировать объ<strong>е</strong>кты по вы полня<strong>е</strong>мы м<br />

ф ункциям , а н<strong>е</strong> по кпассам, от которых они насл<strong>е</strong>дуют. Зд<strong>е</strong>сь вам на помощь<br />

приходят инт<strong>е</strong>рф <strong>е</strong>йсы , они позволяют работать с любым классом, отв<strong>е</strong>чающим<br />

вашим потр<strong>е</strong>бностям. Но ч<strong>е</strong>м больш <strong>е</strong> возможност<strong>е</strong>й, т<strong>е</strong>м вы ш<strong>е</strong><br />

отв<strong>е</strong>тств<strong>е</strong>нность, и <strong>е</strong>сли классы, р<strong>е</strong>ализующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс, н<strong>е</strong> вы полнят<br />

обязат<strong>е</strong>льств ... программа компилироваться н<strong>е</strong> буд<strong>е</strong>т.


рабочи<strong>е</strong> пч<strong>е</strong>лы, объ<strong>е</strong>диняйт<strong>е</strong>сь!<br />

В<strong>е</strong>рн<strong>е</strong>мся к нашим пч<strong>е</strong>лам<br />

Было принято р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> пр<strong>е</strong>вратить сист<strong>е</strong>му уч<strong>е</strong>та из<br />

пр<strong>е</strong>дыдущ^<strong>е</strong>й главы в полноц<strong>е</strong>нный симулятор улья.<br />

Вот как выглядит сп<strong>е</strong>цификация новой в<strong>е</strong>рсии программы:<br />

Симулятор улья<br />

Для лучш<strong>е</strong>го пр<strong>е</strong>дставл<strong>е</strong>ния жизни в уль<strong>е</strong> укаж<strong>е</strong>м сп<strong>е</strong>ииальны<strong>е</strong><br />

возможности рабочих пч<strong>е</strong>л:<br />

• Вс<strong>е</strong> пч<strong>е</strong>лы потр<strong>е</strong>бляют м<strong>е</strong>д и обладают в<strong>е</strong>сом.<br />

. Матка разда<strong>е</strong>т задания, сл<strong>е</strong>дит за отч<strong>е</strong>тами и отправля<strong>е</strong>т<br />

рабочих на сл<strong>е</strong>дующую см<strong>е</strong>ну.<br />

• Рабочи<strong>е</strong> трудятся посм<strong>е</strong>нно.<br />

• Охранники «точат» жало, ишут врагов и жалят их.<br />

. Сборшики м<strong>е</strong>да ишут цв<strong>е</strong>ты, собирают н<strong>е</strong>ктар и воз-<br />

врашаются в ул<strong>е</strong>й.<br />

сохранять<br />

от ви!<br />

в зависимости<br />

от выполня<strong>е</strong>мых ими функций<br />

Много<strong>е</strong> о ста <strong>е</strong> тся н<strong>е</strong>изм<strong>е</strong>нным<br />

в новом симулятор<strong>е</strong> улья пч<strong>е</strong>лы потр<strong>е</strong>бляют м<strong>е</strong>д<br />

т<strong>е</strong>м ж<strong>е</strong> способом, что и раньш<strong>е</strong>. Матка по-пр<strong>е</strong>жн<strong>е</strong>му<br />

должна раздавать задания и отсл<strong>е</strong>живать, сколько<br />

см<strong>е</strong>н осталось отработать каждой пч<strong>е</strong>л<strong>е</strong>. Рабочи<strong>е</strong><br />

по-пр<strong>е</strong>жн<strong>е</strong>му трудятся посм<strong>е</strong>нно. Просто их д<strong>е</strong>ят<strong>е</strong>льность<br />

пр<strong>е</strong>т<strong>е</strong>рп<strong>е</strong>ла н<strong>е</strong>больши<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ния.<br />

284 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Классы для различных типов пч<strong>е</strong>л<br />

Вот и<strong>е</strong>рархия с классами W o r k e r и Q u e en , насл<strong>е</strong>дующими от класса В<strong>е</strong><strong>е</strong>.<br />

При этом класс W o r k e r им<strong>е</strong><strong>е</strong>т производны<strong>е</strong> классы N e c t a r C o l l e c t o r<br />

(Сборщик м<strong>е</strong>да) и S t i n g P a t r o l (Охранник).<br />

о о<strong>е</strong>с<strong>е</strong> пч<strong>е</strong>л<br />

Так будут выгляд<strong>е</strong>ть<br />

новы<strong>е</strong> производны<strong>е</strong><br />

классы.<br />

J VJorke,<br />

о рабочих см<strong>е</strong>нах<br />

Worker<br />

Job<br />

ShiftsToWork<br />

ShiftsWorked<br />

ShiftsLeft<br />

DoThisJobO<br />

WorkOneShiftO<br />

Queen<br />

WorkerQ<br />

ShiftNumber<br />

AssignWorkO<br />

WorkTheNextShiftO<br />

HoneyConsumptionO<br />

class StingPatrol : Worker<br />

i n t S tin g e r L e n g th ;<br />

b o o l en em y A lert;<br />

p u b l i c b o o l S h a r p e n S tin g e r<br />

{...}<br />

( i n t L ength)<br />

p u b l i c b o o l L ookForE nem ies ( ) { . . ' . }<br />

p u b l i c v o id S t i n g ( s t r i n g E nem y){ . . . }<br />

StingPatrol<br />

StingerLength<br />

EnemyAlert<br />

NectarCollector<br />

Nectar<br />

class NectarCollector ; Worker<br />

{<br />

i n t N e c ta r ;<br />

p u b l i c v o id F in d F lo w er s (){...}<br />

p u b l i c v o id G a th e r N e c ta r ( ) { . . . }<br />

p u b l i c v o id R e tu r n T o H iv e ( ) { . . . }<br />

SharpenStingerO<br />

LookForEnemiesO<br />

StingO<br />

FindFlowersO<br />

GatherNectarO<br />

RetumToHiveO<br />

1<br />

классы<br />

>^анят ин~<br />

Формации)<br />

> 285


инт<strong>е</strong>рф<strong>е</strong>йсы для работы<br />

инт<strong>е</strong>рф<strong>е</strong>йсы<br />

Насл<strong>е</strong>довать класс мож<strong>е</strong>т только от одного класса. Поэтому создани<strong>е</strong><br />

двух производных классов S t i n g P a t r o l и N e c t a r C o l l e c t o r н<strong>е</strong> помож<strong>е</strong>т<br />

нам описать пч<strong>е</strong>лу, которая в состоянии выполнять задания разных<br />

типов.<br />

М<strong>е</strong>тод D e f e n d T h e H iv e () (Защита улья) из класса Q u e e n мож<strong>е</strong>т заставить<br />

объ<strong>е</strong>кты S t i n g P a t r o l защищать ул<strong>е</strong>й. Но <strong>е</strong>сли матка захоч<strong>е</strong>т, чтобы<br />

за эту работу принялись други<strong>е</strong> пч<strong>е</strong>лы, она н<strong>е</strong> смож<strong>е</strong>т дать им команду:<br />

class Queen {<br />

private void DefendTheHive(StingPatrol patroller) { }<br />

}<br />

'G<br />

Класс, р<strong>е</strong>ализующий<br />

инт<strong>е</strong>рф<strong>е</strong>йс,<br />

долж<strong>е</strong>н включать<br />

в с<strong>е</strong>бя вс<strong>е</strong><br />

м<strong>е</strong>тоды и свойства,<br />

указанны<strong>е</strong><br />

в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нии<br />

инт<strong>е</strong>рф<strong>е</strong>йса.<br />

Объ<strong>е</strong>кт N e c t a r C o l l e c t o r ум<strong>е</strong><strong>е</strong>т собирать н<strong>е</strong>ктар, а экз<strong>е</strong>мпляры S t i n g P a t r o l борются с врагами.<br />

Но даж<strong>е</strong> <strong>е</strong>сли матка научит сборщиков н<strong>е</strong>ктара защищать ул<strong>е</strong>й, добавив м<strong>е</strong>тоды S h a r p e n S t i n g e r ()<br />

и L o o k F o r E n e m ie s О в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> их класса, она вс<strong>е</strong> рав н о н<strong>е</strong> смож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дать их сво<strong>е</strong>му м<strong>е</strong>тоду<br />

D e f e n d T h e H iv e (). Впроч<strong>е</strong>м, можно воспользоваться двумя м<strong>е</strong>тодами:<br />

private void DefendTheHive(StingPatrol patroller);<br />

private void AlternateDefendTheHive(NectarCollector patroller);<br />

Ho это плохо<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>. Вы получа<strong>е</strong>т<strong>е</strong> два фрагм<strong>е</strong>нта<br />

кода, <strong>е</strong>динств<strong>е</strong>нным различи<strong>е</strong>м которьк явля<strong>е</strong>тся то,<br />

что один м<strong>е</strong>тод им<strong>е</strong><strong>е</strong>т парам<strong>е</strong>тр S t i n g P a t r o l , а второй—N<br />

e c t a r C o l l e c t o r .<br />

К счастью, р<strong>е</strong>шить подобны<strong>е</strong> пробл<strong>е</strong>мы позволяют<br />

инт<strong>е</strong>рф <strong>е</strong>йсы (interfaces). Они опр<strong>е</strong>д<strong>е</strong>ляют, каки<strong>е</strong> м<strong>е</strong>тоды<br />

должны присутствовать в класс<strong>е</strong>.<br />

М<strong>е</strong>тоды, указанны<strong>е</strong> в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нии инт<strong>е</strong>рф<strong>е</strong>йса, должны<br />

быть р<strong>е</strong>ализованы. В противном случа<strong>е</strong> компилятор<br />

выдаст сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>. Код м<strong>е</strong>тодов мож<strong>е</strong>т быть<br />

написан н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно в рассматрива<strong>е</strong>мом класс<strong>е</strong><br />

или ж<strong>е</strong> унасл<strong>е</strong>дован от базового класса. Инт<strong>е</strong>рф<strong>е</strong>йс н<strong>е</strong><br />

инт<strong>е</strong>р<strong>е</strong>су<strong>е</strong>т происхожд<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тодов и свойств, главно<strong>е</strong><br />

—чтобы при компиляции кода они были на сво<strong>е</strong>м<br />

м<strong>е</strong>ст<strong>е</strong>.<br />

Даж<strong>е</strong> <strong>е</strong>сли матка добавит м&тоды защиты<br />

обь<strong>е</strong>кту NectarCollectorJ она н<strong>е</strong><br />

смож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дать их сво<strong>е</strong>му м<strong>е</strong>тоду<br />

PefendTheHiveQ, так как он ожида<strong>е</strong>т<br />

ссылки StingPatrol. Приравнять ж<strong>е</strong> ссылку<br />

StingPatrol объ<strong>е</strong>кту NectarCollector н<strong>е</strong>возможно.<br />

К<br />

Можно добавить аналогичный м<strong>е</strong>тод<br />

с названи<strong>е</strong>м AlternatePefendTheHiveQ, _<br />

который буд<strong>е</strong>т ссылаться на объ<strong>е</strong>кт<br />

NectarCollector, но код получится<br />

слиилком громоздким и н<strong>е</strong>удобным. _<br />

М<strong>е</strong>тоды PefendTheHiveQ<br />

j<br />

и AlternatePefendTheHiveQ будут отличаться<br />

только типом парам<strong>е</strong>тра. А чтобы заставить<br />

защищать ул<strong>е</strong>й объ<strong>е</strong>кты ВаЬуВ<strong>е</strong><strong>е</strong>Саг<strong>е</strong><br />

или Maintenance , вам потр<strong>е</strong>буются дополнит<strong>е</strong>льны<strong>е</strong>,<br />

«альт<strong>е</strong>рнативны<strong>е</strong>» м<strong>е</strong>тоды.<br />

286 глава 7


Ключ<strong>е</strong>во<strong>е</strong> слово interface<br />

инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Чтобы добавить инт<strong>е</strong>рф<strong>е</strong>йс к программ<strong>е</strong>, писать м<strong>е</strong>тоды<br />

н<strong>е</strong> нужно. Достаточно указать их парам<strong>е</strong>тры и тип возвраща<strong>е</strong>мого<br />

ими знач<strong>е</strong>ния. И поставить в конц<strong>е</strong> строки<br />

точку с запятой.<br />

Инт<strong>е</strong>рф<strong>е</strong>йсы н<strong>е</strong> хранят данны<strong>е</strong>, поэтому вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong><br />

добавить к ним поля. Но можно добавить опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ния<br />

свойств. Д<strong>е</strong>ло в том, что инт<strong>е</strong>рф<strong>е</strong>йс опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т список м<strong>е</strong>тодов<br />

класса с опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нными им<strong>е</strong>нами, типами и парам<strong>е</strong>трами.<br />

Если вам каж<strong>е</strong>тся, что пробл<strong>е</strong>ма мож<strong>е</strong>т быть р<strong>е</strong>ш<strong>е</strong>на<br />

добавл<strong>е</strong>ни<strong>е</strong>м поля к инт<strong>е</strong>рф<strong>е</strong>йсу, попробуйт<strong>е</strong> вм<strong>е</strong>сто этого<br />

добавить свойство, вполн<strong>е</strong> в<strong>е</strong>роятно, это им<strong>е</strong>нно то, что<br />

вам было н у ж н о ^ ^ ^ _ ^ interface iStingPatrol<br />

И нт<strong>е</strong>рф<strong>е</strong>йс {<br />

объявля<strong>е</strong>тся: Л . ^sint AlertLevel { get;}<br />

int StingerLength { get; set;}<br />

bool LookForEnemiesO;<br />

int SharpenStinger(int length)<br />

И нт <strong>е</strong>рф ш сш стоит давать<br />

им<strong>е</strong>на, начинающи<strong>е</strong>ся с п^описнои<br />

бцквы I. Н<strong>е</strong>т, правила, одязмбающ<strong>е</strong>го<br />

вас так nocmynamt^, но э т о<br />

д<strong>е</strong>ла<strong>е</strong>т код бол<strong>е</strong>в простым. Чтоды<br />

u6edumt>ca, насколько это обл<strong>е</strong>гча<strong>е</strong>т<br />

жизнь, установит<strong>е</strong> курсор на<br />

пистун> строчку внутри любого<br />

м<strong>е</strong>тода и наб<strong>е</strong>рит<strong>е</strong> I— Inte/liSense<br />

сразу ж<strong>е</strong> покаж<strong>е</strong>твам список доступных<br />

инт<strong>е</strong>рф<strong>е</strong>йсов NET<br />

Любому классу,<br />

р<strong>е</strong>ализующ<strong>е</strong>му<br />

инт<strong>е</strong>рф<strong>е</strong>йс, понадобится<br />

м<strong>е</strong>тод<br />

SharpenStingerO<br />

С парам <strong>е</strong>т ром типа<br />

int.<br />

interface INectarCollector<br />

{<br />

void FindFlowersO;<br />

void GatherNectar<br />

void ReturnToHive<br />

^<br />

;;; ' t C »<br />

Так как ж<strong>е</strong> помочь матк<strong>е</strong>? Т<strong>е</strong>п<strong>е</strong>рь она мож<strong>е</strong>т создать м<strong>е</strong>тод, б<strong>е</strong>рущий<br />

ЛЛЫНО и(^0МЯК9>^‘’<br />

Л(^0 ЭЛСМ6НТЫ ОТКОЫ“<br />

в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра любой объ<strong>е</strong>кт, который зна<strong>е</strong>т, как защитить ул<strong>е</strong>й: *<br />

p r i v a t e v o i d D e f e n d T h e H i v e ( I S t i n g P a t r o l p a t r o l l e r )<br />

ТОГО инт<strong>е</strong>рф<strong>е</strong>йса по<br />

J<br />

Этот м<strong>е</strong>тод мож<strong>е</strong>т использовать объ<strong>е</strong>кт S t i n g P a t r o l , N e c t a r S t i n g e r<br />

или любую другую пч<strong>е</strong>лу, знающую, как защитить ул<strong>е</strong>й. При р<strong>е</strong>ализации<br />

умолчанию являются<br />

открытыми. То <strong>е</strong>сть<br />

с помопц>ю инт<strong>е</strong>р-<br />

I S t i n g P a t r o l м <strong>е</strong>тод D e f e n d T h e H iv e о гарантиру<strong>е</strong>т нал ичи<strong>е</strong> у объ<strong>е</strong>к- ( g jjJ О П О <strong>е</strong> Д <strong>е</strong> Л Я С ”<br />

та свойств и м <strong>е</strong>тодов, н <strong>е</strong>о б х о д и м ы х для защ иты улья. i г<br />

т<strong>е</strong> открыты<strong>е</strong> м<strong>е</strong>тоды<br />

^ <strong>е</strong> н т О ^<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда я знаю,<br />

как защитить ул<strong>е</strong>й, мы<br />

в б<strong>е</strong>зопасности!<br />

и свойства любого<br />

р<strong>е</strong>ализующ<strong>е</strong>го <strong>е</strong>го<br />

класса.<br />

дальш<strong>е</strong> > 287


.ласс<br />

н<strong>е</strong>много от сборщика н<strong>е</strong>ктара и н<strong>е</strong>много от охранника улья<br />

Экз<strong>е</strong>мпляр NectarStinger<br />

Используйт<strong>е</strong> дво<strong>е</strong>точи<strong>е</strong>, чтобы р<strong>е</strong>ализовать инт<strong>е</strong>рф<strong>е</strong>йс. Посл<strong>е</strong><br />

дво<strong>е</strong>точия сначала указыва<strong>е</strong>тся класс, от которого происходит<br />

насл<strong>е</strong>довани<strong>е</strong>, зат<strong>е</strong>м список инт<strong>е</strong>рф<strong>е</strong>йсов. Если насл<strong>е</strong>дования<br />

н<strong>е</strong> происходит, то инт<strong>е</strong>рф<strong>е</strong>йсы п<strong>е</strong>р<strong>е</strong>числяются<br />

в произвольном порядк<strong>е</strong>.<br />

.. ^ _<br />

Как и в случа<strong>е</strong> насл<strong>е</strong>дования,<br />

Э т о т класс нлсл<strong>е</strong>Эч<strong>е</strong>ил ом<br />

класса Worker и р<strong>е</strong>ализу<strong>е</strong>м<br />

для р<strong>е</strong>ализаиии инм<strong>е</strong>рф<strong>е</strong>йса<br />

использу<strong>е</strong>тся Эво<strong>е</strong>мочи<strong>е</strong>.<br />

иим<strong>е</strong>рф<strong>е</strong>йсы INectarCollector<br />

IStingPatrol. ^<br />

class NectarStinger^^^WorkerQlNectarCollector,<br />

IStingPatrol {<br />

■\Анм<strong>е</strong>рдр<strong>е</strong>йсы<br />

public int AlertLevel { п <strong>е</strong> р <strong>е</strong> ч и с л я ю т с я<br />

y' ^ get { return alertLevel; J ч<strong>е</strong>р<strong>е</strong>з з а п я т у ю .<br />

’e c t a r S t i n gii^.r<br />

e r ^<br />

ада<strong>е</strong>м вспохогат<strong>е</strong>льно<strong>е</strong><br />

,ол<strong>е</strong> для сбойтва<br />

A le r tL e v e l<br />

I м<strong>е</strong>тод<strong>е</strong><br />

^ o o k F o rE n e m ie sQ -<br />

КаждоЩ<br />

м<strong>е</strong>тоду 6 1ЛНщл<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong><br />

соотб<strong>е</strong>тстба<br />

“<br />

<strong>е</strong> т т глоЪ в<br />

класс<strong>е</strong>. Инач<strong>е</strong><br />

у^рограм м а н<strong>е</strong><br />

5 уд<strong>е</strong>т KOfAnu<br />

л и р о ва т м я .<br />

ргдЬИс int StingerLength {<br />

get { return StingerLength;<br />

set {<br />

StingerLength = value;<br />

}<br />

public bool LookForSnemies() {•■•}<br />

public int SharpenStinger(int length)<br />

pxiblic void FindFlowersO {...}<br />

public void GatherNectarO {...}<br />

pviblic void RetumToHiveO {.•.}<br />

С о зд а н н ы й в а м и о б ь <strong>е</strong> к т<br />

N e c t a r S t in g e r с м о ж <strong>е</strong> т б ы -<br />

п о л н я т » р а б о т у п ч <strong>е</strong> л к а к<br />

и з к л а с с а N e c ta r C o lle c to r , т а к<br />

и из к л а с с а S tin g P a tr o l.<br />

В<strong>е</strong>ли врагов н<strong>е</strong>м<br />

пч<strong>е</strong>ла пряч<strong>е</strong>м жало,<br />

оспомогам<strong>е</strong>льно<strong>е</strong><br />

1^ол<strong>е</strong> StingerLenqtk<br />

м<strong>е</strong>ня<strong>е</strong>м сво<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong>.<br />

Класс, р<strong>е</strong>ализующий инт<strong>е</strong>рф<strong>е</strong>йс так ж<strong>е</strong>, как и обычный, созда<strong>е</strong>т<br />

экз<strong>е</strong>мпляры при помощи оп<strong>е</strong>ратора new и использу<strong>е</strong>т м<strong>е</strong>тоды:<br />

N e c t a r S t in g e r bobT heB ee = new N e c t a r S t i n g e r ( );<br />

bo b T h eB ee. L o o k F o rE n em ies{);<br />

bo b T h eB ee. F in d F lo w e r s ( );<br />

_ Чаоцо<br />

------------^ а Д а Б а <strong>е</strong> М ы <strong>е</strong> ------------<br />

Б оЛ роС Ь !<br />

Зач<strong>е</strong>м симулятору улья инт<strong>е</strong>рф<strong>е</strong>йсы?<br />

В<strong>е</strong>дь мы добавля<strong>е</strong>м <strong>е</strong>щ<strong>е</strong> один класс<br />

NectarStinger, и вс<strong>е</strong> равно получа<strong>е</strong>м<br />

дублирующийся код?<br />

О; Инт<strong>е</strong>рф<strong>е</strong>йсы и н<strong>е</strong> пр<strong>е</strong>дназнач<strong>е</strong>ны для борьбы<br />

с'дублирующимся кодом. Они просто позволяют<br />

использовать один и тот ж<strong>е</strong> класс в разных<br />

ситуациях. Вам тр<strong>е</strong>бовалось создать класс рабочих<br />

пч<strong>е</strong>л, которы<strong>е</strong> могут выполнять два задания.<br />

Инт<strong>е</strong>рф<strong>е</strong>йсы дают возможность получить класс,<br />

выполняющий произвольно<strong>е</strong> колич<strong>е</strong>ство заданий.<br />

Скаж<strong>е</strong>м, у вас <strong>е</strong>сть м<strong>е</strong>тод P a tro lT h eH iv e (),<br />

работающий с объ<strong>е</strong>ктом S t in g P a t r o l,<br />

и м<strong>е</strong>тод C o lle c t N e c t a r () для объ<strong>е</strong>кта<br />

N e c t a r C o lle c t o r . При этом хоч<strong>е</strong>тся, чтобы<br />

класс S t in g P a t r o l мог насл<strong>е</strong>довать от<br />

класса N e c t a r C o lle c t o r ИЛИ наоборот, в<strong>е</strong>дь<br />

в каждом класс<strong>е</strong> <strong>е</strong>сть открыты<strong>е</strong> м<strong>е</strong>тоды и свойства,<br />

отсутствующи<strong>е</strong> у другого. А т<strong>е</strong>п<strong>е</strong>рь подумайт<strong>е</strong>, как<br />

можно создать класс, экз<strong>е</strong>мпляры которого могут<br />

быть п<strong>е</strong>р<strong>е</strong>даны обоим м<strong>е</strong>тодам. Есть каки<strong>е</strong>-нибудь<br />

ид<strong>е</strong>и?<br />

Пробл<strong>е</strong>му р<strong>е</strong>шают инт<strong>е</strong>рф<strong>е</strong>йсы. Создав ссылку<br />

IStingPatrol, вы мож<strong>е</strong>т<strong>е</strong> указать на любой объ<strong>е</strong>кг,<br />

р<strong>е</strong>ализующий I S t in g P a t r o l, какому<br />

бы классу этот объ<strong>е</strong>кг ни принадл<strong>е</strong>жал. Можно<br />

указать, как на объ<strong>е</strong>кг S t in g P a t r o l, так и на<br />

объ<strong>е</strong>кг N e c t a r S t in g e r ИЛИ<strong>е</strong>щ<strong>е</strong> на что-нибудь.<br />

При этом вы мож<strong>е</strong>т<strong>е</strong> использовать вс<strong>е</strong> м<strong>е</strong>тоды и<br />

свойства, которы<strong>е</strong> являются частью инт<strong>е</strong>рф<strong>е</strong>йса<br />

I S t in g P a t r o l, н<strong>е</strong>зависимо от типа объ<strong>е</strong>кта.<br />

Разум<strong>е</strong><strong>е</strong>тся, вам прид<strong>е</strong>тся создать новый класс,<br />

который и буд<strong>е</strong>т р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс. Так что<br />

этот инструм<strong>е</strong>нт н<strong>е</strong> позволит изб<strong>е</strong>жать создания<br />

дополнит<strong>е</strong>льных классов или сократить колич<strong>е</strong>ство<br />

дублирующ<strong>е</strong>гося кода. Он вс<strong>е</strong>го лишь да<strong>е</strong>т возможность<br />

получить класс для выполн<strong>е</strong>ния н<strong>е</strong>скольких<br />

работ б<strong>е</strong>з привл<strong>е</strong>ч<strong>е</strong>ния насл<strong>е</strong>дования. В<strong>е</strong>дь насл<strong>е</strong>дуются<br />

вс<strong>е</strong> м<strong>е</strong>тоды, свойства и поля другого класса.<br />

Как при работ<strong>е</strong> с инт<strong>е</strong>рф<strong>е</strong>йсами изб<strong>е</strong>жать дублирующ<strong>е</strong>гося<br />

кода? Можно создать отд<strong>е</strong>льный<br />

класс с им<strong>е</strong>н<strong>е</strong>м s t i n g e r и кодом, относящимся<br />

к укусам или сбору н<strong>е</strong>ктара. Посл<strong>е</strong> ч<strong>е</strong>го объ<strong>е</strong>кгы<br />

N e c t a r S t in g e r H N e c ta r C o lle c to r<br />

смогут создать закрытый экз<strong>е</strong>мпляр s t i n g e r ,<br />

и для сбора н<strong>е</strong>ктара будут использовать <strong>е</strong>го м<strong>е</strong>тоды<br />

и задавать <strong>е</strong>го свойства.<br />

288 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Классы, {р<strong>е</strong>ализующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсы, дол)кны включать ВСЕ<br />

м<strong>е</strong>тоды инт<strong>е</strong>рф<strong>е</strong>йсов<br />

Р<strong>е</strong>ализация инт<strong>е</strong>рф<strong>е</strong>йсов означа<strong>е</strong>т, что в класс<strong>е</strong> должны присутствовать<br />

вс<strong>е</strong> объявл<strong>е</strong>нны<strong>е</strong> в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong> м<strong>е</strong>тоды и свойства. Если это н<strong>е</strong><br />

так, программа н<strong>е</strong> компилиру<strong>е</strong>тся. Если класс р<strong>е</strong>ализу<strong>е</strong>т н<strong>е</strong>сколько инт<strong>е</strong>рф<strong>е</strong>йсов,<br />

он долж<strong>е</strong>н включать в с<strong>е</strong>бя вс<strong>е</strong> свойства и м<strong>е</strong>тоды каждого<br />

их них. Впроч<strong>е</strong>м, мож<strong>е</strong>т<strong>е</strong> н<strong>е</strong> в<strong>е</strong>рить на слово...<br />

Г - У п р а ж н <strong>е</strong> н и <strong>е</strong><br />

О Создайт<strong>е</strong> ново<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong> и добавьт<strong>е</strong> в н<strong>е</strong>го класс IS tin g P a tro l.c s<br />

В файл вв<strong>е</strong>дит<strong>е</strong> код инт<strong>е</strong>рф<strong>е</strong>йса I S t i n g P a t r o l , прив<strong>е</strong>д<strong>е</strong>нный пару страниц назад. Программа<br />

при этом буд<strong>е</strong>т компилироваться.<br />

О Добавьт<strong>е</strong> к про<strong>е</strong>кту класс В<strong>е</strong><strong>е</strong><br />

Но пока н<strong>е</strong> добавляйт<strong>е</strong> ни свойств, ни м<strong>е</strong>тодов. Заставьт<strong>е</strong> этот класс р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс<br />

IStingPatrol:<br />

c l a s s B e e : I S t i n g P a t r o l<br />

{<br />

}<br />

О П опы тайт<strong>е</strong>сь скомпилировать проградш у<br />

Выб<strong>е</strong>рит<strong>е</strong> команду Rebuild в м<strong>е</strong>ню Build. Компилятор н<strong>е</strong> запустится:<br />

Error List<br />

! O 4 Errors 0 Warnings 0 Messages<br />

O i<br />

©2<br />

© 3<br />

0 4<br />

Description<br />

'IStingPatroLExperimervt.Bee' does not implement interface member ’IStingPatroLExperiment.!StingPatrol.ShsrpenStingef(int)'<br />

IStingPatroL&tpsriment.Bee' does not implement interface member 'IStingPatrQl_Experiment,IStitT§Patrol.LooicFQrEnem(e50‘<br />

'IStingPatroLExperiment.Bee' does not implement interface member '!StingPatrol_E](perrment.lStingPatro!.Stin§erLength‘<br />

'IStingPatroLExperiment.Bee' does not implement interface member ’IStingPatrol_Experiment.lStingPatrol.AtertLever<br />

лизовали каждый м<strong>е</strong>тод инт<strong>е</strong>рф<strong>е</strong>йса.<br />

Добавьт<strong>е</strong> в класс В<strong>е</strong><strong>е</strong> м<strong>е</strong>тоды и свойства<br />

Добавьт<strong>е</strong> м<strong>е</strong>тоды L o o k F o r E n e m ie s и S h a r p e n S t i n g e r . Пока они н<strong>е</strong> должны выполнять<br />

никаких функций, они должны просто компилироваться. Добавьт<strong>е</strong> м<strong>е</strong>тод чт<strong>е</strong>ния для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

A l e r t L e v e l типа i n t и м<strong>е</strong>тоды чт<strong>е</strong>ния и записи для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной S t i n g e r L e n g t h .<br />

Посл<strong>е</strong> этого программа снова начн<strong>е</strong>т компилироваться!<br />

дальш<strong>е</strong> * 289


поваля<strong>е</strong>м дурака<br />

Учимся работать с инт<strong>е</strong>рф<strong>е</strong>йсами<br />

Использовать инт<strong>е</strong>рф<strong>е</strong>йсы л<strong>е</strong>гко. Вы пойм<strong>е</strong>т<strong>е</strong> это, н<strong>е</strong>много по- ^ I<br />

практиковавшись. Начнит<strong>е</strong> с создания про<strong>е</strong>кта Windows Forms ^ jTLp’aXHeHue.<br />

Application. П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> на форму кнопку и приступим!<br />

'<br />

Это класс T a l lG u y (Высокий пар<strong>е</strong>нь) и код для кнопки, нажати<strong>е</strong> которой созда<strong>е</strong>т объ<strong>е</strong>кт<br />

и вызыва<strong>е</strong>т <strong>е</strong>го м<strong>е</strong>тод T a l k A b o u t Y o u r s e l f () (Рассказ о с<strong>е</strong>б<strong>е</strong>). Пока нич<strong>е</strong>го нового:<br />

c l a s s T a l lG u y {<br />

}<br />

p u b l i c s t r i n g Nam e;<br />

p u b l i c i n t H e i g h t ;<br />

p u b l i c v o i d T a l k A b o u t Y o u r s e l f 0 {<br />

}<br />

M e s s a g e B o x .S h o w ( "М<strong>е</strong>ня з о в у т " + Name + " я р о с т о м "<br />

+ H e i g h t + " с м . " ) ;<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

1<br />

T a l lG u y t a l l G u y = n ew T a l l G u y () { H e i g h t = 1 9 0 , Name = "<strong>Дж</strong>имми" } ;<br />

t a l l G u y . T a l k A b o u t Y o u r s e l f ( ) ;<br />

© Создадим и н т <strong>е</strong> р ф <strong>е</strong> й с I C low n .<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты инт<strong>е</strong>рф<strong>е</strong>йса должны быть открытыми. Пров<strong>е</strong>рим это утв<strong>е</strong>ржд<strong>е</strong>ни<strong>е</strong><br />

на практик<strong>е</strong>. Создайт<strong>е</strong> новый про<strong>е</strong>кт и объявит<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс:<br />

in t e r f a c e IClown<br />

Т<strong>е</strong>п<strong>е</strong>рь попробуйт<strong>е</strong> объявить внутри н<strong>е</strong>го закрытый м<strong>е</strong>тод:<br />

p r iv a t e v o id Honk О ;<br />

Выбрав команду B uild»B uild Solution, вы увидит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong>:<br />

Модификатор public<br />

оку т ри инт <strong>е</strong>рф <strong>е</strong>йса<br />

писат ь н<strong>е</strong> нужно,<br />

доступ ко вс<strong>е</strong>м <strong>е</strong>го<br />

м<strong>е</strong>т одам и свойствам<br />

им<strong>е</strong><strong>е</strong>т ся по умолчанию<br />

0 1 The modifier 'private' is not valid for this item I<br />

Удалит<strong>е</strong> модификатор p r iv a t e , сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong> исч<strong>е</strong>зн<strong>е</strong>т.<br />

© Попробуйт<strong>е</strong> создать инт<strong>е</strong>рф<strong>е</strong>йс I C lo w n самостоят<strong>е</strong>льно и заставьт<strong>е</strong> класс T a l lG u y <strong>е</strong>го р<strong>е</strong>ализовывать.<br />

Начнит<strong>е</strong> с создания класса I C lo w n . c s .<br />

Инт<strong>е</strong>рф<strong>е</strong>йс IC lo w n долж<strong>е</strong>н им<strong>е</strong>ть н<strong>е</strong> возвращающий знач<strong>е</strong>ний и н<strong>е</strong> им<strong>е</strong>ющий парам<strong>е</strong>тров м<strong>е</strong>тод<br />

H onk (Гудок) и пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> только для чт<strong>е</strong>ния свойство F u n n y T h in g lH a v e (Смотри,<br />

что у м<strong>е</strong>ня <strong>е</strong>сть) типа s t r i n g с м<strong>е</strong>тодом чт<strong>е</strong>ния, но б<strong>е</strong>з м<strong>е</strong>тода записи.<br />

290 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Q<br />

Вы записали инт<strong>е</strong>рф<strong>е</strong>йс вот так?<br />

i n t e r f a c e IClown<br />

{<br />

}<br />

s t r i n g F unnyT hinglH ave { g e t ; }<br />

v o i d H onk() ;<br />

Это прим<strong>е</strong>р инт<strong>е</strong>рф<strong>е</strong>йса, им<strong>е</strong>ющ<strong>е</strong>го<br />

м<strong>е</strong>тод чт<strong>е</strong>ния, но н<strong>е</strong> им<strong>е</strong>ющ<strong>е</strong>го<br />

м<strong>е</strong>тода записи. Помнит<strong>е</strong>, что<br />

инт<strong>е</strong>рф<strong>е</strong>йсы н<strong>е</strong> могут им<strong>е</strong>ть пол<strong>е</strong>й,<br />

но когда вы р<strong>е</strong>ализу<strong>е</strong>т<strong>е</strong> свойство,<br />

пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> только для чт<strong>е</strong>ния<br />

аля остальных объ<strong>е</strong>ктов оно выглядит<br />

как пол<strong>е</strong>.<br />

Заставим класс T a l lG u y р<strong>е</strong>ализовывать IC lo w n . Помнит<strong>е</strong>, что посл<strong>е</strong> дво<strong>е</strong>точия сначала<br />

ставится имя базового класса (<strong>е</strong>сли такой им<strong>е</strong><strong>е</strong>тся), а зат<strong>е</strong>м список инт<strong>е</strong>рф<strong>е</strong>йсов<br />

ч<strong>е</strong>р<strong>е</strong>з запятую. В данном случа<strong>е</strong> базовый класс отсутству<strong>е</strong>т, поэтому напиш<strong>е</strong>м:<br />

c l a s s T allG u y : IC low n<br />

^ — Р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс IClown буд<strong>е</strong>т класс Tailduy.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что остальной код класса остался б<strong>е</strong>з изм<strong>е</strong>н<strong>е</strong>ний. Выб<strong>е</strong>рит<strong>е</strong> команду<br />

Build Solution в м<strong>е</strong>ню Build, чтобы построить р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>. Появятся два сообш,<strong>е</strong>ния об<br />

ошибк<strong>е</strong>. Вот одно из них: , „ „<br />

Объявив, что класс<br />

I TallGuy р<strong>е</strong>ализу<strong>е</strong>т ин-<br />

'T a llG u y ' d o e s n o t im plem ent i n t e r f a c e<br />

т<strong>е</strong>рф&ис IClown, вы<br />

member ' IC lo w n . H onk( ) '<br />

пооб<strong>е</strong>щали добавить<br />

в эт от инт<strong>е</strong>рф<strong>е</strong>йс вс<strong>е</strong><br />

м<strong>е</strong>тоды и свойства, но<br />

н<strong>е</strong> сд<strong>е</strong>лали этого!<br />

Как только вы добавит<strong>е</strong> вс<strong>е</strong> свойства и м<strong>е</strong>тоды, упомянуты<strong>е</strong> в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong>, сообш;<strong>е</strong>ни<strong>е</strong><br />

об ошибк<strong>е</strong> пропад<strong>е</strong>т. Поэтому добавьт<strong>е</strong> пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> только для чт<strong>е</strong>ния<br />

свойство F u n n y T h in g lH a v e с м<strong>е</strong>тодом чт<strong>е</strong>ния, который вс<strong>е</strong>гда возвраща<strong>е</strong>т строку<br />

больши<strong>е</strong> ботинки. И добавьт<strong>е</strong> м<strong>е</strong>тод H onk ( ) , вызывающий окно с надписью Биби!<br />

Вот, как это выглядит:<br />

p u b l i c s t r i n g F unnyT hinglH ave {<br />

}<br />

g e t { r e t u r n "больши<strong>е</strong> ботинки"; '<br />

p u b lic v o id HonkO {<br />

M essa g eB o x .S h o w ("Би-би!'<br />

}<br />

Т<strong>е</strong>п<strong>е</strong>рь ничто н<strong>е</strong> м<strong>е</strong>ша<strong>е</strong>т компиляции кода! Сд<strong>е</strong>лайт<strong>е</strong><br />

так, чтобы кнопка вызывала м<strong>е</strong>тод Honk () объ<strong>е</strong>кта<br />

T a llG u y .<br />

Инт<strong>е</strong>рф<strong>е</strong>йсу нуж<strong>е</strong>н открытый<br />

м<strong>е</strong>тод Нопк, н<strong>е</strong> возвращающий<br />

знач<strong>е</strong>ния, но при этом сов<strong>е</strong>рш<strong>е</strong>нно<br />

н<strong>е</strong> важно, что буд<strong>е</strong>т д<strong>е</strong>лать<br />

этот м<strong>е</strong>тод. Если м<strong>е</strong>тод присутству<strong>е</strong>т<br />

и сигнатура совпада<strong>е</strong>т,<br />

программа буд<strong>е</strong>т компилироваться.<br />

дальш<strong>е</strong> > 291


инт<strong>е</strong>рф<strong>е</strong>йсы н<strong>е</strong> создают объ<strong>е</strong>кты<br />

Ссылки на инт<strong>е</strong>рф<strong>е</strong>йс<br />

Пр<strong>е</strong>дположим, у вас <strong>е</strong>сть м<strong>е</strong>тод, которому тр<strong>е</strong>бу<strong>е</strong>тся объ<strong>е</strong>кт,<br />

ум<strong>е</strong>ющий выполнять м<strong>е</strong>тод F i n d F l o w e r s (). Под<br />

это услови<strong>е</strong> подходит любой объ<strong>е</strong>кт, р<strong>е</strong>ализующий инт<strong>е</strong>рф<strong>е</strong>йс<br />

I N e c t a r C o l l e c t o r . Это мож<strong>е</strong>т быть объ<strong>е</strong>кт<br />

W o rk er, объ<strong>е</strong>кт R o b o t или объ<strong>е</strong>кт Dog.<br />

Вы мож<strong>е</strong>т<strong>е</strong> сослаться на этот объ<strong>е</strong>кт и быть ув<strong>е</strong>р<strong>е</strong>нными<br />

в наличии нужных вам м<strong>е</strong>тодов.<br />

Можно создать массив<br />

но получить новш оЗъ<strong>е</strong>кты из ин<br />

т<strong>е</strong>рф<strong>е</strong>йса вы н<strong>е</strong><br />

в а Л с т а т о ч н о буд<strong>е</strong>т<br />

новы<strong>е</strong> экз<strong>е</strong>мпляры классов, р<strong>е</strong>ализу ^<br />

шик инт<strong>е</strong>рф<strong>е</strong>йс (Worker. Р<strong>е</strong>зультд<br />

том буд<strong>е</strong>т м а с с и в , кранящии набор<br />

различнык объ<strong>е</strong>ктов! \<br />

Это н<strong>е</strong> работа<strong>е</strong>т...<br />

IStingPatrol dennis = n e w I S t i n g P a t r o l ();<br />

Q I Cannot create an instance of the abstract class or interface |<br />

Помнит<strong>е</strong>, вы могли<br />

п<strong>е</strong>р<strong>е</strong>дать ссылку<br />

BLT любому классу,<br />

который долж<strong>е</strong>н<br />

ссылаться на<br />

сэндвичи, так как<br />

класс 8LT явля<strong>е</strong>т ­<br />

ся производным от<br />

класса Sandwich?<br />

То ж<strong>е</strong> само<strong>е</strong> происходит<br />

и в данном<br />

случа<strong>е</strong>, вы мож<strong>е</strong>т<strong>е</strong><br />

использовать объ<strong>е</strong>кт<br />

NectarStinger<br />

_____<br />

Для инт<strong>е</strong>рф<strong>е</strong>йсов ключ<strong>е</strong>во<strong>е</strong> слово n ew н<strong>е</strong> работа<strong>е</strong>т, и это им<strong>е</strong><strong>е</strong>т смысл, в<strong>е</strong>дь<br />

м<strong>е</strong>тоды и свойства н<strong>е</strong> им<strong>е</strong>ют р<strong>е</strong>ализации. Объ<strong>е</strong>ктам просто н<strong>е</strong>откуда было бы<br />

узнать, как с<strong>е</strong>бя в<strong>е</strong>сти.<br />

...зато работа<strong>е</strong>т это:<br />

N e c t a r S t i n g e r fred = n e w N e c t a r S t i n g e r ()<br />

/ ^ I S t i n g P a t r o l g e o r g e = fred; объ<strong>е</strong>кт мож<strong>е</strong>1^<br />

J, „ ^ ^ выполнят^ много<br />

В п<strong>е</strong>рвой строчк<strong>е</strong> при помощи оп<strong>е</strong>ратора n ew созда<strong>е</strong>тся ссылка сЬункции, но исс<br />

им<strong>е</strong>н<strong>е</strong>м Fred, указывающая на объ<strong>е</strong>кт N e c t a r S t i n g e r .<br />

А олмуя инт <strong>е</strong>рсЬ<strong>е</strong>йснукз<br />

ссылку^<br />

Со второй строчкой вс<strong>е</strong> намного инт<strong>е</strong>р<strong>е</strong>сн<strong>е</strong><strong>е</strong>, так как зд<strong>е</strong>сь при h получа<strong>е</strong>т<strong>е</strong><br />

п ом ощ и и н т <strong>е</strong> р ф <strong>е</strong> й с а I S t i n g P a t r o l со зд а<strong>е</strong>т ся новая ссы л оч ­ доступ только<br />

ная п <strong>е</strong>р <strong>е</strong>м <strong>е</strong>н н ая. На п<strong>е</strong>рвый взгляд код выглядит н<strong>е</strong>сколько к м<strong>е</strong>т одам, упомянуп^^>^^<br />

в<br />

странно. Но взглянит<strong>е</strong>:<br />

т<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong>.<br />

N e c t a r S t i n g e r g i n g e r = f r e d ;<br />

Тр<strong>е</strong>тий оп<strong>е</strong>ратор созда<strong>е</strong>т новую ссылку на объ<strong>е</strong>кт N e c t a r S t i n g e r .<br />

Имя этой ссылки g i n g e r , и она указыва<strong>е</strong>т на тот ж<strong>е</strong> самый объ<strong>е</strong>кт,<br />

что и ссылка f r e d . Оп<strong>е</strong>ратор g e o r g e использу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс<br />

в любом м<strong>е</strong>тод<strong>е</strong> или i s t i n g P a t r o l аналогичным способом.<br />

оп<strong>е</strong>ратор<strong>е</strong>, ожидаюш,<strong>е</strong>м<br />

istingPatrol.<br />

Что ж<strong>е</strong> случилось?<br />

Тут только один оп<strong>е</strong>ратор new , так что появля<strong>е</strong>тся только од и н<br />

н о в ы й объ <strong>е</strong>к т. Второй оп<strong>е</strong>ратор созда<strong>е</strong>т ссылочную п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

g e o r g e , которая мож<strong>е</strong>т указывать на экз<strong>е</strong>мпляр л ю б о го<br />

класса, р <strong>е</strong>ал и зую щ и й и н т <strong>е</strong> р ф <strong>е</strong> й с i s t i n g P a t r o l .<br />

292 глава 7


Ссылка на инт<strong>е</strong>рф<strong>е</strong>йс аналогична ссылк<strong>е</strong> на объ<strong>е</strong>кт<br />

инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, как выглядят объ<strong>е</strong>кты в куч<strong>е</strong>. Инт<strong>е</strong>рф<strong>е</strong>йсная<br />

ссылка явля<strong>е</strong>тся вс<strong>е</strong>го лишь <strong>е</strong>щ<strong>е</strong> одним способом обратиться<br />

к уж<strong>е</strong> знакомым объ<strong>е</strong>ктам. Это оч<strong>е</strong>нь просто!<br />

О Создадим пару пч<strong>е</strong>л<br />

Вы уж<strong>е</strong> н<strong>е</strong> раз это д<strong>е</strong>лали.<br />

О<br />

о<br />

S t i n g P a t r o l b i f f = new S t i n g P a t r o l О ;<br />

т<br />

Пусть класс StingPatrol р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс<br />

IStingPatrolj а класс NectarCollector — инт<strong>е</strong>рф<strong>е</strong>йс<br />

INectarCollector.<br />

N e c t a r C o l l e c t o r b e r t h a = new N e c t a r C o l l e c t o r ( );<br />

Добавьт<strong>е</strong> ссы лки на is tin g P a tro l и IN e c ta rC o lle c to r<br />

Инт<strong>е</strong>рф<strong>е</strong>йсны<strong>е</strong> ссылки нич<strong>е</strong>м н<strong>е</strong> отличаются от ссылок<br />

любого другого типа.<br />

i s t i n g P a t r o l d e f e n d e r = b i f f ;<br />

I N e c t a r C o lle c t o r c u t i e P i e = b e r th a ;<br />

Эти два оп<strong>е</strong>ратора используют инт<strong>е</strong>рф<strong>е</strong>(лсы для<br />

создания новых ссылок на<br />

Инт<strong>е</strong>рф<strong>е</strong>йсны<strong>е</strong> ссылки м огут указывать >^олько<br />

н а экз<strong>е</strong>мпляр./ классов, р<strong>е</strong>ализую щ их инт<strong>е</strong>рф<strong>е</strong>йс.<br />

MHTepqiencHafl ссы лка позволя<strong>е</strong>т сохранить объ<strong>е</strong>кт<br />

Объ<strong>е</strong>кт исч<strong>е</strong>за<strong>е</strong>т, как только на н<strong>е</strong>го н<strong>е</strong> оста<strong>е</strong>тся ссылок.<br />

Но никто н<strong>е</strong> говорит, что вс<strong>е</strong> ссылки должны принадл<strong>е</strong>жать<br />

одному типу! Инт<strong>е</strong>рф<strong>е</strong>йсны<strong>е</strong> ссылки позволяют<br />

спасти объ<strong>е</strong>кт от удал<strong>е</strong>ния.<br />

b i f f = n u l l ;<br />

Этот объ<strong>е</strong>кт н<strong>е</strong><br />

исч<strong>е</strong>за<strong>е</strong>т из-за<br />

ссылки defender.<br />

Назначьт<strong>е</strong> инт<strong>е</strong>рд><strong>е</strong>йсной ссы лк<strong>е</strong> новый экз<strong>е</strong>мпляр<br />

На самом д<strong>е</strong>л<strong>е</strong> вам н<strong>е</strong> нужны ссылки на объ<strong>е</strong>кты, можно<br />

создать новый объ<strong>е</strong>кт и сопоставить <strong>е</strong>го с ссылочной инт<strong>е</strong>рф<strong>е</strong>йсной<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной.<br />

I N e c t a r C o lle c t o r g a t h e r e r = new N e c t a r S t i n g e r ( );<br />

дальш<strong>е</strong> > 293


мы ожида<strong>е</strong>м большо<strong>е</strong> насл<strong>е</strong>дство<br />

Оп<strong>е</strong>ратор is<br />

Иногда тр<strong>е</strong>бу<strong>е</strong>тся понять, р<strong>е</strong>ализу<strong>е</strong>тся ли инт<strong>е</strong>рф<strong>е</strong>йс опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным<br />

классом. Пр<strong>е</strong>дположим, что вс<strong>е</strong> рабочи<strong>е</strong> пч<strong>е</strong>лы пр<strong>е</strong>дставл<strong>е</strong>ны в вид<strong>е</strong><br />

массива Bees. В массив<strong>е</strong> можно хранить п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> типа W orker, так<br />

как вс<strong>е</strong> рабочи<strong>е</strong> пч<strong>е</strong>лы принадл<strong>е</strong>жат классу W orker или производным<br />

от н<strong>е</strong>го классам.<br />

Но какая из рабочих пч<strong>е</strong>л мож<strong>е</strong>т собирать н<strong>е</strong>ктар? Для отв<strong>е</strong>та на этот вопрос<br />

нужно узнать, р<strong>е</strong>ализу<strong>е</strong>т ли класс инт<strong>е</strong>рф<strong>е</strong>йс IN e c ta r C o lle c to r .<br />

Это можно сд<strong>е</strong>лать при помощи оп<strong>е</strong>ратора is .<br />

Рабочи<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ны в вид<strong>е</strong><br />

массива Workers. Оп<strong>е</strong>ратор<br />

IS позволя<strong>е</strong>т опр<strong>е</strong>д<strong>е</strong>лить<br />

тип пч<strong>е</strong>лы.<br />

Worker [] bees = new Worker [3];<br />

bees[0] = new NectarCollector0;<br />

bees[1] = new StingPatrol0;<br />

bees [2] = new NectarStinger0;<br />

for (int i = 0; i < bees.Length;<br />

{<br />

^<br />

Массиб рабочих пч<strong>е</strong>л<br />

IS опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

н а л и ч и <strong>е</strong> м<strong>е</strong>тодой<br />

Тсвойств, нужных<br />

для выполн<strong>е</strong>ния<br />

у к а з а н н о й работы.<br />

i++)<br />

,5 срабнибл<strong>е</strong>ил UH-<br />

1^<strong>е</strong>рф<strong>е</strong>йсы и дру<br />

if (bees [i] /^i^INectarCollector)2Me типы данных.<br />

{ Эта запись означа<strong>е</strong>т, что <strong>е</strong>сли<br />

bees [i].DoThisJob("Nectar Collector", 3)<br />

f<br />

Т<strong>е</strong>п<strong>е</strong>рь,<br />

ч т о эта<br />

г г ; Г и - ^<br />

Ш Т У Р М<br />

Класс, н<strong>е</strong> производный от класса worker, но р<strong>е</strong>ализующий инт<strong>е</strong>рф<strong>е</strong>йс<br />

INectarCollector, мож<strong>е</strong>т ВЫПОЛНЯТЬ работу по сборк<strong>е</strong><br />

н<strong>е</strong>ктара! Но так как класс Worker н<strong>е</strong> явля<strong>е</strong>тся для н<strong>е</strong>го базовым, вы<br />

н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> пом<strong>е</strong>стить <strong>е</strong>го в массив с другими пч<strong>е</strong>лами. Подумайт<strong>е</strong>,<br />

каким образом можно получить массив из пч<strong>е</strong>л обоих видов?<br />

_ Часто<br />

- ^ а Д а Б а <strong>е</strong> М ы <strong>е</strong> ------<br />

Боц|эос;ь1<br />

Свойства, добавля<strong>е</strong>мы<strong>е</strong> в<br />

инт<strong>е</strong>рф<strong>е</strong>йс, выглядят как автоматич<strong>е</strong>ски<br />

р<strong>е</strong>ализу<strong>е</strong>мы<strong>е</strong>. Н<strong>е</strong>уж<strong>е</strong>ли<br />

при р<strong>е</strong>ализации инт<strong>е</strong>рф<strong>е</strong>йса<br />

я могу использовать только<br />

таки<strong>е</strong> свойства?<br />

О! Вовс<strong>е</strong> н<strong>е</strong>т. Свойства внутри<br />

инт<strong>е</strong>рф<strong>е</strong>йсов д<strong>е</strong>йствит<strong>е</strong>льно напоминают<br />

своим видом автоматич<strong>е</strong>ски<br />

р<strong>е</strong>ализу<strong>е</strong>мы<strong>е</strong> — посмотрит<strong>е</strong><br />

на свойства Job и ShiftsLeft<br />

в iworker на сл<strong>е</strong>дующ<strong>е</strong>й страниц<strong>е</strong>.<br />

Р<strong>е</strong>ализовать свойство Job<br />

можно так:<br />

public Job { get;<br />

private set; }<br />

Модификатор private set<br />

ставится, так как автоматич<strong>е</strong>ски<strong>е</strong><br />

свойства тр<strong>е</strong>буют наличия как м<strong>е</strong>тода<br />

чт<strong>е</strong>ния, так и м<strong>е</strong>тода записи<br />

(пусть даж<strong>е</strong> и закрытого). Но вы<br />

мож<strong>е</strong>т<strong>е</strong> написать и другой код:<br />

public job { get {<br />

return "Бухгалт<strong>е</strong>р"; } }<br />

И программа вс<strong>е</strong> равно буд<strong>е</strong>т<br />

компилироваться. По ж<strong>е</strong>ланию<br />

можно добавить и м<strong>е</strong>тод записи.<br />

(При р<strong>е</strong>ализации ж<strong>е</strong> ч<strong>е</strong>р<strong>е</strong>з автоматич<strong>е</strong>ско<strong>е</strong><br />

свойство вы вс<strong>е</strong>го лишь<br />

р<strong>е</strong>ша<strong>е</strong>т<strong>е</strong>, буд<strong>е</strong>т ли м<strong>е</strong>тод записи<br />

открытым или закрытым.)<br />

294 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

инт<strong>е</strong>рф<strong>е</strong>йсы U насл<strong>е</strong>довани<strong>е</strong><br />

Когда один класс насл<strong>е</strong>ду<strong>е</strong>т от другого, он получа<strong>е</strong>т вс<strong>е</strong> <strong>е</strong>го м<strong>е</strong>тоды<br />

и свойства. Насл<strong>е</strong>довани<strong>е</strong> инт<strong>е</strong>рф <strong>е</strong>йсов происходит <strong>е</strong>щ<strong>е</strong><br />

прощ<strong>е</strong>. Так как в инт<strong>е</strong>рф<strong>е</strong>йсах отсутствуют т<strong>е</strong>ла м<strong>е</strong>тодов, вам<br />

уж<strong>е</strong> н<strong>е</strong> прид<strong>е</strong>тся заботиться о вызов<strong>е</strong> конструкторов и м<strong>е</strong>тодов<br />

базового класса. Насл<strong>е</strong>дующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсы просто накапливают<br />

в с<strong>е</strong>б<strong>е</strong> м<strong>е</strong>тоды и свойства своих родит<strong>е</strong>л<strong>е</strong>й.<br />

i n t e r f a c e IW o r k e r<br />

{<br />

s t r i n g J o b { g e t ; }<br />

i n t S h i f t s L e f t { g e t ;<br />

v o i d D o T h i s J o b ( s t r i n g<br />

}<br />

j o b , i n t s h i f t s )<br />

Om созданного ^<br />

НЛММ инт<strong>е</strong>рф<strong>е</strong>й<br />

ca M orker м о­<br />

г у т насл<strong>е</strong>довать<br />

вс<strong>е</strong> остальны<strong>е</strong><br />

инт<strong>е</strong>рф<strong>е</strong>йсы.<br />

Н а д и а г р а м м <strong>е</strong> к л а с с о в<br />

н а с л <strong>е</strong> д о в а н и <strong>е</strong> и н т <strong>е</strong> р ­<br />

ф <strong>е</strong> й с о в о б о з н а ч а <strong>е</strong> т с я<br />

п у н к т и р н о й л и н и <strong>е</strong> й .<br />

i<br />

(interface)<br />

IW orker<br />

Job<br />

ShiftsLeft<br />

DoThisJobO<br />

Worl


скр<strong>е</strong>стить бульдога с носорогом<br />

RoboBee 4 0 0 0 функциониру<strong>е</strong>т б<strong>е</strong>з м<strong>е</strong>да<br />

Создадим пч<strong>е</strong>лу новой формации, КоЬоВ<strong>е</strong><strong>е</strong> 4000, работающую<br />

на топлив<strong>е</strong>. «Привив» <strong>е</strong><strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсу инт<strong>е</strong>рф<strong>е</strong>йс<br />

11^огк<strong>е</strong>г, вы да<strong>е</strong>т<strong>е</strong> <strong>е</strong>й возможность д<strong>е</strong>лать вс<strong>е</strong> то, что д<strong>е</strong>ла<strong>е</strong>т<br />

обычная пч<strong>е</strong>ла.<br />

RoboBee<br />

ShiftsToWork<br />

ShiftsWorked<br />

ShiftsLeft<br />

Job<br />

DoThisJobO<br />

class Robot<br />

{<br />

public void ConsumeGasO<br />

}<br />

Г Г Г г Х Г к о М .<br />

Класс RoboBee насл<strong>е</strong>ди<strong>е</strong>т от<br />

/г’<strong>е</strong>йлизу<strong>е</strong>т<br />

ант<strong>е</strong>^ф <strong>е</strong>ас (Worker. В итог<strong>е</strong><br />

м о ж <strong>е</strong> т выполнять ра6о~<br />

- обычной пч<strong>е</strong>лы. ^<br />

class RoboBee Robot, IWorker f r .<br />

{<br />

Класс RoboBee<br />

private int shiftsToWork;<br />

р<strong>е</strong>ализу<strong>е</strong>т<br />

private int shiftsWorked;<br />

вс<strong>е</strong> м<strong>е</strong>тоды<br />

инт<strong>е</strong>рф<strong>е</strong>йса<br />

public int ShiftsLeft<br />

iWorker-<br />

{get {return shiftsToWork - shiftsWorked;}}<br />

public string Job { get; private set; }<br />

public bool DoThisJob(string job, int shiftsToWork){...}<br />

public void WorkOneShiftO {...}<br />

}<br />

Остальны<strong>е</strong> классы наш<strong>е</strong>го прилож<strong>е</strong>ния н<strong>е</strong> «увидят» функциональной<br />

разницы м<strong>е</strong>жду пч<strong>е</strong>лой-роботом и обычной<br />

пч<strong>е</strong>лой. Оба эти класса р<strong>е</strong>ализуют инт<strong>е</strong>рф<strong>е</strong>йс ХКогк<strong>е</strong>г, с<br />

точки зр<strong>е</strong>ния программы д<strong>е</strong>йствуют, как рабочи<strong>е</strong> пч<strong>е</strong>лы.<br />

Отличить объ<strong>е</strong>кты друг от друга позволит оп<strong>е</strong>ратор<br />

if (workerBee is Robot) {<br />

}<br />

// мы узнали, что workerBee<br />

// это объ<strong>е</strong>кт Robot<br />

Оп<strong>е</strong>ратор 15 показы<br />

ва<strong>е</strong>т, какой класс или<br />

инт<strong>е</strong>рф<strong>е</strong>йс р<strong>е</strong>ализу<strong>е</strong>т<br />

^огк<strong>е</strong>гВ<strong>е</strong><strong>е</strong> и каково <strong>е</strong>го<br />

полож<strong>е</strong>ни<strong>е</strong> в и<strong>е</strong>рархии<br />

насл<strong>е</strong>дования.<br />

Любой класс мож<strong>е</strong>т<br />

р<strong>е</strong>ализовывать ЛЮБОЙ<br />

инт<strong>е</strong>рф<strong>е</strong>йс, <strong>е</strong>сли он<br />

р<strong>е</strong>ализу<strong>е</strong>т вс<strong>е</strong> м<strong>е</strong>тоды<br />

и свойства этого инт<strong>е</strong>рф<strong>е</strong>йса.<br />

296 глава 7


1$ показыва<strong>е</strong>т Вам, что им<strong>е</strong>нно объ<strong>е</strong>кт р<strong>е</strong>ализу<strong>е</strong>т<br />

а$ показыва<strong>е</strong>т компилятору, как обработать этот объ<strong>е</strong>кт<br />

Иногда тр<strong>е</strong>бу<strong>е</strong>тся вызвать м<strong>е</strong>тод, получ<strong>е</strong>нный объ<strong>е</strong>ктом в проц<strong>е</strong>сс<strong>е</strong> р<strong>е</strong>ализации<br />

инт<strong>е</strong>рф<strong>е</strong>йса. Но что д<strong>е</strong>лать, <strong>е</strong>сли вы н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, нужному ли типу принадл<strong>е</strong>жит<br />

объ<strong>е</strong>кт? На помощь вам прид<strong>е</strong>т оп<strong>е</strong>ратор 1б. А оп<strong>е</strong>ратор аз позволит пр<strong>е</strong>образовать<br />

один совм<strong>е</strong>стимый ссылочный тип в другой.<br />

инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

IWorker[] bees = new IWorker[3];<br />

beesEO] = new NectarStinger{)<br />

bees [1] = new RoboBeeO;<br />

bees [2] = new Worker 0;<br />

Mw п<strong>е</strong>р<strong>е</strong>бира<strong>е</strong>м пч<strong>е</strong>л.--<br />

for (int i = 0; i < bees.Length; i++) {<br />

C ^ i f<br />

- .Mпров<strong>е</strong>ря<strong>е</strong>м,<br />

р<strong>е</strong>ализу<strong>е</strong>т<br />

ли пч<strong>е</strong>ла<br />

инт<strong>е</strong>рф<strong>е</strong>йс<br />

INectarCollector.<br />

Возьми в руку карандаш<br />

(bees[i] is INectarCollector)<br />

INectarCollector thisCollector;<br />

thisCollector = bees [i]<br />

thisCollector.GatherNectarо ;<br />

f<br />

* * ' Т<strong>е</strong>п<strong>е</strong>рь можно вызывать м<strong>е</strong>тоды<br />

инт<strong>е</strong>рф<strong>е</strong>йса INectarCollector.<br />

{<br />

Cor.<br />

Мы н<strong>е</strong> мож<strong>е</strong>м вызывать<br />

для пч<strong>е</strong>л м <strong>е</strong>­<br />

тоды инт<strong>е</strong>рф<strong>е</strong>йса<br />

INectarCollector- В<strong>е</strong>дь<br />

пч<strong>е</strong>лы принадл<strong>е</strong>жат<br />

типу M arker и нич<strong>е</strong>го<br />

н<strong>е</strong> знают о м<strong>е</strong>тодах<br />

INectarCollector.<br />

INectarCollector;<br />

Для каждого из показанных справа оп<strong>е</strong>раторов напишит<strong>е</strong>, при каком знач<strong>е</strong>нии сч<strong>е</strong>тчика<br />

пч<strong>е</strong>л i он буд<strong>е</strong>т им<strong>е</strong>ть знач<strong>е</strong>ни<strong>е</strong> tr u e . Зач<strong>е</strong>ркнит<strong>е</strong> сл<strong>е</strong>ва дв<strong>е</strong> строчки, которы<strong>е</strong><br />

н<strong>е</strong> компилируются.<br />

Г-, „ -гг. 1 Г01<br />

i w o r k e r [] B e es = new i w o r k e r [8 ];<br />

1. ( B e e s [ i ] i s I N e c t a r C o l l e c t o r )<br />

B e es [0] = new N e c t a r S t i n g e r 0 ;<br />

B e e s [ l] = new R o b o B eeO ; ................................................................................................<br />

B e e s [2] = new W orker 0 ;<br />

B e e s [3 ] = B e e s [0 ]<br />

B e e s [4] = i s t i n g P a t r o l ;<br />

B e es [5] = n u l l ;<br />

B e es [6] = B e es [0] ;<br />

a s IW orker;<br />

B e es [7] = new I N e c t a r C o l l e c t o r {) ;<br />

2 . (Bees[i] is istingPatrol)<br />

3. ( B e e s [ i ] i s IW o r k e r )<br />

дальш<strong>е</strong> > 297


н<strong>е</strong> в<strong>е</strong>рь глазам своим<br />

Коф<strong>е</strong>барка отн о си тся к Приборам<br />

Для задачи экономии эл<strong>е</strong>ктроэн<strong>е</strong>ргии функции отд<strong>е</strong>льных приборов<br />

н<strong>е</strong> им<strong>е</strong>ют знач<strong>е</strong>ния. Вас заботит только то, что вс<strong>е</strong> они потр<strong>е</strong>бляют<br />

эл<strong>е</strong>ктрич<strong>е</strong>ство. Поэтому при написании программы уч<strong>е</strong>та эл<strong>е</strong>ктроэн<strong>е</strong>ргии<br />

можно ограничиться классом A p p lia n c e (Прибор). Но чтобы<br />

отличить коф<strong>е</strong>варку от духовки, потр<strong>е</strong>бу<strong>е</strong>тся и<strong>е</strong>рархия классов.<br />

М<strong>е</strong>тоды и свойства, описывающи<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> коф<strong>е</strong>варки и духовки,<br />

будут пом<strong>е</strong>щ<strong>е</strong>ны в классы Cof feeM aker и Oven. Эти классы будут производными<br />

от класса A p p lia n c e , сод<strong>е</strong>ржащ<strong>е</strong>го общи<strong>е</strong> для них м<strong>е</strong>тоды<br />

и свойства.<br />

p u b l i c v o i d M o n ito rP o w e r(A p p lia n c e a p p l i a n c e ) {<br />

}<br />

/ / к о д д о б а в л <strong>е</strong> н и я данны х в домашнюю<br />

/ / б а з у п о т р <strong>е</strong> б л <strong>е</strong> н и я э н <strong>е</strong> р г и и 33 ^ ^ ^ долж<strong>е</strong>н<br />

Э т о т код отсл<strong>е</strong>жива<strong>е</strong>т,<br />

^^^^л<strong>е</strong>жиТающий<br />

сколько эл<strong>е</strong>ктроэн<strong>е</strong>ргии<br />

потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong><br />

тр<strong>е</strong>дц<strong>е</strong>тся для работы \ эл<strong>е</strong>ктроэн<strong>е</strong>ргии<br />

коф<strong>е</strong>варки. \ g<br />

C offeeM aker<br />

CoffeeLett<br />

FlllWithWaterO<br />

MakeCoffeeO<br />

A ppliance<br />

Pluggedin<br />

Color<br />

ConsumePowerO<br />

Oven<br />

Capacity<br />

PreheatO<br />

HeatUpO<br />

ReheatO<br />

C o ffe e M a k e r m i s t e r C o f f e e = new C o f f e e M a k e r ( ) ;<br />

M o n ito r P o w e r ( m is te r C o f f <strong>е</strong> <strong>е</strong> ) ;<br />

Возьми в руку карандаш<br />

*0Ш0НИ6<br />

IW orker[] B ees = new IW o rk er[8 ];<br />

B e es [5] = n u l l ;<br />

B e e s [6] = B e e s [0] ;<br />

-RoQia.r-Tl - 1 )<br />

V<br />

М<strong>е</strong>тод MonitorPowerQ тр<strong>е</strong>би<strong>е</strong>т<br />

ссылки на обь<strong>е</strong>кт Appliance<br />

но <strong>е</strong>му можно п<strong>е</strong>р<strong>е</strong>дать ссыл- '<br />

ку misterCofFee, так как класс<br />

Согг<strong>е</strong><strong>е</strong>Мак<strong>е</strong>г явля<strong>е</strong>тся производным<br />

от класса Appliance.<br />

Тако<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> вы<br />

уж<strong>е</strong> наблюдали в<br />

пр<strong>е</strong>дыдуш,<strong>е</strong>й глав<strong>е</strong>,<br />

когда п<strong>е</strong>р<strong>е</strong>давали<br />

м<strong>е</strong>тоду, ожидающ<strong>е</strong>му<br />

ссылки на<br />

Sandwich, ссылки<br />

на BLT.<br />

каких знач<strong>е</strong>ниях сч<strong>е</strong>тчика пч<strong>е</strong>л i оп<strong>е</strong>раторы справа возвращ<br />

аю т знач<strong>е</strong>ни<strong>е</strong> tr u e . Сл<strong>е</strong>ва зач<strong>е</strong>ркнуты дв<strong>е</strong> строчки, пр<strong>е</strong>пятствующи<strong>е</strong><br />

компиляции.<br />

1. (Bees [i] i s IN e c ta r C o lle c to r )<br />

B e e s [0 ] = new N e c t a r S t in g e r 0 ; J<br />

B e e s [ l] = new R o b o B eeO ; М<strong>е</strong>тод<br />

о и &<br />

B e e s [2 ] = new W ork erO ; NectarStinger()<br />

р<strong>е</strong>ализу<strong>е</strong>т 2. (B e e s[i] i s i s t i n g P a t r o l )<br />

B e e s [3 ] = B e e s [0 ] a s IW orker; инт<strong>е</strong>рф<strong>е</strong>йс<br />

«iBiBoaili'iil-] — lO tei.n gP a faiwl-;'»“ istingPatrol.'^— q ^<br />

3. (B e e s[i] i s IW orker)<br />

298 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

Когда вы использу<strong>е</strong>т<strong>е</strong> производный класс вм<strong>е</strong>сто базового, наприм<strong>е</strong>р, ссылаясь на коф<strong>е</strong>варку вм<strong>е</strong>сто<br />

прибора, - это называ<strong>е</strong>тся в о с х о д я щ и м п р и в <strong>е</strong> д <strong>е</strong> н и <strong>е</strong> м (u p c a s tin g ). Это оч<strong>е</strong>нь мощный инструм<strong>е</strong>нт,<br />

который вы получа<strong>е</strong>т<strong>е</strong>, построив и<strong>е</strong>рархию классов. К сожал<strong>е</strong>нию, он работа<strong>е</strong>т только с м<strong>е</strong>тодами и<br />

свойствами базового класса. Другими словами, рассматривая коф<strong>е</strong>варку как прибор, вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong><br />

заставить <strong>е</strong><strong>е</strong> сварить коф<strong>е</strong> MakeCoffee() или налить воду FillWithWater(). Зато вы жож<strong>е</strong>ш<strong>е</strong> опр<strong>е</strong>д<strong>е</strong>лить,<br />

включ<strong>е</strong>на ли она в роз<strong>е</strong>тку, так как это состояни<strong>е</strong> относится ко вс<strong>е</strong>м приборам (и им<strong>е</strong>нно поэтому свойство<br />

P l u g g e d i n пом<strong>е</strong>щ<strong>е</strong>но в класс A p p l i a n c e ) .<br />

Q Создадим объ<strong>е</strong>кты<br />

Классы C o f f e e M a k e r и O v en создаются обычным способом:<br />

C offeeM aker m i s t e r C o f f e e = new C o ffe e M a k e r О ; ? Д л я начала получиМ<br />

Oven o ld T o a s ty = new Oven {) ;<br />

Т экз<strong>е</strong>мпляры оо-ь<strong>е</strong>ктоо<br />

__J O ven и C offeeM aker.<br />

@ A вдруг ном потр<strong>е</strong>бу<strong>е</strong>тся массив приборов?<br />

Объ<strong>е</strong>кт C o f f e e M a k e r н<strong>е</strong>льзя пом<strong>е</strong>стить в массив O v e n [ ] , а объ<strong>е</strong>кту O v en н<strong>е</strong> м<strong>е</strong>сто<br />

в массив<strong>е</strong> C o f f e e M a k e r [ ]. Но они пр<strong>е</strong>красно уживутся в массив<strong>е</strong> A p p l i a n c e [ ]:<br />

A p p l i a n c e [] k itc h e n w a r e = new A p p l i a n c e [2 ];<br />

k itc h e n w a r e [0] = m is t e r C o f f e e ; МаССив,<br />

ухОЗООЛЯСг^ '^75/?1лл.СЯ<br />

k itc h e n w a r e [1] = o ld T o a s ty ; ^ Зля Эихобки,<br />

м<strong>е</strong>сто как ол^^р<br />

^ а к U Эля коф<strong>е</strong>б<strong>е</strong>^рки,<br />

О Н <strong>е</strong> лю бой прибор явля<strong>е</strong>тся духовкой<br />

Ссылаясь на объ<strong>е</strong>кт A p p l i a n c e , вы получа<strong>е</strong>т<strong>е</strong> доступ т о л ь к о к м<strong>е</strong>тодам и свойствам<br />

приборов. Вы н <strong>е</strong> м о ж <strong>е</strong> т <strong>е</strong> при этом воспользоваться м<strong>е</strong>тодами и свойствами<br />

объ<strong>е</strong>кта C o f f e e M a k e r даж<strong>е</strong> <strong>е</strong>сли вы зна<strong>е</strong>т<strong>е</strong>, что р<strong>е</strong>чь и в самом д<strong>е</strong>л<strong>е</strong> ид<strong>е</strong>т о коф<strong>е</strong>powerConsumer<br />

-<br />

варк<strong>е</strong>. Поэтому корр<strong>е</strong>ктны сл<strong>е</strong>дующи<strong>е</strong> оп<strong>е</strong>раторы:<br />

ссылка<br />

A p p lia n c e powerConsum er = new C o ffe e M a k e r О ;<br />

класса Appliance<br />

на ооь<strong>е</strong>кт<br />

pow erC onsum er.C onsum eP ow erО ; ^^'^рочка н<strong>е</strong> буд<strong>е</strong>т КОМ- (CoffeeMaker.<br />

Но написав вот такую строчку:<br />

пилироваться, т ак как<br />

^ м <strong>е</strong>т од pow erC onsu m er ра -<br />

pow erC on su m er.M ak ecoffee О; ------------- сТвТ2 Т з Т <strong>е</strong> Т т а Х р Х п с <strong>е</strong> .<br />

вы получит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>:<br />

'A p p lia n c e ' d o e s n o t c o n t a i n a 1 '’ЧЩ РГ'<br />

^ d e f i n i t i o n f o r 'M ak eC offee' I ^ ^ <strong>е</strong> М б У '<br />

так как посл<strong>е</strong> восходящ<strong>е</strong>го прив<strong>е</strong>д<strong>е</strong>ния можно пользоваться только м<strong>е</strong>тодами<br />

и свойствами одного уровня с ссылкой, которую вы использу<strong>е</strong>т<strong>е</strong> для доступа<br />

к объ<strong>е</strong>кту.<br />

дальш<strong>е</strong> > 299


вв<strong>е</strong>рх л<strong>е</strong>гко, а вот вниз — рискованно<br />

Нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

Т<strong>е</strong>п<strong>е</strong>рь вы зна<strong>е</strong>т<strong>е</strong>, что рассматривая коф<strong>е</strong>варку и духовку как приборы, вы лиша<strong>е</strong>т<strong>е</strong>сь<br />

доступа к их собств<strong>е</strong>нным м<strong>е</strong>тодам и свойствам. К счастью, суш;<strong>е</strong>ству<strong>е</strong>т проц<strong>е</strong>дура<br />

н и с х о д я щ <strong>е</strong> г о п р и в <strong>е</strong> д <strong>е</strong> н и я (d o w n c a s tin g ). Узнать, относится ли рассматрива<strong>е</strong>мый<br />

объ<strong>е</strong>кт A p p lian c e к классу C offeeM aker, можно при помощи оп<strong>е</strong>ратора i s .<br />

Т<strong>е</strong>п<strong>е</strong>рь ничто н<strong>е</strong> м<strong>е</strong>ша<strong>е</strong>т вам в<strong>е</strong>рнуться от класса A p p lia n c e к классу C offeeM aker<br />

при помощи оп<strong>е</strong>ратора a s .<br />

О Н ачн<strong>е</strong>м с объ<strong>е</strong>кта C o ffe e M a k e r<br />

Вот код, который мы использовали для восходящ<strong>е</strong>го прив<strong>е</strong>д<strong>е</strong>ния:<br />

В о т ссылка<br />

АррИапс<strong>е</strong>,<br />

указывающая<br />

на обь<strong>е</strong>кт<br />

CoffeeMaker<br />

A p p lia n c e powerConsum er = new C o ffe e M a k e r ( );<br />

pow erC onsum er.C onsum eP ow er0 ;<br />

О H o как пр<strong>е</strong>вратить Appliance обратно в класс C o ffe e M a k e r?<br />

Для начала воспользуйт<strong>е</strong>сь оп<strong>е</strong>ратором i s для пров<strong>е</strong>рки совм<strong>е</strong>стимости.<br />

i f<br />

(powerConsum er i s C offeeM aker)<br />

//мы мож<strong>е</strong>м осущ<strong>е</strong>ствить нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>!<br />

Ссылка javaJoe ука -<br />

зыва<strong>е</strong>т на тот ж<strong>е</strong><br />

обь<strong>е</strong>кт, что и ссыл-<br />

О Т<strong>е</strong>п<strong>е</strong>рь когда вы точно зна<strong>е</strong>т<strong>е</strong>, что ваш прибор , — коя><strong>е</strong>варка... __ I___ I_____ ка powerConsumer.<br />

... вы мож<strong>е</strong>т<strong>е</strong> воспользоваться оп<strong>е</strong>ратором a s для нисходящ<strong>е</strong>го прив<strong>е</strong>д<strong>е</strong>ния, ‘^'^косится<br />

чтобы снова получить доступ к м<strong>е</strong>тодам и свойствам класса CoffeeM aker. ^<br />

Так как класс CoffeeM aker насл<strong>е</strong>ду<strong>е</strong>т от класса A p p lian ce, доступ к м<strong>е</strong>то- вызвать<br />

дам и свойствам базового класса у н<strong>е</strong>го тож<strong>е</strong> сохранится.<br />

MakeCoffeeQ.<br />

i f (powerConsum er i s C offeeM aker) {<br />

}<br />

C offeeM ak er ja v a J o e = powerConsum er a s C o ffeeM a k er;<br />

j a v a J o e . M akeC off<strong>е</strong> <strong>е</strong> ( );<br />

Н<strong>е</strong>удачно<strong>е</strong> нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> бозбраща<strong>е</strong>ш null<br />

А что произойд<strong>е</strong>т, <strong>е</strong>сли при помощи оп<strong>е</strong>ратора a s попытаться пр<strong>е</strong>образовать<br />

объ<strong>е</strong>кт Oven в объ<strong>е</strong>кт C offeeM aker? Вы получит<strong>е</strong> нул<strong>е</strong>вой р<strong>е</strong>зультат, и програм<br />

м а п р <strong>е</strong>к р а т и т работу,<br />

i f (powerConsum er i s C o ffeeM a k er) { Z' относится к классу Oven. По-<br />

/ этому при попытк<strong>е</strong> осущ<strong>е</strong>ствить<br />

нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>­<br />

Oven foodW armer = powerConsum er as Oven;<br />

«<strong>е</strong>тмш mil<br />

ни<strong>е</strong> ссылка foodVJarmer даст<br />

foodW arm er. P r e h e a t ( );<br />

null. Вот что произойд<strong>е</strong>т при<br />

попытк<strong>е</strong> использовать п у ­<br />

}<br />

стую ссылку... ч<br />

т<br />

300 глава 7<br />

Nul№teferenceExceptkm wm ifftwreiled<br />

I


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Нисходящ<strong>е</strong><strong>е</strong> и Восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йсов<br />

Вы уж<strong>е</strong> вид<strong>е</strong>ли, что оп<strong>е</strong>раторы i s и a s работают с инт<strong>е</strong>рф<strong>е</strong>йсами. Значит, для них возможны оп<strong>е</strong>рации<br />

восходящ<strong>е</strong>го и нисходящ<strong>е</strong>го прив<strong>е</strong>д<strong>е</strong>ния. Добавим инт<strong>е</strong>рф<strong>е</strong>йс I C o o k s F o o d к любому классу который<br />

ум<strong>е</strong><strong>е</strong>т подогр<strong>е</strong>вать <strong>е</strong>ду. Добавим такж<strong>е</strong> класс M ic r o w a v e (Микроволновка). Наряду с классом O v en он<br />

буд<strong>е</strong>т р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс IC o o k s F o o d . В р<strong>е</strong>зультат<strong>е</strong> вы получит<strong>е</strong> три способа доступа к объ<strong>е</strong>кту<br />

O ven. А функция I n t e l l i S e n s e подскаж<strong>е</strong>т, каки<strong>е</strong> оп<strong>е</strong>рации вы мож<strong>е</strong>т<strong>е</strong> производить в каждом из этих<br />

тр<strong>е</strong>х случа<strong>е</strong>в:<br />

O v en m i s t e r T o a s t y = n ew O v en О<br />

m i s t e r T o a s t y .<br />

Сразу посл<strong>е</strong> ввода<br />

мочки функця<br />

IntelliSense<br />

выв<strong>е</strong>д<strong>е</strong>т список<br />

вс<strong>е</strong>я возможных<br />

чл<strong>е</strong>нов.<br />

•mCapacity<br />

ж Color<br />

: ConsumePower<br />

Equals<br />

GetHashCode<br />

GetType<br />

' HeatUp<br />

Я * Pluggedin<br />

Preheat<br />

Reheat<br />

I C o o k s F o o d c o o k e r ;<br />

i f ( m i s t e r T o a s t y i s I C o o k s F o o d )<br />

lint Oven.Capacit/<br />

misterToasty — это ссылка<br />

класса Oven, указываю-<br />

‘ ш,ая на обь<strong>е</strong>кт Oven, так<br />

что у вас <strong>е</strong>сть доступ ко<br />

вс<strong>е</strong>м свойствам ц м <strong>е</strong>т о-<br />

, дам этого класса... но это<br />

[ссылка м<strong>е</strong>н<strong>е</strong><strong>е</strong> общ<strong>е</strong>го типа,<br />

j поэтому указывать она<br />

мож<strong>е</strong>т только на объ<strong>е</strong>кты<br />

класса Oven.<br />

Capacity<br />

(interface)<br />

ICooksFood<br />

Capacity<br />

HeatUpO<br />

ReheatO<br />

_<br />

Любой класс,<br />

р<strong>е</strong>ализующий<br />

инт<strong>е</strong>рф<strong>е</strong>йс<br />

1Соо1аРоо1^,<br />

относится к<br />

приборам, которы<strong>е</strong><br />

могут<br />

разогр<strong>е</strong>вать<br />

ИeatUp() <strong>е</strong>ду.<br />

Microwave<br />

Capacity<br />

c o o k e r = m i s t e r T o a s t y a s I C o o k s F o o d ;<br />

c o o k e r .<br />

Equals<br />

GetHashCode<br />

GetType<br />

♦ HeatUp<br />

* Reheat<br />

ToString<br />

A p p l i a n c e p o w e r C o n su m e r ;<br />

lint ICooksFood.Capaclty<br />

i f ( m i s t e r T o a s t y i s A p p l i a n c e )<br />

p o w e r C o n su m e r = m i s t e r T o a s t y ;<br />

p o w e r C o n s u m e r .<br />

Ссылка powerConsumer<br />

принадл<strong>е</strong>жит классу<br />

АррИам<strong>е</strong>. Она да<strong>е</strong>т<br />

доступ к открытым<br />

полям, м<strong>е</strong>тодам и свойствам<br />

этого класса. Но<br />

при ж<strong>е</strong>лании вы мож<strong>е</strong>т<strong>е</strong><br />

с <strong>е</strong><strong>е</strong> помощью сослаться<br />

на обь<strong>е</strong>кт CoffeeMaker.<br />

ConsumePower<br />

Equals<br />

GetHashCode<br />

GetType<br />

^ Pluggedin<br />

"^T o S tring<br />

Ссылка cooker принадл<strong>е</strong>жит<br />

инт<strong>е</strong>рф<strong>е</strong>йсу ICooksFood<br />

и указыва<strong>е</strong>т на т от ж<strong>е</strong><br />

обь<strong>е</strong>кт Oven. Она да<strong>е</strong>т<br />

доступ только к чл<strong>е</strong>нам<br />

инт<strong>е</strong>рф<strong>е</strong>йса ICooksFood, но<br />

при этом мож<strong>е</strong>т указывать<br />

на обь<strong>е</strong>кт Microwave.<br />

[icolor Appllance.Color<br />

PreheatO<br />

HeatUpQ<br />

ReheatO<br />

HeatUpO<br />

ReheatO<br />

MakePopcornO<br />

Три ссылки на<br />

один и тот ж<strong>е</strong><br />

объ<strong>е</strong>кт дают доступ<br />

к различным<br />

м<strong>е</strong>тодам и свойствам,<br />

в зависимости<br />

от сво<strong>е</strong>го<br />

типа.<br />

дальш<strong>е</strong> > 301


н<strong>е</strong>глупы<strong>е</strong> вопросы<br />

_ Часто<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Поч<strong>е</strong>му восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

можно осущ<strong>е</strong>ствлять вс<strong>е</strong>гда, а нисходящ<strong>е</strong><strong>е</strong><br />

н<strong>е</strong>т?<br />

Q « Компилятор мож<strong>е</strong>т пр<strong>е</strong>дупр<strong>е</strong>дить<br />

вас о том, что восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

происходит н<strong>е</strong>правильно. Бол<strong>е</strong><strong>е</strong> того, эта<br />

оп<strong>е</strong>рация н<strong>е</strong> работа<strong>е</strong>т только когда вы<br />

пыта<strong>е</strong>т<strong>е</strong>сь сопоставить объ<strong>е</strong>кт классу, от<br />

которого н<strong>е</strong> происходит насл<strong>е</strong>дования,<br />

или инт<strong>е</strong>рф<strong>е</strong>йсу, который этим объ<strong>е</strong>кгом<br />

н<strong>е</strong> р<strong>е</strong>ализу<strong>е</strong>тся. Компилятор распозна<strong>е</strong>т<br />

н<strong>е</strong>возможность подобной оп<strong>е</strong>рации и выводит<br />

сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>.<br />

При этом компилятор н<strong>е</strong> мож<strong>е</strong>т пров<strong>е</strong>рить,<br />

допустимо ли нисходящ<strong>е</strong><strong>е</strong> присваивани<strong>е</strong>,<br />

которо<strong>е</strong> вы пыта<strong>е</strong>т<strong>е</strong>сь осущ<strong>е</strong>ствить.<br />

Справа от оп<strong>е</strong>ратора a s мож<strong>е</strong>т располагаться<br />

любо<strong>е</strong> имя класса или инт<strong>е</strong>рф<strong>е</strong>йса.<br />

В случа<strong>е</strong>, когда нисходящ<strong>е</strong><strong>е</strong> присваивани<strong>е</strong><br />

н<strong>е</strong>возможно, оп<strong>е</strong>ратор a s возвраща<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> n u ll. Компилятор допуска<strong>е</strong>т<br />

тако<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>, потому что бывают<br />

случаи, когда им<strong>е</strong>нно оно и тр<strong>е</strong>бу<strong>е</strong>тся.<br />

Кто-то говорил мн<strong>е</strong>, что инт<strong>е</strong>рф<strong>е</strong>йс<br />

подоб<strong>е</strong>н контракту, но я н<strong>е</strong> понимаю,<br />

поч<strong>е</strong>му.<br />

о! Да, в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нной ст<strong>е</strong>п<strong>е</strong>ни это д<strong>е</strong>йствит<strong>е</strong>льно<br />

так. Заставляя класс р<strong>е</strong>ализовывать<br />

инт<strong>е</strong>рф<strong>е</strong>йс, вы как бы об<strong>е</strong>ща<strong>е</strong>т<strong>е</strong><br />

компилятору пом<strong>е</strong>стить в н<strong>е</strong>го опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong><br />

м<strong>е</strong>тоды, и компилятор сл<strong>е</strong>дит, чтобы<br />

вы это об<strong>е</strong>щани<strong>е</strong> выполнили.<br />

Хотя намного наглядн<strong>е</strong><strong>е</strong> пр<strong>е</strong>дставить<br />

инт<strong>е</strong>рф<strong>е</strong>йс в вид<strong>е</strong> списка. По этому<br />

списку компилятор пров<strong>е</strong>ря<strong>е</strong>т присутстви<strong>е</strong><br />

в кпасс<strong>е</strong> вс<strong>е</strong>х м<strong>е</strong>тодов, упомянутых<br />

в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong>.<br />

Могу ли я пом<strong>е</strong>стить т<strong>е</strong>ло м<strong>е</strong>тода<br />

в инт<strong>е</strong>рф<strong>е</strong>йс?<br />

Q ; Н<strong>е</strong>т, компилятор н<strong>е</strong> позволит вам это<br />

сд<strong>е</strong>лать. Инт<strong>е</strong>рф<strong>е</strong>йс н<strong>е</strong> долж<strong>е</strong>н сод<strong>е</strong>ржать<br />

оп<strong>е</strong>раторов. Оп<strong>е</strong>ратор в вид<strong>е</strong> дво<strong>е</strong>точия, р<strong>е</strong>ализующий<br />

инт<strong>е</strong>рф<strong>е</strong>йс, н<strong>е</strong> им<strong>е</strong><strong>е</strong>т отнош<strong>е</strong>ния<br />

к оп<strong>е</strong>ратору, использующ<strong>е</strong>муся при насл<strong>е</strong>довании<br />

классов. Р<strong>е</strong>ализация инт<strong>е</strong>рф<strong>е</strong>йса<br />

нич<strong>е</strong>го н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>т в кпасс<strong>е</strong>. Она вс<strong>е</strong>го лишь<br />

гарантиру<strong>е</strong>т присутстви<strong>е</strong> в кпасс<strong>е</strong> м<strong>е</strong>тодов,<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>нных в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong>.<br />

Инт<strong>е</strong>рф<strong>е</strong>йс выглядит как налож<strong>е</strong>ни<strong>е</strong><br />

огранич<strong>е</strong>ний, нич<strong>е</strong>го н<strong>е</strong> м<strong>е</strong>няющих<br />

в самом класс<strong>е</strong>. Зач<strong>е</strong>м мн<strong>е</strong> <strong>е</strong>го использовать?<br />

Q ; Если класс р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс,<br />

инт<strong>е</strong>рф<strong>е</strong>йсная ссылка мож<strong>е</strong>т указывать<br />

на любой экз<strong>е</strong>мпляр этого класса. Это позволя<strong>е</strong>т<br />

оботись одним ссылочным типом,<br />

который работа<strong>е</strong>т с набором объ<strong>е</strong>ктов<br />

различного вида.<br />

Вот мал<strong>е</strong>нький прим<strong>е</strong>р. Лошадь, буйвол,<br />

мул и вол могут тащить т<strong>е</strong>л<strong>е</strong>гу. Но в наш<strong>е</strong>м<br />

симулятор<strong>е</strong> зоопарка H orse, Ох,<br />

M ule и s t e e r — разны<strong>е</strong> классы. Для<br />

аттракциона катания вы хотит<strong>е</strong> создать<br />

массив животных, которы<strong>е</strong> могут тащить<br />

т<strong>е</strong>л<strong>е</strong>гу. Но пом<strong>е</strong>стить в один массив животных<br />

из разных классов можно только в случа<strong>е</strong>,<br />

когда вс<strong>е</strong> они насл<strong>е</strong>дуют от общ<strong>е</strong>го<br />

базового класса. В наш<strong>е</strong>м случа<strong>е</strong> это<br />

услови<strong>е</strong> н<strong>е</strong> соблюда<strong>е</strong>тся. Что ж<strong>е</strong> д<strong>е</strong>лать?<br />

Вам потр<strong>е</strong>бу<strong>е</strong>тся инт<strong>е</strong>рф<strong>е</strong>йс i P u l l e r<br />

с м<strong>е</strong>тодами, отв<strong>е</strong>чающими за п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong><br />

т<strong>е</strong>л<strong>е</strong>ги. Т<strong>е</strong>п<strong>е</strong>рь вы мож<strong>е</strong>т<strong>е</strong> объявить<br />

массив:<br />

I P u l l e r [] p u lle r A r r a y ;<br />

В этот массив можно пом<strong>е</strong>стить ссылку на<br />

любо<strong>е</strong> животно<strong>е</strong>, р<strong>е</strong>ализующ<strong>е</strong><strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс<br />

Х РиН <strong>е</strong>г.<br />

Можно ли р<strong>е</strong>ализовать инт<strong>е</strong>рф<strong>е</strong>йс,<br />

н<strong>е</strong> вводя много кода?<br />

! Кон<strong>е</strong>чно! Ср<strong>е</strong>дства ИСР позволяют<br />

р<strong>е</strong>ализовать инт<strong>е</strong>рф<strong>е</strong>йс автоматич<strong>е</strong>ски.<br />

Начнит<strong>е</strong> вводить код класса:<br />

c l a s s<br />

M icrow ave<br />

{ }<br />

IC ooksFood<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на ICooksFood — под буквой I<br />

появится мал<strong>е</strong>нькая полоска. Если зад<strong>е</strong>ржать<br />

на н<strong>е</strong>й курсор, появится значок:<br />

[interface ICooksFood<br />

TCooksFood<br />

1 Если щ<strong>е</strong>лкнуть на значк<strong>е</strong><br />

н<strong>е</strong> уда<strong>е</strong>тся, используйт<strong>е</strong><br />

комбинацию Ctrl-точка.<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на значк<strong>е</strong> и выб<strong>е</strong>рит<strong>е</strong> команду<br />

Implement Interface ‘ICooksFood’. Это автоматич<strong>е</strong>ски<br />

добавит вс<strong>е</strong> чл<strong>е</strong>ны, которы<strong>е</strong><br />

<strong>е</strong>щ<strong>е</strong> н<strong>е</strong> р<strong>е</strong>ализуют инт<strong>е</strong>рф<strong>е</strong>йс. Каждый из<br />

них снабж<strong>е</strong>н оп<strong>е</strong>ратором throw s, о котором<br />

мы подробно поговорим в глав<strong>е</strong> 10.<br />

Инт<strong>е</strong>рф<strong>е</strong>йс напомина<strong>е</strong>т<br />

список, с которым<br />

св<strong>е</strong>ря<strong>е</strong>тся компилятор,<br />

пров<strong>е</strong>ряя,<br />

р<strong>е</strong>ализу<strong>е</strong>т ли ваш<br />

класс опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нный<br />

набор м<strong>е</strong>тодов.<br />

302 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

ажн<strong>е</strong>нк<strong>е</strong><br />

Расширьт<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс IClown при помощи р<strong>е</strong>ализующих <strong>е</strong>го<br />

классов.<br />

Начнит<strong>е</strong> с инт<strong>е</strong>рф<strong>е</strong>йса IC lo w n из Упражн<strong>е</strong>ния! на с. 290:<br />

i n t e r f a c e IClown {<br />

s t r i n g F unnyT hinglH ave { g e t ; }<br />

}<br />

v o i d H onk{);<br />

IClown<br />

(interface)<br />

FunnyThinglHave<br />

HonkO<br />

^ Создайт<strong>е</strong> производный инт<strong>е</strong>рф<strong>е</strong>йс IS caryC low n со свойством<br />

S c a r y T h i n g l H a v e типа s t r i n g и м<strong>е</strong>тодом чт<strong>е</strong>ния,<br />

но б<strong>е</strong>з м<strong>е</strong>тода записи, а такж<strong>е</strong> с н<strong>е</strong> возвращающим знач<strong>е</strong>ния<br />

м<strong>е</strong>тодом S c a r e L i t t l e C h i l d r e n ( ) .<br />

О<br />

О<br />

Создайт<strong>е</strong> классы для забавных и страшных клоунов:<br />

★<br />

★<br />

Класс F u n n y F u n n y с закрытой строковой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной,<br />

хранящ<strong>е</strong>й список забавного. На основ<strong>е</strong><br />

парам<strong>е</strong>тра F u n n y T h in g lH a v e конструктор зада<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> закрытого поля. М<strong>е</strong>тод Н опк ()<br />

выводит сообщ<strong>е</strong>ни<strong>е</strong> «Би-би! У м<strong>е</strong>ня <strong>е</strong>сть », дал<strong>е</strong><strong>е</strong><br />

сл<strong>е</strong>ду<strong>е</strong>т возвраща<strong>е</strong>мо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода записи<br />

F u n n y T h i n g I H a v e .<br />

FunnyFunny<br />

FunnyThinglHave<br />

HonkO<br />

Класс S c a r y S c a r y хранит в закрытой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной ц<strong>е</strong>ло<strong>е</strong><br />

число, п<strong>е</strong>р<strong>е</strong>данно<strong>е</strong> конструктором в вид<strong>е</strong> парам<strong>е</strong>тра<br />

n u m b e r o f S c a r y T h in g s . М<strong>е</strong>тод чт<strong>е</strong>ния S c a r y T h in g lH a v e<br />

возвраща<strong>е</strong>т строку с числом из конструктора и словом «пауков».<br />

М<strong>е</strong>тод S c a r e L i t t l e C h i l d r e n О вызыва<strong>е</strong>т окно<br />

с т<strong>е</strong>кстом «Ага! Попался!»<br />

Scarygpary..<br />

ScaryThinglHave<br />

IScaryClown<br />

(interface)<br />

ScaryThinglHave<br />

ScareLiffleChildernO<br />

ScareLiffleChildrenO<br />

А это н<strong>е</strong>работающий код для кнопки. Вам нужно найти ошибки и заставить <strong>е</strong>го работать.<br />

p r i v a t e v o id b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

S c a r y S c a r y fin g e r sT h e C lo w n = new S c a r y S c a r y ( "больши<strong>е</strong> ботинки"<br />

}<br />

FunnyFunny som eFunnyClown = fin g e rsT h e C lo w n ;<br />

IS caryC low n so m eO th erS ca ry clo w n = someFunnyClown;<br />

so m e O th e rS ca r y clo w n . H onk(!<br />

ПйЛЬЦМ к л о у н «<br />

ужасны-<br />

0<br />

О<br />

Если н<strong>е</strong> найд<strong>е</strong>шь<br />

ошибку... то...<br />

14)<br />

дальш<strong>е</strong> * 303


уб<strong>е</strong>рит<strong>е</strong> страшных клоунов!<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

]^<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как выглядит расшир<strong>е</strong>ни<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йса IClown с р<strong>е</strong>ализующими <strong>е</strong>го классами.<br />

i n t e r f a c e IC low n {<br />

}<br />

s t r i n g F unnyT hinglH ave { g e t ; }<br />

v o id H onk( );<br />

i n t e r f a c e IS caryC low n : IC low n {<br />

М<strong>е</strong>тод HonkQ<br />

v o i d S c a r e L i t t l e C h i l d r e n 0 ;<br />

использу<strong>е</strong>т<br />

эт от м<strong>е</strong>тод<br />

записи для<br />

отображ<strong>е</strong>ний<br />

p u b l i c F u n n y F u n n y (str in g fu n n y T h in g lH a v e) { сообщ<strong>е</strong>ния, что<br />

t h is .f u n n y T h in g lH a v e = fu n n y T h in g lH a v e; избавля<strong>е</strong>т вас<br />

} от дублируюp<br />

r i v a t e s t r i n g fu n n y T h in g lH a v e;<br />

щ<strong>е</strong>гося кода.<br />

s t r i n g S c a r y T h in g lH a v e { g e t ; }<br />

}<br />

c l a s s FunnyFunny : IC low n {<br />

p u b l i c s t r i n g F unnyT hinglH ave {<br />

}<br />

g e t { r e t u r n "Би-би! У м<strong>е</strong>ня <strong>е</strong>ст ь<br />

p u b l i c v o i d HonkO {<br />

M essa g eB o x . Show {t h i s . F u n n yT h in glH ave);<br />

Г<br />

+ fu n n y T h in g lH a v e; }<br />

Можно <strong>е</strong>щ<strong>е</strong> раз<br />

р<strong>е</strong>ализовать<br />

этот м<strong>е</strong>тод и<br />

свойство инт <strong>е</strong>рф<strong>е</strong>йса<br />

IClown,<br />

но поч<strong>е</strong>му бы н<strong>е</strong><br />

унасл<strong>е</strong>довать их<br />

от FunnyFunny?<br />

, ^ ScaryScary —j m o производный класс от<br />

} который р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс IClown,<br />

Г -^-----fctown<br />

^У^<strong>е</strong>т р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс<br />

c l a s s S c a r y S c a r y i ^ i j n n y F u n ^ IS caryC low n {<br />

p u b l i c S c a r y S c a r y ( s t r in g fu n n y T h in g lH a v e,<br />

: b a se (fu n n y T h in g lH a v e ) {<br />

th is.n u m b e r O fS c a r y T h in g s = n u m b erO fS ca ry T h in g s;<br />

i n t num berO fScaryT hings)<br />

p r i v a t e i n t n u m b ero fS ca ry T h in g s;<br />

p u b l i c s t r i n g S ca ry T h in g lH a v e {<br />

g e t { r e t u r n "У м<strong>е</strong>ня " + num berO fScaryT hings + " п а у к о в " ; }<br />

304 глава 7<br />

p u b l i c v o id S c a r e L i t t l e C h i l d r e n 0 {<br />

M essa g eB o x .S h o w (" A .a ! “ . » ) ;<br />

}<br />

КЯК клоун мож<strong>е</strong>т<br />

^ ^ к<br />

Поэтому вы исполйт ТТ'^^ к&страилным.<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) { оп<strong>е</strong>ратор as.<br />

S c a r y S c a r y fin g e r sT h e C lo w n = new S c a r y S c a r y ("больши<strong>е</strong> ботинки",<br />

FunnyFunny someFunnyClown = fin g e rsT h e C lo w n ;<br />

1 4 )y ^<br />

IS caryC low n so m eO th erS ca ry clo w n = som eFunnyClown OS SCQPySCQPy;<br />

so m e O th e r S c a r y c lo w n .H o n k O ;<br />

} ------- Ссылку someOtherScaryclown можно использовать для<br />

вызова м<strong>е</strong>тода ScareLittleChildrenQ, но вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong><br />

вызвать этот м<strong>е</strong>тод ссылкой someFunnyClown.


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Модификаторы доступа<br />

Вы , * <strong>е</strong> зн а <strong>е</strong> т <strong>е</strong> , н а ск ол ь к о важ н ы м я .^ я <strong>е</strong> т с я к л ю ч <strong>е</strong>в о <strong>е</strong> с л о в о p r l v a t e , Л<br />

как <strong>е</strong>го нужно использовать и ч<strong>е</strong>м оно отлича<strong>е</strong>тся от ключ<strong>е</strong>вого слова ^ чл<strong>е</strong>нами (tnembers)<br />

p u b lic . В <strong>C#</strong> подобны<strong>е</strong> ключ<strong>е</strong>вы<strong>е</strong> слова называются модификаторами Людой чл<strong>е</strong>н мож<strong>е</strong>м быть<br />

доступа (access modifiers). М<strong>е</strong>няя модификатор свойства, поля, м<strong>е</strong>тода пом<strong>е</strong>ч<strong>е</strong>н модификамоили<br />

даж<strong>е</strong> вс<strong>е</strong>го класса, вы м<strong>е</strong>ня<strong>е</strong>т<strong>е</strong> способ доступа других классов к ука- Р°М доступа public или<br />

занным эл<strong>е</strong>м<strong>е</strong>нтам. В этом разд<strong>е</strong>л<strong>е</strong> мы вспомним про уж<strong>е</strong> изв<strong>е</strong>стны<strong>е</strong> вам priva <strong>е</strong>.<br />

модификаторы и познакомимся с новыми:<br />

сущ<strong>е</strong>ству<strong>е</strong>т<br />

доступ к объявл<strong>е</strong>нному классу.)<br />

Q public означа<strong>е</strong>т свободный доступ ^<br />

Пом<strong>е</strong>тив класс или <strong>е</strong>го чл<strong>е</strong>ны модификатором p u b lic , вы объявля<strong>е</strong>т<strong>е</strong> открытый<br />

доступ для вс<strong>е</strong>х экз<strong>е</strong>мпляров вс<strong>е</strong>х классов. Это наим<strong>е</strong>н<strong>е</strong><strong>е</strong> ограничивающий из модификаторов.<br />

И вы уж<strong>е</strong> вид<strong>е</strong>ли, причиной каких пробл<strong>е</strong>м он мож<strong>е</strong>т стать,<br />

зуйт<strong>е</strong> <strong>е</strong>го только тогда, когда это д<strong>е</strong>йствит<strong>е</strong>льно нужно. модификато -<br />

ра доступа при<br />

Q private означа<strong>е</strong>т доступ только для д руги х чл<strong>е</strong>нов этого ж <strong>е</strong> класса объявл<strong>е</strong>нии чл<strong>е</strong>на<br />

Пом<strong>е</strong>тив чл<strong>е</strong>ны класса модификатором p r iv a t e , вы оставля<strong>е</strong>т<strong>е</strong> доступ к ним класса о зт ч м т ,<br />

только для других чл<strong>е</strong>нов этого ж<strong>е</strong> класса или экз<strong>е</strong>мпляров этого ж<strong>е</strong> класса,<br />

_<br />

Сам класс можно пом<strong>е</strong>тить словом p r iv a t e , только <strong>е</strong>сли он находится внутри Private.<br />

другого класса. Посл<strong>е</strong> этого доступ к н<strong>е</strong>му сохранится только у экз<strong>е</strong>мпляров э т ^<br />

го вн<strong>е</strong>шн<strong>е</strong>го класса.<br />

Q protected означа<strong>е</strong>т откры тий только для производных классов<br />

Вы уж<strong>е</strong> вид<strong>е</strong>ли, что из производных классов н<strong>е</strong> вс<strong>е</strong>гда им<strong>е</strong><strong>е</strong>тся доступ к полям базовых, что н<strong>е</strong><br />

вс<strong>е</strong>гда удобно. Но любой чл<strong>е</strong>н класса с модификатором p r o te c te d доступ<strong>е</strong>н как в рамках <strong>е</strong>го собств<strong>е</strong>нного<br />

класса, так и из м<strong>е</strong>тодов производных классов.<br />

—' Отсутстви<strong>е</strong> модифика<br />

О internai означа<strong>е</strong>т открытый для други х классов в сборк<strong>е</strong> _ Х <strong>е</strong> н ы ? ^ й с с д или °ин"<br />

Встро<strong>е</strong>нны<strong>е</strong> классы .NET Framework являются сборками (assemblies) —<br />

библиот<strong>е</strong>ками классов, на которы<strong>е</strong> можно ссылаться из ваш<strong>е</strong>го про<strong>е</strong>кта.<br />

Их список можно увид<strong>е</strong>ть, щ<strong>е</strong>лкнув правой кнопкой мыши на пункт<strong>е</strong><br />

References в окн<strong>е</strong> Solution Explorer и выбрав команду Add Reference...<br />

Если при постро<strong>е</strong>нии сборки воспользоваться модификатором<br />

i n t e r n a i , доступ к классам буд<strong>е</strong>т осущ<strong>е</strong>ствляться только изнутри сборки.<br />

Сущ<strong>е</strong>ству<strong>е</strong>т вариация этого модификатора p r o te c te d i n t e r n a i ,<br />

воспользовавшись которой вы ограничит<strong>е</strong> доступ т<strong>е</strong>кущ<strong>е</strong>й сборкой<br />

и типами, которы<strong>е</strong> являются производными от сод<strong>е</strong>ржащ<strong>е</strong>го класса.<br />

s e a le d означа<strong>е</strong>т, что от данного класса н<strong>е</strong>льзя насл<strong>е</strong>довать<br />

Сущ<strong>е</strong>ствуют классы, насл<strong>е</strong>довани<strong>е</strong> от которых н<strong>е</strong>возможно. К ним относятся многи<strong>е</strong><br />

классы .NET Framework, попробуйт<strong>е</strong>, к прим<strong>е</strong>ру, создать класс, насл<strong>е</strong>дующий<br />

от класса S tr in g (м<strong>е</strong>тод этого класса IsEm ptyO rN ull ( ) вы использовали в пр<strong>е</strong>дыдущ<strong>е</strong>й<br />

глав<strong>е</strong>). Компилятор выдаст сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong> «cannot derive from<br />

sealed type ‘string’». Чтобы запр<strong>е</strong>тить насл<strong>е</strong>довани<strong>е</strong> от созданного вами класса,<br />

достаточно добавить ключ<strong>е</strong>во<strong>е</strong> слово s e a le d посл<strong>е</strong> модификатора доступа.<br />

__________ ______<br />

т<strong>е</strong>рф<strong>е</strong>йса означа<strong>е</strong>т, что<br />

буд<strong>е</strong>т использован вариант<br />

internal. При этом класс<br />

становится доступ<strong>е</strong>н для<br />

любого другого класса в состав<strong>е</strong><br />

сборки. Если сборка<br />

вс<strong>е</strong>го одна, модификатор<br />

internal явля<strong>е</strong>тся аналогом<br />

модификатора public<br />

для классов и инт<strong>е</strong>рф<strong>е</strong>йсов.<br />

Откройт<strong>е</strong> какой-нибудь^<br />

старый про<strong>е</strong>кт, пом<strong>е</strong>няйт<strong>е</strong><br />

доступ н<strong>е</strong>которых классов<br />

на internal и посмотрит<strong>е</strong>,<br />

что получится.<br />

Ключ<strong>е</strong>во<strong>е</strong> слово<br />

Sealed н<strong>е</strong> о т ­<br />

носится к м о­<br />

дификаторам<br />

доступа.


про видимость<br />

изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> 6uguMocmu при помои^и<br />

модификаторов доступа<br />

Посмотрим, как модификаторы доступа влияют на видимость различных<br />

чл<strong>е</strong>нов класса. Пом<strong>е</strong>тим вспомогат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong> funnyT hinglH ave<br />

словом p r o te c te d и отр<strong>е</strong>дактиру<strong>е</strong>м м<strong>е</strong>тод S c a r e L ittle C h ild r e n {),<br />

использующий пол<strong>е</strong> funnyT hinglH ave;<br />

В н <strong>е</strong> с и т <strong>е</strong> эт и изм<strong>е</strong>н<strong>е</strong>ния<br />

^ ^ <strong>е</strong> и ^ <strong>е</strong> н к <strong>е</strong> . Зат <strong>е</strong>м в<strong>е</strong>рнимодификат<br />

ора доf<br />

^ y n a знач<strong>е</strong>ни<strong>е</strong> private<br />

и посм от рит <strong>е</strong>, к каким<br />

ошибкам эт о прив<strong>е</strong>д<strong>е</strong>т<br />

О<br />

П<strong>е</strong>р<strong>е</strong>д вами два инт<strong>е</strong>рф<strong>е</strong>йса. IClown для клоуна с набором<br />

см<strong>е</strong>шных в<strong>е</strong>щ<strong>е</strong>й и производный от н<strong>е</strong>го IScaryC low n.<br />

Страшный клоун н<strong>е</strong> только им<strong>е</strong><strong>е</strong>т вс<strong>е</strong> функции обычного<br />

клоуна, но <strong>е</strong>щ<strong>е</strong> и пуга<strong>е</strong>т мал<strong>е</strong>ньких д<strong>е</strong>т<strong>е</strong>й.<br />

interface IClown {<br />

string FunnyThinglHave { get; }<br />

void HonkO;<br />

}<br />

interface IScaryClown : IClown {<br />

string ScaryThinglHave { get;<br />

void ScareLittleChildren0;<br />

}<br />

Слово указыва<strong>е</strong>т, на<br />

какую им<strong>е</strong>нно п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

вы ссыла<strong>е</strong>т<strong>е</strong>сь. Оно говорит<br />

«Посмотри на т<strong>е</strong>кущий<br />

экз<strong>е</strong>мпляр класса».<br />

I<br />

Ключ<strong>е</strong>во<strong>е</strong> слово tkis позволя<strong>е</strong>т<br />

о ж л и ч ы т ь вспомогат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong><br />

^^Р


^ Класс S c a r y S c a r y р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс I S c a r y C lo w n<br />

и насл<strong>е</strong>ду<strong>е</strong>т от класса F u n n y F u n n y , р<strong>е</strong>ализующ<strong>е</strong>го инт<strong>е</strong>р- Моди^Рикадаоры ^<br />

ф<strong>е</strong>йс IC lo w n . Посмотрит<strong>е</strong>, как им<strong>е</strong>нно м<strong>е</strong>тод S c a r e L i t t l e ' J<br />

C h i l d r e n О осущ<strong>е</strong>ствля<strong>е</strong>т доступ к вспомогат<strong>е</strong>льному полю Доступа под<br />

f u n n y T h i n g l H a v e . Тако<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> связано с модификато- уВ<strong>е</strong>лиЧитп<strong>е</strong>ЛьНьхМ<br />

ром p r o t e c t e d . При модификатор<strong>е</strong> p r i v a t e компиляция<br />

кода стала бы н<strong>е</strong>возможной.<br />

class ScaryScary : FunnyFunny, IScaryClown { закрым,<br />

Diiblic ScaryScary (string funnyThinglHave,<br />

со вспомогат<strong>е</strong>льными<br />

, _ __ . полями. Соомв<strong>е</strong>тств<strong>е</strong>нноJ он<br />

int numberof ScaryThxngs) доступ<strong>е</strong>н только для экз<strong>е</strong>мпля-<br />

: base (funnyThinglHave) { ров класса ScaryScary.<br />

this. numberOfScaryThings = numberOfScaryThings;^:<br />

}<br />

private int numberOfScaryThings;<br />

public string ScaryThinglHave {<br />

get { return «У м<strong>е</strong>ня " + numberOfScaryThings + " пауков"; }<br />

J<br />

Ключ<strong>е</strong>во<strong>е</strong> слово protected<br />

оставля<strong>е</strong>т доступ к<br />

public void ScareLittleChildren о {<br />

MessageBox. Show ("Ты н<strong>е</strong> мож<strong>е</strong>шь забрать " производного класса.<br />

+ base.funnyThinglHave);<br />

т, о N ^ Наличи<strong>е</strong> при п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной funnyThing<br />

S ^^^'^<strong>е</strong>во<strong>е</strong> слово base заставля<strong>е</strong>т 1Н


ox уж этот дублирующийся код!<br />

Зач<strong>е</strong>м нуж<strong>е</strong>н инт<strong>е</strong>рф<strong>е</strong>йс, <strong>е</strong>сли вс<strong>е</strong><br />

н<strong>е</strong>обходимы<strong>е</strong> м<strong>е</strong>тоды можно написать<br />

н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно в т<strong>е</strong>л<strong>е</strong> класса?<br />

; По м<strong>е</strong>р<strong>е</strong> усложн<strong>е</strong>ния программ<br />

классов становится слишком много.<br />

Инт<strong>е</strong>рф<strong>е</strong>йсы позволяют сгруппировать<br />

эти классы в соотв<strong>е</strong>тствии с выполня<strong>е</strong>мыми<br />

задачами. Это гарантиру<strong>е</strong>т, что для<br />

выполн<strong>е</strong>ния опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нной работы классы<br />

будут использовать одни и т<strong>е</strong> ж<strong>е</strong> м<strong>е</strong>тоды.<br />

Благодаря инт<strong>е</strong>рф<strong>е</strong>йсу вам н<strong>е</strong> прид<strong>е</strong>тся<br />

б<strong>е</strong>спокоиться о том, как им<strong>е</strong>нно выполня<strong>е</strong>тся<br />

эта работа.<br />

Пр<strong>е</strong>дставим, что у вас <strong>е</strong>сть классы<br />

грузовиков и парусников, р<strong>е</strong>ализующи<strong>е</strong><br />

инт<strong>е</strong>рф<strong>е</strong>йс п<strong>е</strong>р<strong>е</strong>возки пассажиров<br />

1С а ггу Р а зз<strong>е</strong>п д <strong>е</strong>г. Он тр<strong>е</strong>бу<strong>е</strong>т<br />

у р<strong>е</strong>ализующих <strong>е</strong>го классов наличия<br />

м<strong>е</strong>тода С опзит<strong>е</strong>Е п<strong>е</strong>гду ( ) . Программа<br />

мож<strong>е</strong>т использовать оба класса<br />

для п<strong>е</strong>р<strong>е</strong>возки пассажиров, хотя м<strong>е</strong>тод<br />

С опзит<strong>е</strong>Е п<strong>е</strong>гду () для парусников<br />

использу<strong>е</strong>т силу в<strong>е</strong>тра, а для грузовиков —<br />

диз<strong>е</strong>льно<strong>е</strong> топливо.<br />

Б<strong>е</strong>з инт<strong>е</strong>рф<strong>е</strong>йса Х С аггуР азз<strong>е</strong>п д<strong>е</strong>г<br />

программ<strong>е</strong> сложно объяснить, каки<strong>е</strong><br />

транспортны<strong>е</strong> ср<strong>е</strong>дства могут п<strong>е</strong>р<strong>е</strong>возить<br />

пассажиров, а каки<strong>е</strong> — н<strong>е</strong>т. Вам потр<strong>е</strong>бовалось<br />

бы просматривать вс<strong>е</strong> классы,<br />

чтобы опр<strong>е</strong>д<strong>е</strong>лить в них наличи<strong>е</strong> м<strong>е</strong>тодов,<br />

пригодных для п<strong>е</strong>р<strong>е</strong>возки пассажиров,<br />

а потом вызывать эти м<strong>е</strong>тоды вручную.<br />

Б<strong>е</strong>з стандартного инт<strong>е</strong>рф<strong>е</strong>йса они, скор<strong>е</strong><strong>е</strong><br />

вс<strong>е</strong>го, назывались бы слишком разнородно,<br />

кром<strong>е</strong> того, могли оказаться скрытыми<br />

в т<strong>е</strong>л<strong>е</strong> других м<strong>е</strong>тодов. Запутаться в этом<br />

оч<strong>е</strong>нь л<strong>е</strong>гко.<br />

I О ЛЯ?<br />

_ Часто<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

BoiiJJoCbi<br />

Зач<strong>е</strong>м нужны свойства, <strong>е</strong>сли <strong>е</strong>сть<br />

Q ; Инт<strong>е</strong>рф<strong>е</strong>йс опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т способ, которым<br />

класс выполня<strong>е</strong>т опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нную работу. При<br />

этом он н<strong>е</strong> явля<strong>е</strong>тся объ<strong>е</strong>кгом, поэтому вы<br />

н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> создавать экз<strong>е</strong>мпляры и хранить<br />

в них информацию. Добавив пол<strong>е</strong> пут<strong>е</strong>м объявл<strong>е</strong>ния<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, вы ставит<strong>е</strong> п<strong>е</strong>р<strong>е</strong>д профаммой<br />

задачу сохранить данны<strong>е</strong>. Свойство<br />

ж<strong>е</strong>, с точки зр<strong>е</strong>ния остальных объ<strong>е</strong>ктов, выглядиг<br />

как пол<strong>е</strong>, но по сути явля<strong>е</strong>тся м<strong>е</strong>тодом<br />

и н<strong>е</strong> нужда<strong>е</strong>тся в хран<strong>е</strong>нии данных.<br />

Ч<strong>е</strong>м обычная ссылка отлича<strong>е</strong>тся<br />

от инт<strong>е</strong>рф<strong>е</strong>йсной?<br />

Q ; Как работают обычны<strong>е</strong> ссылки,<br />

вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>. Еспи создать экз<strong>е</strong>мпляр<br />

S k a teb o a rd С им<strong>е</strong>н<strong>е</strong>м<br />

VertBoard, и ссылку на н<strong>е</strong>го с им<strong>е</strong>н<strong>е</strong>м<br />

H a lf pipeB oard, ОНИ будут указывать на<br />

один объ<strong>е</strong>кт. Но <strong>е</strong>спи S k a teb o a rd р<strong>е</strong>ализу<strong>е</strong>т<br />

инт<strong>е</strong>рф<strong>е</strong>йс is t r e e t T r i c k s , а вы<br />

созда<strong>е</strong>т<strong>е</strong> ссылку на sk a te b o a r d с им<strong>е</strong>н<strong>е</strong>м<br />

str e e tB o a r d , она буд<strong>е</strong>т знать только<br />

м<strong>е</strong>тоды класса sk a teb o a rd , являющи<strong>е</strong>ся<br />

частью инт<strong>е</strong>рф<strong>е</strong>йса is t r e e t T r ic k 3 .<br />

Вс<strong>е</strong> три ссылки указывают на один объ<strong>е</strong>кт.<br />

Но <strong>е</strong>сли ссылки H a lf P ip eB o a rd<br />

и V ertB o a rd дают доступ ко вс<strong>е</strong>м<br />

свойствам и м<strong>е</strong>тодам объ<strong>е</strong>кта, ссылка<br />

S tr e e tB o a r d видит только т<strong>е</strong> м<strong>е</strong>тоды<br />

и свойства, которы<strong>е</strong> указаны в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong>.<br />

Получа<strong>е</strong>тся, инт<strong>е</strong>рф<strong>е</strong>йсны<strong>е</strong> ссылки<br />

ограничивают мои возможности.<br />

Зач<strong>е</strong>м ж<strong>е</strong> мн<strong>е</strong> их тогда использовать?<br />

S Инт<strong>е</strong>рф<strong>е</strong>йсны<strong>е</strong> ссылки позволяют<br />

работать с различными объ<strong>е</strong>ктами,<br />

выполняющими одну функцию, с их помощью<br />

вы мож<strong>е</strong>т<strong>е</strong> создать массив, обм<strong>е</strong>нивающийся<br />

информаци<strong>е</strong>й с м<strong>е</strong>тодами инт<strong>е</strong>рф<strong>е</strong>йса<br />

IC a rry P a s3 en g er, н<strong>е</strong>важно,<br />

работа<strong>е</strong>т<strong>е</strong> вы с грузовиком, лошадью или<br />

автомобил<strong>е</strong>м. Способы, которыми эти<br />

объ<strong>е</strong>кты выполняют работу, различаются,<br />

но благодаря инт<strong>е</strong>рф<strong>е</strong>йсным ссылкам вы<br />

зна<strong>е</strong>т<strong>е</strong>, что вс<strong>е</strong> они им<strong>е</strong>ют одни и т<strong>е</strong> ж<strong>е</strong><br />

м<strong>е</strong>тоды, одинаковы<strong>е</strong> парам<strong>е</strong>тры и возвращают<br />

знач<strong>е</strong>ния одинаковых типов. Это<br />

да<strong>е</strong>т вам возможность <strong>е</strong>динообразно вызывать<br />

их и п<strong>е</strong>р<strong>е</strong>давать им информацию.<br />

Зач<strong>е</strong>м мн<strong>е</strong> мож<strong>е</strong>т понадобиться<br />

ключ<strong>е</strong>во<strong>е</strong> слово protected?<br />

! Оно позволя<strong>е</strong>т инкапсулировать<br />

класс. Иногда тр<strong>е</strong>бу<strong>е</strong>тся доступ из производного<br />

класса к внутр<strong>е</strong>нн<strong>е</strong>й части<br />

базового. Но при постро<strong>е</strong>нии классов поля<br />

оставляют открытыми только <strong>е</strong>сли б<strong>е</strong>з<br />

этого совс<strong>е</strong>м н<strong>е</strong>льзя обойтись. Модификатор<br />

доступа protected позволя<strong>е</strong>т открыть<br />

поля, доступ к которым нуж<strong>е</strong>н производному<br />

классу, оставив их закрытыми для<br />

остальных объ<strong>е</strong>ктов.<br />

Инт<strong>е</strong>рф<strong>е</strong>йсны<strong>е</strong><br />

ссылки «знают»<br />

только о т<strong>е</strong>х свойствах<br />

и м<strong>е</strong>тодах,<br />

которы<strong>е</strong> упомянуты<br />

в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong>.<br />

308 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Классы, для которых н<strong>е</strong>допустимо создани<strong>е</strong><br />

экз<strong>е</strong>мпляров<br />

Помнит<strong>е</strong> и<strong>е</strong>рархию классов, использованную для симулятора зоопарка? Закончили<br />

вы <strong>е</strong><strong>е</strong> множ<strong>е</strong>ством экз<strong>е</strong>мпляров б<strong>е</strong>г<strong>е</strong>мотов, собак и львов. Но в и<strong>е</strong>рархию<br />

входят и классы C anine и F e lin e , а такж<strong>е</strong> базовый класс Anim al. Дума<strong>е</strong>м,<br />

вы уж<strong>е</strong> поняли, что создани<strong>е</strong> экз<strong>е</strong>мпляров н<strong>е</strong>которых классов н<strong>е</strong> им<strong>е</strong><strong>е</strong>т<br />

смысла. Рассмотрим дополнит<strong>е</strong>льный прим<strong>е</strong>р:<br />

Начн<strong>е</strong>м с базового класса, описывающ<strong>е</strong>го пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> студ<strong>е</strong>нтов<br />

в магазин<strong>е</strong>.<br />

ShQPBer...<br />

TotalSpent<br />

Credilim it<br />

ShopTillYouDropO<br />

BuyFavoriteStuffO<br />

c l a s s S h o p p er {<br />

p u b l i c v o i d S h o p T illY o u D r o p ()<br />

w h ile (T o ta lS p e n t < C r e d itL im it) ArtStudent Engineering<br />

Student<br />

B u y F a v o r it e S t u f f 0 ;<br />

}<br />

p u b l i c v i r t u a l v o i d B u y F a v o r it e S t u f f 0 {<br />

/ / Р<strong>е</strong>ализация зд <strong>е</strong> с ь н <strong>е</strong>ум <strong>е</strong>стна - мы н<strong>е</strong> зн а<strong>е</strong>м ,<br />

/ / что любит покупать наш ст у д <strong>е</strong> н т !<br />

BuyFavoriteStuffO<br />

BuyFavoriteStuffO<br />

}<br />

}<br />

Класс A r t S t u d e n t производный от класса S h o p p e r :<br />

c l a s s ArtStudent : Sh opp er {<br />

p u b l i c o v e r r id e v o id B u y F a v o r it e S t u f f () {<br />

B u y A r tS u p p lie s 0 ;<br />

Г /<br />

Классы A rtStudent<br />

и EngineeringStudent<br />

п<strong>е</strong>р<strong>е</strong>крывают м<strong>е</strong>мод<br />

BuyFavoriteStuffQ.<br />

Они покупают разны<strong>е</strong><br />

книги.<br />

}<br />

B u y B la c k T u r tle n e c k s ( );<br />

B u y D e p r e ss in g M u sic ( ) ;<br />

}<br />

И класс E n g i n e e r i n g S t u d e n t насл<strong>е</strong>ду<strong>е</strong>т от класса S h o p p e r :<br />

c l a s s EngineeringStudent : Sh opp er {<br />

p u b l i c o v e r r id e v o id B u y F a v o r it e S t u f f<br />

О {<br />

B u y P e n c il s {);<br />

B u y G r a p h in g C a lc u la to r { );<br />

B u y P o c k e t P r o t e c t o r 0 ;<br />

}<br />

}<br />

Ч то п р о и зо й д <strong>е</strong> т с п о я в л <strong>е</strong>ни<strong>е</strong>м экз<strong>е</strong> м п л я р а кл а с с а S h o p p e r? И м <strong>е</strong> <strong>е</strong>т л и см ы сл <strong>е</strong>го со зд а в а ть ?<br />

дальш<strong>е</strong> > 309


н<strong>е</strong> могу пов<strong>е</strong>рить, что это н<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс<br />

А бстрактн ы й класс. П<strong>е</strong>р<strong>е</strong>путь<strong>е</strong> м<strong>е</strong>)кду<br />

классом U инт<strong>е</strong>рф<strong>е</strong>йсом<br />

Пр<strong>е</strong>дположим, вам тр<strong>е</strong>бу<strong>е</strong>тся инт<strong>е</strong>рф<strong>е</strong>йс, чтобы заставить классы р<strong>е</strong>ализовывать<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды и свойства. Но при этом вы хотит<strong>е</strong><br />

включить в этот инт<strong>е</strong>рф<strong>е</strong>йс н<strong>е</strong>кий код, чтобы опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды н<strong>е</strong><br />

приходилось р<strong>е</strong>ализовывать во вс<strong>е</strong>х насл<strong>е</strong>дующих классах. На помощь<br />

вам прид<strong>е</strong>т абстрактный класс (abstract class). Этот эл<strong>е</strong>м<strong>е</strong>нт им<strong>е</strong><strong>е</strong>т<br />

свойства инт<strong>е</strong>рф<strong>е</strong>йса, но позволя<strong>е</strong>т записать внутри с<strong>е</strong>бя код.<br />

О Абстрактный класс напом ина<strong>е</strong>т обычный<br />

Как уж<strong>е</strong> знакомый обычный класс, абстрактный класс им<strong>е</strong><strong>е</strong>т<br />

поля и м<strong>е</strong>тоды, и даж<strong>е</strong> позволя<strong>е</strong>т осущ<strong>е</strong>ствлять насл<strong>е</strong>довани<strong>е</strong>.<br />

Фактич<strong>е</strong>ски вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что ум<strong>е</strong><strong>е</strong>т д<strong>е</strong>лать абстрактный<br />

класс!<br />

Абстрактный класс напом ина<strong>е</strong>т инт<strong>е</strong>рцжйс<br />

Создавая класс, р<strong>е</strong>ализующий инт<strong>е</strong>рф<strong>е</strong>йс, вы соглаша<strong>е</strong>т<strong>е</strong>сь<br />

р<strong>е</strong>ализовывать вс<strong>е</strong> опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong> в рамках инт<strong>е</strong>рф<strong>е</strong>йса<br />

свойства и м<strong>е</strong>тоды. Абстрактный класс работа<strong>е</strong>т аналогичным<br />

способом —вс<strong>е</strong> объявл<strong>е</strong>нны<strong>е</strong> в н<strong>е</strong>м свойства и м<strong>е</strong>тоды<br />

должны р<strong>е</strong>гшизовываться в производных классах.<br />

М<strong>е</strong>тод, н<strong>е</strong> им<strong>е</strong>ющий т<strong>е</strong>ла,<br />

называ<strong>е</strong>тся абстракп^иы^<br />

(abstract Method) Н асл!^<br />

дующи<strong>е</strong> классы должны<br />

р<strong>е</strong>ализовывать вс<strong>е</strong> абстрактны<strong>е</strong><br />

м<strong>е</strong>тоды, как<br />

и в случа<strong>е</strong> насл<strong>е</strong>дования от<br />

инт<strong>е</strong>рф<strong>е</strong>йса.<br />

V<br />

Абстрактны<strong>е</strong> м<strong>е</strong>тоды<br />

могут находиться т олько<br />

бнутри абстрактных<br />

классов. Если пом<strong>е</strong>стить<br />

Ому^рь класса абстрактный<br />

м<strong>е</strong>тод и н<strong>е</strong> пом<strong>е</strong>тить сам<br />

класс словом abstract, про-<br />

Создавать экз<strong>е</strong>мпляры абстрактного класса н<strong>е</strong>льзя<br />

Самым большим отличи<strong>е</strong>м абстрактного класса явля<strong>е</strong>тся н<strong>е</strong>возможность<br />

создать <strong>е</strong>го экз<strong>е</strong>мпляр при помощи оп<strong>е</strong>ратора<br />

new. Попытавшись это сд<strong>е</strong>лать, вы получит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об<br />

ошибк<strong>е</strong>.<br />

^ -----<br />

Cannot c r e a t e an i n s t a n c e o f th e<br />

a b s t r a c t c l a s s o r i n t e r f a c e<br />

'M yC lass'<br />

Оилибка связана с наличи<strong>е</strong>м<br />

абстрактных<br />

м<strong>е</strong>тодов, н<strong>е</strong> сод<strong>е</strong>ржащих<br />

' ^^омпилятор н<strong>е</strong> позволя<strong>е</strong>т<br />

создать экз<strong>е</strong>мпляр<br />

класса, который н<strong>е</strong><br />

сод<strong>е</strong>ржит кода, точно<br />

•позволял<br />

экз<strong>е</strong>мпляры<br />

инт<strong>е</strong>рф<strong>е</strong>йсов.<br />

310 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Что? Класс, от которого я н<strong>е</strong> могу получить<br />

экз<strong>е</strong>мпляры? Зач<strong>е</strong>м он вообщ<strong>е</strong> нуж<strong>е</strong>н?<br />

c l a s s Plan0 tMission {<br />

}<br />

Класс PlanetMission клуб<br />

аст рофизиков использу<strong>е</strong>т<br />

для отправки рак<strong>е</strong>т —<br />

к различным план<strong>е</strong>т ам. \<br />

p u b l i c lo n g R o c k e tF u e lP e r M ile ;<br />

p u b l i c lo n g RocketSpeedM PH;<br />

p u b l i c i n t M ile s T o P la n e t ;<br />

p u b l i c lo n g U n its O fF u e lN e e d e d () {<br />

}<br />

Иногда источником части кода являю тся производны <strong>е</strong> классы .<br />

Быва<strong>е</strong>т так, что создани<strong>е</strong> н<strong>е</strong>нужных объ<strong>е</strong>ктов им<strong>е</strong><strong>е</strong>т плохи<strong>е</strong> посл<strong>е</strong>дствия.<br />

Поля самого в<strong>е</strong>рхн<strong>е</strong>го класса и<strong>е</strong>рархии обычно задаются в производных<br />

классах. В класс<strong>е</strong> Animal могут находится вычисл<strong>е</strong>ния, зависящи<strong>е</strong> от знач<strong>е</strong>ния<br />

логич<strong>е</strong>ской п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной HasTail или Vertebrate, но в н<strong>е</strong>м н<strong>е</strong>возможно<br />

задать эту п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную.<br />

Вот <strong>е</strong>щ<strong>е</strong> один прим<strong>е</strong>р...<br />

J<br />

Присваивать этим<br />

полям знач<strong>е</strong>ния в<br />

базовом класс<strong>е</strong> б<strong>е</strong>ссмысл<strong>е</strong>нно,<br />

потому<br />

что мы н<strong>е</strong> зна<strong>е</strong>м,<br />

какая рак<strong>е</strong>та куда<br />

пол<strong>е</strong>тит.<br />

r e t u r n M ile s T o P la n e t * R o c k e tF u e lP e r M ile ;<br />

p u b l i c i n t T im eN eededO {<br />

}<br />

r e t u r n M ile s T o P la n e t / ( i n t ) RocketSpeedM PH;<br />

p u b l i c s t r i n g F u e lN e e d e d 0 (<br />

}<br />

r e t u r n " Y o u 'll n e e d "<br />

+ M ile s T o P la n e t * R o c k e tF u e lP e r M ile<br />

+ " u n i t s o f f u e l t o g e t t h e r e . I t ' l l ta k e<br />

+ T im eN eed ed () + " h o u r s ." ;<br />

Один пол<strong>е</strong>т сов<strong>е</strong>рша<strong>е</strong>мся на<br />

В<strong>е</strong>н<strong>е</strong>ру, другой-на Марс.<br />

\<br />

c l a s s Venus : P la n e t M is s io n {<br />

}<br />

p u b l i c V enus О {<br />

}<br />

M ile s T o P la n e t = 4 0 0 0 0 0 0 0 ;<br />

R o c k e tF u e lP e r M ile = 100000;<br />

RocketSpeedMPH = 25000;<br />

c l a s s Mars : P la n e t M is s io n {<br />

p u b l i c Mars 0 {<br />

M ile s T o P la n e t = 7500 0 0 0 0 ;<br />

R o c k e tF u e lP e r M ile = 1 00000;<br />

RocketSpeedMPH = 25000;<br />

}<br />

} Конструкторы производных классов^Мап<br />

и Venus задают знач<strong>е</strong>ния тр<strong>е</strong>х пол<strong>е</strong>й, унасл<strong>е</strong>дованных<br />

от класса Planet. Но поля н<strong>е</strong><br />

могут получить знач<strong>е</strong>ния от экз<strong>е</strong>мпляра<br />

Planet. Что произойд<strong>е</strong>т, <strong>е</strong>сли их ‘допыта<strong>е</strong>тся<br />

использовать м<strong>е</strong>тод FuelNeeaed{).<br />

p r i v a t e v o id b u t t o n l _ C l i c k ( o b j e c t s .<br />

Mars mars = new M a rs( );<br />

M essa g eB o x . S h ow (m ars. F u e lN e e d e d ())<br />

}<br />

E ven tA rgs e) {<br />

p r i v a t e v o id b u t t o n 2 _ C lic k ( o b j e c t s ,<br />

V enus v e n u s = new V e n u s() ;<br />

E ven tA rgs e) {<br />

M essageB ox. Show (v en u s . F u elN eed ed ( ) ) ;<br />

}<br />

p r i v a t e v o id b u t t o n 3 _ C lic k ( o b j e c t s , E v en tA rg s e) {<br />

P la n e t M is s io n p l a n e t = new P la n e t M i s s i o n ( );<br />

M essageB ox. Show ( p l a n e t . F u elN eed ed ( ) ) ; — —<br />

}<br />

П <strong>е</strong> р <strong>е</strong> д т <strong>е</strong> м к а к п <strong>е</strong> р <strong>е</strong> в <strong>е</strong> р н у т ь с т р а ­<br />

н и ц у, п о д у м а й т <strong>е</strong> , ч т о п р о и з о й д <strong>е</strong> т<br />

п о с л <strong>е</strong> щ <strong>е</strong> л ч к а н а т р <strong>е</strong> т ь <strong>е</strong> й к н о п к <strong>е</strong> ...<br />

дальш<strong>е</strong> ► 311


абстрактны<strong>е</strong> классы изб<strong>е</strong>гают порядка<br />

Как у)к<strong>е</strong> было сказано, н<strong>е</strong>допустимо создавать экз<strong>е</strong>мпляры<br />

н<strong>е</strong>которых классоб<br />

в программ<strong>е</strong> с пр<strong>е</strong>дыдущ<strong>е</strong>й страницы пробл<strong>е</strong>мы начинаются с появл<strong>е</strong>ни<strong>е</strong>м экз<strong>е</strong>мпляра P l a n e t -<br />

M issio n . М<strong>е</strong>тод FuelN eeded () этого класса ожида<strong>е</strong>т, что знач<strong>е</strong>ния <strong>е</strong>го пол<strong>е</strong>й будут заданы в производном<br />

класс<strong>е</strong>. Если этого н<strong>е</strong> происходит, им по умолчанию присваива<strong>е</strong>тся нул<strong>е</strong>во<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. А при<br />

попытк<strong>е</strong> под<strong>е</strong>лить на ноль...<br />

p r i v a t e v o id b u t t o n 3 _ C l i c k ( o b j e c t s , E v en tA rg s e) {<br />

P la n e t M is s io n p l a n e t = new P la n e t M is s io n () ;<br />

}<br />

M e s sa g e B o x .S h o w (p la n e t. F u e lN e e d e d ( ) ) ;<br />

\<br />

- I f<br />

Б м<strong>е</strong>тод<strong>е</strong>- FuelNeededO происходим<br />

д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> Нй<br />

рам<strong>е</strong>тр RocketSpeedMPH.<br />

который рав<strong>е</strong>н нулю.<br />

Attemfrted to dw


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Абстрактный м<strong>е</strong>тод н<strong>е</strong> им<strong>е</strong><strong>е</strong>т т<strong>е</strong>ла<br />

Как вы зна<strong>е</strong>т<strong>е</strong>, в инт<strong>е</strong>рф<strong>е</strong>йс<strong>е</strong> объявляются м<strong>е</strong>тоды и свойства, но отсутству<strong>е</strong>т<br />

их код. Это потому, что каждый м<strong>е</strong>тод в состав<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йса явля<strong>е</strong>тся абстрактным<br />

(abstract method). Давгшт<strong>е</strong> <strong>е</strong>го р<strong>е</strong>ализу<strong>е</strong>м! Сообщ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong><br />

должно исч<strong>е</strong>знуть. Продолжая абстрактный класс, нужно гарантировать<br />

п<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> вс<strong>е</strong>х <strong>е</strong>го абстрактных м<strong>е</strong>тодов. К счастью, достаточно нап<strong>е</strong>чатать<br />

«public override», и как только вы нажм<strong>е</strong>т<strong>е</strong> проб<strong>е</strong>л, появится список вс<strong>е</strong>х<br />

доступных для п<strong>е</strong>р<strong>е</strong>крытия м<strong>е</strong>тодов. Выб<strong>е</strong>рит<strong>е</strong> вариант S e tM issio n In f о ()<br />

и напишит<strong>е</strong>:<br />

abstract class PlanetMission {<br />

pi^lic(^abstrac^void SetMissionlnfo (<br />

int milesToPlanet, int rocketFuelPerMile,<br />

long rocketSpeedMPH);<br />

И н т <strong>е</strong> р ф <strong>е</strong> й с с о д <strong>е</strong> р ж и т<br />

т о л ь к о а б с т р а к т н ы <strong>е</strong> м <strong>е</strong> ­<br />

то д ы , п о э т о м у к л ю ч <strong>е</strong> в о <strong>е</strong><br />

с л о в о a b s tra c t п р и м <strong>е</strong> н я ­<br />

<strong>е</strong> т с я т о л ь к о к о гд а р <strong>е</strong> ч ь<br />

и д <strong>е</strong> т о б а б с т р а к т н ы х<br />

к л а с с а х . Т о л ь к о т а к и <strong>е</strong><br />

к л а с с ы м о гу т и м <strong>е</strong> т ь<br />

в с в о <strong>е</strong> м с о с т а в <strong>е</strong> а б ­<br />

с т р а к т н ы <strong>е</strong> м <strong>е</strong> то д ы .<br />

// остальной код класса...<br />

П о бмЭу э^v^0M д л <strong>е</strong> т<br />

Жизнь абстрактного Л<br />

Г м<strong>е</strong>тода ужасна. В<strong>е</strong>дь ч<br />

это жизнь б<strong>е</strong>з т<strong>е</strong>ла. )<br />

1лрогрйММй нб ь-а<br />

Попытавшись построить программу, вы получит<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong> об отсутствии<br />

р<strong>е</strong>ализации унасл<strong>е</strong>дованного абстрактного чл<strong>е</strong>на:<br />

'V e n u sM issio n ' d o e s n o t im plem ent i n h e r i t e d a b s t r a c t<br />

^ member ' P l a n e t M i s s i o n .S e t M i s s io n l n f o ( l o n g , i n t , i n t ) '<br />

Так давайт<strong>е</strong> р<strong>е</strong>ализу<strong>е</strong>м <strong>е</strong>го! Ошибка сразу исч<strong>е</strong>зн<strong>е</strong>т.<br />

c l a s s V enus : P la n e t M is s io n {<br />

p u b l i c V enus О {<br />

S e t M i s s i n l n f o (4 0 0 0 0 0 0 0 , 1 0 0 0 0 0 , 25000)<br />

} spr<br />

Насл<strong>е</strong>дуя от<br />

абстрактного<br />

класса, нужно<br />

п<strong>е</strong>р<strong>е</strong>крыть ос<strong>е</strong><br />

<strong>е</strong>го абстрактны<strong>е</strong><br />

м<strong>е</strong>тоды.<br />

p u b l i c o v e r r id e S e t M i s s i o n l n f o ( i n t m ile s T o P la n e t , lo n g r o c k e tF u e lP e r M ile ,<br />

}<br />

i n t rocketSpeedM PH) {<br />

t h i s .M il e s T o P l a n e t = m ile s T o P la n e t ;<br />

t h is - R o c k e t F u e lP e r M ile = r o c k e tF u e lP e r M ile ;<br />

th is.R o ck etS p eed M P H = rocketSpeedM PH ;<br />

дальш<strong>е</strong> > 313


стоит тысячи слов<br />

Возьми в руку карандаш<br />

Прод<strong>е</strong>монстрируйт<strong>е</strong> сво<strong>е</strong> искуссство. Сл<strong>е</strong>ва вы видит<strong>е</strong> набор классов и объявл<strong>е</strong>ний инт<strong>е</strong>рф<strong>е</strong>йсов.<br />

Нарисуйт<strong>е</strong> справа соотв<strong>е</strong>тствующи<strong>е</strong> диаграммы классов, как показано в прим<strong>е</strong>р<strong>е</strong><br />

ном<strong>е</strong>р один. Н<strong>е</strong> забудьт<strong>е</strong>, что пунктирная линия показыва<strong>е</strong>т насл<strong>е</strong>довани<strong>е</strong> от инт<strong>е</strong>рф<strong>е</strong>йса,<br />

в то вр<strong>е</strong>мя как сплошная — насл<strong>е</strong>довани<strong>е</strong> от класса.<br />

Дано:<br />

Диаграмма<br />

1) i n t e r f a c e Foo { }<br />

c l a s s B ar : Foo { }<br />

1 )<br />

( in t e r f a c e )<br />

F oo<br />

2) i n t e r f a c e V in n { }<br />

2)<br />

a b s t r a c t c l a s s V o u t : V in n { }<br />

3)<br />

a b s t r a c t c l a s s M u f f ie : W h u ffie { }<br />

c l a s s F l u f f i e : M u f f ie { }<br />

i n t e r f a c e W h u ffie { }<br />

3)<br />

4)<br />

c l a s s Zoop { }<br />

c l a s s Boop : Zoop { )<br />

c l a s s Goop : Boop { }<br />

4)<br />

5)<br />

c l a s s Gamma : D e l t a , E p s i l o n { }<br />

i n t e r f a c e E p s i l o n { }<br />

i n t e r f a c e B e ta { }<br />

c l a s s A lp h a : G am m a,B eta { }<br />

c l a s s D e l t a { }<br />

5)<br />

314 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

А в этом задании сл<strong>е</strong>ва прив<strong>е</strong>д<strong>е</strong>ны диаграммы классов, вам ж<strong>е</strong> нужно пр<strong>е</strong>вратить их в объявл<strong>е</strong>ния,<br />

как показано в п<strong>е</strong>рвом прим<strong>е</strong>р<strong>е</strong>.<br />

Дано:<br />

Объявл<strong>е</strong>ни<strong>е</strong><br />

1) public class Click { }<br />

public class Clack : Click { }<br />

О б о з н а ч <strong>е</strong> н и я<br />

насл<strong>е</strong>ду<strong>е</strong>т<br />

; р<strong>е</strong>ализу<strong>е</strong>т<br />

I<br />

C la c k ^ i класс<br />

Clack i и н т <strong>е</strong> р ф <strong>е</strong> й с<br />

C la c k<br />

абстрактный<br />

класс<br />

дальш<strong>е</strong> > 315


слов<strong>е</strong>сная битва<br />

Б<strong>е</strong>с<strong>е</strong>да у камина<br />

К то важн<strong>е</strong><strong>е</strong>: абстр актн ы й класс<br />

или инт<strong>е</strong>рф<strong>е</strong>йс?<br />

А б с т р а к т н ы й класс<br />

я думаю, абсурдна сама постановка вопроса: кто<br />

из нас важн<strong>е</strong><strong>е</strong>. Б<strong>е</strong>з м<strong>е</strong>ня программист н<strong>е</strong> выполнит<br />

свою работу. Посмотрим правд<strong>е</strong> к глаза, ты<br />

и близко ко мн<strong>е</strong> н<strong>е</strong> мож<strong>е</strong>шь подойти.<br />

И н т<strong>е</strong>р ф <strong>е</strong>й с<br />

Пр<strong>е</strong>красно. Другого я от т<strong>е</strong>бя и н<strong>е</strong> ожидал!<br />

Как ты вообщ<strong>е</strong> мог подумать, что мож<strong>е</strong>шь быть<br />

важн<strong>е</strong><strong>е</strong> м<strong>е</strong>ня? Ты даж<strong>е</strong> н<strong>е</strong> в состоянии насл<strong>е</strong>довать,<br />

как полага<strong>е</strong>тся, т<strong>е</strong>бя можно только р<strong>е</strong>ализовать.<br />

Пр<strong>е</strong>восходит? Да ты сош<strong>е</strong>л с ума. Я намного бол<strong>е</strong><strong>е</strong><br />

гибок. Я могу им<strong>е</strong>ть как обычны<strong>е</strong>, так и абстрактны<strong>е</strong><br />

м<strong>е</strong>тоды. И даж<strong>е</strong> виртуальны<strong>е</strong> м<strong>е</strong>тоды, <strong>е</strong>сли<br />

захочу. Да, я н<strong>е</strong> создаю экз<strong>е</strong>мпляров, но этого н<strong>е</strong><br />

мож<strong>е</strong>шь и ты. Зато моя функциональность нич<strong>е</strong>м<br />

н<strong>е</strong> хуж<strong>е</strong>, ч<strong>е</strong>м у обычного класса.<br />

Возьми в руку карандаш<br />

2) (interfaced<br />

Vinn 1<br />

Vout<br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

3) (interface)]<br />

Whuffie<br />

~ 7 К<br />

Л-<br />

Muffie<br />

Только полный н<strong>е</strong>в<strong>е</strong>жда мож<strong>е</strong>т гордиться т<strong>е</strong>м, что<br />

инт<strong>е</strong>рф<strong>е</strong>йсы н<strong>е</strong> используют м<strong>е</strong>ханизм насл<strong>е</strong>дования,<br />

а р<strong>е</strong>ализуются. Р<strong>е</strong>ализация нич<strong>е</strong>м н<strong>е</strong> хуж<strong>е</strong> насл<strong>е</strong>дования,<br />

а в ч<strong>е</strong>м-то даж<strong>е</strong> пр<strong>е</strong>восходит <strong>е</strong>го!<br />

Да? А <strong>е</strong>сли класс захоч<strong>е</strong>т насл<strong>е</strong>довать у т<strong>е</strong>бя<br />

и у тво<strong>е</strong>го товарища? Насл<strong>е</strong>довать у двух классов<br />

н<strong>е</strong>льзя. Нужно выбрать кого-то одного. А вот<br />

число р<strong>е</strong>ализу<strong>е</strong>мых инт<strong>е</strong>рф<strong>е</strong>йсов мож<strong>е</strong>т быть любым,<br />

так что н<strong>е</strong> нужно говорить мн<strong>е</strong> о гибкости!<br />

С мо<strong>е</strong>й помощью программист заставит классы<br />

д<strong>е</strong>лать что угодно.<br />

4) Z o o p 5)<br />

B oop<br />

D elta<br />

(interface^<br />

Epsilon<br />

\<br />

(interface'!<br />

B eta<br />

/s<br />

/ Ч<br />

Готовы<strong>е</strong> диаграммы<br />

Fluffie<br />

Goop<br />

A lp h a<br />

316 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

А б стр ах тн ьхй класс<br />

Каж<strong>е</strong>тся, ты н<strong>е</strong>сколько п<strong>е</strong>р<strong>е</strong>оц<strong>е</strong>нива<strong>е</strong>шь свою<br />

роль.<br />

И н т<strong>е</strong>р ф <strong>е</strong>й с<br />

Дума<strong>е</strong>шь, раз ты сод<strong>е</strong>ржишь код, лучш<strong>е</strong> т<strong>е</strong>бя никого<br />

н<strong>е</strong>т? Но ты н<strong>е</strong> поспоришь с фактом, что насл<strong>е</strong>довать<br />

можно только от одного класса за раз.<br />

Так что ты огранич<strong>е</strong>н. Да, я н<strong>е</strong> сод<strong>е</strong>ржу кода, но<br />

роль кода сильно пр<strong>е</strong>ув<strong>е</strong>лич<strong>е</strong>на.<br />

Такую ч<strong>е</strong>пуху можно услышать только от инт<strong>е</strong>рф<strong>е</strong>йса.<br />

Н<strong>е</strong>т нич<strong>е</strong>го важн<strong>е</strong><strong>е</strong> кода! Им<strong>е</strong>нно он заставля<strong>е</strong>т<br />

программу работать.<br />

Д<strong>е</strong>вять из д<strong>е</strong>сяти, что программисту нужны опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong><br />

свойства и м<strong>е</strong>тоды, но <strong>е</strong>го при этом н<strong>е</strong><br />

волну<strong>е</strong>т, как им<strong>е</strong>нно они р<strong>е</strong>ализуются.<br />

Да ну? По моим наблюд<strong>е</strong>ниям программистов<br />

оч<strong>е</strong>нь даж<strong>е</strong> волну<strong>е</strong>т сод<strong>е</strong>ржимо<strong>е</strong> свойств и м<strong>е</strong>тодов.<br />

Да, кон<strong>е</strong>чно... расскажи код<strong>е</strong>ру, что он н<strong>е</strong> мож<strong>е</strong>т<br />

писать код.<br />

Да, кон<strong>е</strong>чно. Только вспомни, как часто программисты<br />

пишут м<strong>е</strong>тоды с объ<strong>е</strong>ктами в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тров,<br />

которы<strong>е</strong> просто должны включать в<br />

с<strong>е</strong>бя опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды. При этом никого<br />

н<strong>е</strong> волну<strong>е</strong>т, как им<strong>е</strong>нно эти м<strong>е</strong>тоды постро<strong>е</strong>ны.<br />

Главно<strong>е</strong>, чтобы они были. В этой ситуации достаточно<br />

написать инт<strong>е</strong>рф<strong>е</strong>йс и пробл<strong>е</strong>ма р<strong>е</strong>ш<strong>е</strong>на!<br />

Н<strong>е</strong> им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ния!<br />

2) abstract class Top { }<br />

class Tip : Top { }<br />

4) interface Foo { }<br />

class Bar : Foo { }<br />

class Baz : Bar { }<br />

Корр<strong>е</strong>ктны<strong>е</strong> объявл<strong>е</strong>ния<br />

3) abstract class Fee { }<br />

abstract class Fi : Fee { }<br />

5) interface Zeta { }<br />

class Alpha : Zeta { ,<br />

interface Beta { }<br />

class Delta : Alpha, Beta { }<br />

дальш<strong>е</strong> * 317


пробл<strong>е</strong>мы множ<strong>е</strong>ств<strong>е</strong>нного насл<strong>е</strong>дования<br />

Досадно, что я н<strong>е</strong> могу насл<strong>е</strong>довать больш<strong>е</strong>, ч<strong>е</strong>м от одного<br />

класса, и поэтому должна пользоваться инт<strong>е</strong>рф<strong>е</strong>йсами. Это<br />

большой н<strong>е</strong>достаток С #, н<strong>е</strong> так л и ?<br />

Это н<strong>е</strong> н<strong>е</strong>достаток, а защита.<br />

Разр<strong>е</strong>шить сущ<strong>е</strong>ствовани<strong>е</strong> н<strong>е</strong>скольких базовых классов —вс<strong>е</strong> равно что<br />

открыть банку с ч<strong>е</strong>рвями. Сущ<strong>е</strong>ствуют языки программирования, допускающи<strong>е</strong><br />

множ<strong>е</strong>ств<strong>е</strong>нно<strong>е</strong> насл<strong>е</strong>довани<strong>е</strong> (m ultiple inheritance). Но<br />

пр<strong>е</strong>доставив вм<strong>е</strong>сто этой функции инт<strong>е</strong>рф<strong>е</strong>йсы, <strong>C#</strong> спаса<strong>е</strong>т вас от большой<br />

путаницы, которую мы хот<strong>е</strong>ли бы назвать...<br />

О<br />

MoviePlayer<br />

int ScreenWidth<br />

✓<br />

И Television (Т<strong>е</strong>л<strong>е</strong>ви -<br />

д<strong>е</strong>ни<strong>е</strong>) и MovieTkeater<br />

(К и н о т<strong>е</strong>атр ) насл<strong>е</strong>дуют<br />

от класса<br />

MoviePlayer (По- — ^<br />

каз кино), и ода эти<br />

класса п<strong>е</strong>р<strong>е</strong>крывают<br />

м<strong>е</strong>тод ShowAMovieO<br />

(Показ дрильма).<br />

К-ром<strong>е</strong> того, они насл<strong>е</strong>дуют<br />

свойство<br />

ScreenWidth (Ширина<br />

экрана).<br />

Television<br />

ShowAMovieO<br />

ShowAMovieO<br />

MovieTheater<br />

ShowAMovieO<br />

M o vieT h ejxter^<br />

каждого ^ произойд<strong>е</strong>т,<br />

знач<strong>е</strong>ни<strong>е</strong>. Ч ^ gYi^eater (<br />

и л и класс ^om ei<br />

рамный<br />

знач<strong>е</strong>ния<br />

фил&мм?<br />

изб<strong>е</strong>гайт<strong>е</strong> н<strong>е</strong>опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нности!<br />

■<strong>е</strong>гр<br />

в языках, допускающих см<strong>е</strong>рт<strong>е</strong>льный ромб, возможны крайн<strong>е</strong> н<strong>е</strong>приятны<strong>е</strong> ситуации,<br />

так как для работы с подобными н<strong>е</strong>опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нностями тр<strong>е</strong>буются сп<strong>е</strong>циальны<strong>е</strong><br />

правила... А это означа<strong>е</strong>т дополнит<strong>е</strong>льны<strong>е</strong> усилия при написании программы!<br />

<strong>C#</strong> позволя<strong>е</strong>т этого изб<strong>е</strong>жать. Сд<strong>е</strong>лайт<strong>е</strong> T e le v is io n и M ovieT heater<br />

инт<strong>е</strong>рф<strong>е</strong>йсами, и вам хватит одного м<strong>е</strong>тода ShowAMovie (). Главно<strong>е</strong>, чтобы этот<br />

м<strong>е</strong>тод присутствовал в указанном вами м<strong>е</strong>ст<strong>е</strong>.<br />

318 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

<strong>е</strong> б у с Б б а с с <strong>е</strong> й н <strong>е</strong><br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна и пом<strong>е</strong>стит<strong>е</strong> их на пусты<strong>е</strong> строчки.<br />

Каждый фрагм<strong>е</strong>нт можно использовать н<strong>е</strong>сколько раз. В басс<strong>е</strong>йн<strong>е</strong><br />

<strong>е</strong>сть и лишни<strong>е</strong> фрагм<strong>е</strong>нты. Вам нужно получить набор классов, которы<strong>е</strong><br />

будут компилироваться, запускаться и давать показанный ниж<strong>е</strong><br />

р<strong>е</strong>зультат.<br />

}<br />

N ose {<br />

s t r i n g F ace { g e t ; }<br />

c l a s s : .............................{<br />

p u b lic A c ts О : b a s e (" A c ts " ) { }<br />

p u b lic o v e r r id e {<br />

r e t u r n 5;<br />

a b s t r a c t c l a s s ......................: ......................{<br />

}<br />

p u b l i c v i r t u a l i n t E arO<br />

{<br />

r e tu r n 7;<br />

}<br />

p u b lic P i c a s s o ( s t r i n g fa c e )<br />

{<br />

= f a c e ;<br />

}.................<br />

p u b l i c v i r t u a l s t r i n g F ace {<br />

......... { ............................... ; }<br />

}<br />

s t r i n g f a c e ;<br />

I<br />

c l a s s ............. : ............. {<br />

p u b l i c o v e r r id e s t r i n g F ace {<br />

J g e t { r e t u r n "Of76"; }<br />

Точка входа находимся<br />

зд<strong>е</strong>сь.<br />

p u b l i c s t a t i c v o i d M a i n ( s t r i n g [] a r g s) {<br />

s t r i n g r e s u l t = "";<br />

N o s e [] i = new N o se [3 ] ;<br />

i [0] = new A c t s () ;<br />

i [1] = new Clowns 0 ;<br />

i [2] = new O f76 0 ;<br />

f o r ( i n t X = 0; X < 3; X++) {<br />

r e s u l t += ( ............................... + " "<br />

+ ) + "\n";<br />

c l a s s : {<br />

}<br />

p u b l i c Clowns 0 : b a s e ( "C low ns") { }<br />

Каж д ы й ф р а г­<br />

м <strong>е</strong>нт кода м ожно<br />

и сп о л ь зо в ать<br />

н<strong>е</strong>ско л ь ко раз.<br />

QniBem на с. 3 3 7 -


в форм<strong>е</strong>... в<strong>е</strong>дра с орлами<br />

Думаю, что т<strong>е</strong>п<strong>е</strong>рь<br />

я хорошо ум<strong>е</strong>ю<br />

управлять объ<strong>е</strong>ктами!<br />

данны<strong>е</strong><br />

^ код в классы на мо~<br />

появл<strong>е</strong>ния<br />

оыла р<strong>е</strong>волюционной,<br />

но т<strong>е</strong>п<strong>е</strong>рь это вполн<strong>е</strong><br />

обычная практика программирования.<br />

В ы о б ъ <strong>е</strong> к т н о -о р и <strong>е</strong> н т и р о в а н н ы й п р о гр а м м и с т .<br />

То, ч<strong>е</strong>м вы занима<strong>е</strong>т<strong>е</strong>сь, называ<strong>е</strong>тся о б ъ <strong>е</strong> к т н о -о р и <strong>е</strong> н т и -<br />

р о в а н н ы м п р о г р а м м и р о в а н и <strong>е</strong> м (ООР). До появл<strong>е</strong>ния<br />

таких языков, как С#, объ<strong>е</strong>кты и м<strong>е</strong>тоды при написании<br />

кода н<strong>е</strong> использовались. Прим<strong>е</strong>нялись функции (которы<strong>е</strong><br />

в т<strong>е</strong>х языках назывались м<strong>е</strong>тодами), соср<strong>е</strong>доточ<strong>е</strong>нны<strong>е</strong><br />

в одном м<strong>е</strong>ст<strong>е</strong>. Можно сказать, что каждая программа<br />

им<strong>е</strong>ла один статич<strong>е</strong>ский класс, наполн<strong>е</strong>нный статич<strong>е</strong>скими<br />

м<strong>е</strong>тодами. Писать программы было намного сложн<strong>е</strong><strong>е</strong>.<br />

К счастью, вам н<strong>е</strong> прид<strong>е</strong>тся писать программы б<strong>е</strong>з ООР,<br />

так как это ключ<strong>е</strong>вая часть языка С#.<br />

Ч<strong>е</strong>тыр<strong>е</strong> принципа объ<strong>е</strong>ктно-ори<strong>е</strong>нтироВанного программирования<br />

Объ<strong>е</strong>ктно-ори<strong>е</strong>нтированно<strong>е</strong> программировани<strong>е</strong> опира<strong>е</strong>тся на ч<strong>е</strong>тыр<strong>е</strong><br />

принципа, которы<strong>е</strong> вам уж<strong>е</strong> знакомы. Вы пользовались ими при написании<br />

программ: н а с л <strong>е</strong> д о в а н и <strong>е</strong> , а б с т р а к ц и я и и н к а п с у л я ц и я . Посл<strong>е</strong>дний<br />

принцип называ<strong>е</strong>тся н<strong>е</strong>много странно —п о л и м о р ф и з м , но и с ним вы<br />

на самом д<strong>е</strong>л<strong>е</strong> уж<strong>е</strong> сталкивались.<br />

Клдссм и инт<strong>е</strong>рф<strong>е</strong>йсы<br />

могут насл<strong>е</strong>довать<br />

свойства друг друга.<br />

ІТ Ґ ‘' "<br />

данных ^ °<br />

вид<strong>е</strong>ть.<br />

нужно<br />

Абстракция<br />

Создани<strong>е</strong> мод<strong>е</strong>ли, начинающ<strong>е</strong>йся<br />

с бол<strong>е</strong><strong>е</strong> общих - абстрактні,,^<br />

__ классов, от которых<br />

насл<strong>е</strong>дуют бол<strong>е</strong><strong>е</strong> подродны <strong>е</strong>^^^^/<br />

классы.<br />

Инкапсуляция<br />

Полиморфизм<br />

Это слово буквально<br />

означа<strong>е</strong>т «множ<strong>е</strong>ство<br />

форм». Мож<br />

<strong>е</strong> т<strong>е</strong> ли вы пр<strong>е</strong>дставить<br />

ситуацию,<br />

когда объ<strong>е</strong>кт принима<strong>е</strong>т<br />

разны<strong>е</strong> формы?<br />

320 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Различны<strong>е</strong> формы объ<strong>е</strong>кта<br />

Помнит<strong>е</strong>, как вы использовали П<strong>е</strong>р<strong>е</strong>см<strong>е</strong>шника вм<strong>е</strong>сто Животного<br />

и выд<strong>е</strong>ржанный В<strong>е</strong>рмонт вм<strong>е</strong>сто Сыра? Им<strong>е</strong>нно тако<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

называ<strong>е</strong>тся п о л и м о р ф и з м о м . И им<strong>е</strong>нно <strong>е</strong>го вы использу<strong>е</strong>т<strong>е</strong><br />

при восходящ<strong>е</strong>м и нисходящ<strong>е</strong>м прив<strong>е</strong>д<strong>е</strong>нии. Другими<br />

словами, вы вызыва<strong>е</strong>т<strong>е</strong> м<strong>е</strong>тоды и свойства объ<strong>е</strong>кта н<strong>е</strong>зависимо<br />

от их р<strong>е</strong>ализации.<br />

Прим<strong>е</strong>р полиморфизма<br />

Вам пр<strong>е</strong>дстоит выполнить оч<strong>е</strong>нь большо<strong>е</strong> (как никогда ран<strong>е</strong><strong>е</strong>)<br />

упражн<strong>е</strong>ни<strong>е</strong>, в котором вам прид<strong>е</strong>тся то и д<strong>е</strong>ло использовать<br />

полиморфизм, так что будьт<strong>е</strong> внимат<strong>е</strong>льны. Ниж<strong>е</strong> показаны<br />

ч<strong>е</strong>тыр<strong>е</strong> типичных способа прим<strong>е</strong>н<strong>е</strong>ния этого явл<strong>е</strong>ния. Пытайт<strong>е</strong>сь<br />

их отсл<strong>е</strong>живать по м<strong>е</strong>р<strong>е</strong> выполн<strong>е</strong>ния упражн<strong>е</strong>ния:<br />

□<br />

Взять ссылочную п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную одного класса и присвоить<br />

<strong>е</strong>й экз<strong>е</strong>мпляр другого класса.<br />

□<br />

Восходящ<strong>е</strong><strong>е</strong><br />

N e c t a r S t i n g e r b e r t h a = n ew N e c t a r S t i n g e r О ;<br />

I N e c t a r C o l l e c t o r g a t h e r e r = b e r t h a ;<br />

прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> пут<strong>е</strong>м использования производного<br />

класса в оп<strong>е</strong>ратор<strong>е</strong> или м<strong>е</strong>тод<strong>е</strong>, ожидающих<br />

знач<strong>е</strong>ни<strong>е</strong> из базового класса. .<br />

О полиморфизм<strong>е</strong><br />

можно говорить, когда<br />

вы б<strong>е</strong>р<strong>е</strong>т<strong>е</strong> экз<strong>е</strong>мпляр<br />

класса и использу<strong>е</strong>т<strong>е</strong><br />

<strong>е</strong>го в оп<strong>е</strong>ратор<strong>е</strong><br />

или м<strong>е</strong>тод<strong>е</strong>, которы<strong>е</strong><br />

ожидают знач<strong>е</strong>ни<strong>е</strong><br />

другого типа, наприм<strong>е</strong>р,<br />

из родит<strong>е</strong>льского<br />

класса или р<strong>е</strong>ализу<strong>е</strong>мого<br />

инт<strong>е</strong>рф<strong>е</strong>йса.<br />

s p o t = n e w D o g ( ) ;<br />

□<br />

Создани<strong>е</strong><br />

z o o K e e p e r . F e e d A n A n i m a l ( s p o t ) ;<br />

ссылочной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной инт<strong>е</strong>рф<strong>е</strong>йсного типа<br />

и нац<strong>е</strong>ливани<strong>е</strong> <strong>е</strong><strong>е</strong> на объ<strong>е</strong>кт, р<strong>е</strong>ализующий инт<strong>е</strong>рф<strong>е</strong>йс.<br />

i s t i n g P a t r o l d e f e n d e r = n ew S t i n g P a t r o l О ;<br />

Нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> при помощи оп<strong>е</strong>ратора a s .<br />

v o i d M a in t a in T h e H i v e ( I W o r k e r w o r k e r ) {<br />

i f ( w o r k e r i s H i v e M a i n t a i n e r ) {<br />

н а с л <strong>е</strong>д у<strong>е</strong> т о т класса А п ! т ^ ^' к о т о р ы й<br />

Э т о т ож <strong>е</strong> воскодящ <strong>е</strong><strong>е</strong><br />

^ прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>!<br />

М <strong>е</strong> т о д MaintainTheHmO в ка<br />

ч <strong>е</strong>ст в<strong>е</strong> п а р а м <strong>е</strong> т р а u ^ 0 A t> 3 yem<br />

и н т <strong>е</strong> р ф <strong>е</strong> й с (Worker. О п <strong>е</strong> р а т о р<br />

as п о зво л я <strong>е</strong>т<br />

ку H iveM ain tain er на о о ь <strong>е</strong> к т<br />

w orker.<br />

H i v e M a i n t a i n e r m a i n t a i n e r = w o r k e r a s H i v e M a i n t a i n e r ;<br />

дальш<strong>е</strong> * 321


приступим<br />

о<br />

Длинны<strong>е</strong><br />

упражн<strong>е</strong>ния<br />

Давайт<strong>е</strong> построим дом! В мод<strong>е</strong>ли дома классы будут пр<strong>е</strong>дставлять комнаты<br />

и прочи<strong>е</strong> пом<strong>е</strong>щ<strong>е</strong>ния, а инт<strong>е</strong>рф<strong>е</strong>йс пусть соотв<strong>е</strong>тству<strong>е</strong>т дв<strong>е</strong>ри.<br />

Начн<strong>е</strong>м с м од<strong>е</strong>ли классов<br />

Каждая комната и пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> должны быть пр<strong>е</strong>дставл<strong>е</strong>ны<br />

отд<strong>е</strong>льным объ<strong>е</strong>ктом. Внутр<strong>е</strong>нни<strong>е</strong> комнаты насл<strong>е</strong>дуют от<br />

класса Room (Комната), а вн<strong>е</strong>шни<strong>е</strong> от класса O u t s i d e (Снаружи).<br />

Для этих классов в свою оч<strong>е</strong>р<strong>е</strong>дь им<strong>е</strong><strong>е</strong>тся базовый<br />

класс L o c a t i o n (Пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>) с двумя полями: Name для<br />

названия пом<strong>е</strong>щ<strong>е</strong>ния (Кухня) и E x i t s (Выходы) массив<br />

объ<strong>е</strong>ктов, связанный с отд<strong>е</strong>льными пом<strong>е</strong>щ<strong>е</strong>ниями. В итог<strong>е</strong><br />

запись d in in g R o o m .N a m e буд<strong>е</strong>т им<strong>е</strong>ть знач<strong>е</strong>ни<strong>е</strong> D i n i n g<br />

Room (Столовая), а запись d i n in g R o o m . E x i t s буд<strong>е</strong>т соотв<strong>е</strong>тствовать<br />

массиву { L iv in g R o o m , K i t c h e n }.<br />

Н арису<strong>е</strong>м план дома<br />

В дом<strong>е</strong> три комнаты, лужайка, задний двор и сад.<br />

Вн<strong>е</strong>шних дв<strong>е</strong>р<strong>е</strong>й дв<strong>е</strong>; одна в<strong>е</strong>д<strong>е</strong>т из гостиной на лужайку,<br />

а вторая —из кухни на задний двор.<br />

Со<br />

Room<br />

Decoration<br />

Класс Location<br />

''•абстрактный.<br />

' Им<strong>е</strong>нно поэт о­<br />

му на диаграмiMe<br />

он с<strong>е</strong>рый.<br />

Hot<br />

Outside<br />

Инт<strong>е</strong>рь<strong>е</strong>р пом<strong>е</strong>щ<strong>е</strong>ний опи -<br />

сыва<strong>е</strong>тся пр<strong>е</strong>дназнач<strong>е</strong>нным<br />

только для чт<strong>е</strong>ния свойством<br />

decoration.<br />

Опр<strong>е</strong>д<strong>е</strong>лить, жарко<br />

ли снаружи, помож<strong>е</strong>т<br />

пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> т олько<br />

для чт<strong>е</strong>ния бул<strong>е</strong>&о<br />

свойство Hot.<br />

Это дв<strong>е</strong>рь, в<strong>е</strong>дущая из<br />

гостиной на лужайку.<br />

Сущ<strong>е</strong>ству<strong>е</strong>т такж<strong>е</strong><br />

дв<strong>е</strong>рь из кухни на задний<br />

двор.<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ститься<br />

с лужайки на задний<br />

двор можно<br />

ч<strong>е</strong>р<strong>е</strong>з сад.<br />

Вс<strong>е</strong> комнаты им<strong>е</strong>ют<br />

дв<strong>е</strong>ри, но только н<strong>е</strong>которы<strong>е</strong><br />

дв<strong>е</strong>ри в<strong>е</strong>дут<br />

наружу.<br />

О Д ля комнат с вн<strong>е</strong>шн<strong>е</strong>й дв<strong>е</strong>рью создадим инт<strong>е</strong>рд)<strong>е</strong>йс<br />

IH asБxteгiorD oor<br />

Пом<strong>е</strong>щ<strong>е</strong>ния с в<strong>е</strong>дущими наружу дв<strong>е</strong>рями (лужайка, задний двор, гостиная<br />

и кухня) должны р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс IH a sE x te rio rD o o r. Пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong><br />

только для чт<strong>е</strong>ния свойство D o o rD e s c rip tio n сод<strong>е</strong>ржит описани<strong>е</strong><br />

дв<strong>е</strong>ри (п<strong>е</strong>р<strong>е</strong>дняя дв<strong>е</strong>рь «Дубовая с латунной ручкой», в то вр<strong>е</strong>мя как<br />

сзади у нас «Калитка»). Свойство D o o rL o catio n сод<strong>е</strong>ржит ссылку на пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>,<br />

в которо<strong>е</strong> в<strong>е</strong>д<strong>е</strong>т дв<strong>е</strong>рь (Кухня).<br />

IHasExteriorDoor<br />

DoorDescription<br />

DoorLocation<br />

322 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

М <strong>е</strong> т о д<br />

Класс Location<br />

Вот код для абстрактного класса L o c a t io n :<br />

a b s t r a c t c l a s s L o c a tio n {<br />

p u b lic L o c a t i o n ( s t r i n g name<br />

t h i s , name = name;<br />

Description вир- }<br />

туальный,<strong>е</strong>го<br />

нужно п<strong>е</strong>р<strong>е</strong>p<br />

u b l i c L o c a tio n [] E x i t s ;<br />

крыть.<br />

) {<br />

\<br />

p r i v a t e s t r i n g name;<br />

p u b l i c s t r i n g Name {<br />

g e t { r e t u r n nam e;<br />

}<br />

^ -------- ^ p u b l i c v i r t u a l s t r i n g D e s c r i p t i o n {<br />

Свойство Description<br />

возвраща<strong>е</strong>т строку<br />

с описани<strong>е</strong>м комнаты<br />

и вс<strong>е</strong>х прил<strong>е</strong>гающих<br />

к н<strong>е</strong>й пом<strong>е</strong>щ<strong>е</strong>ний (их<br />

список сод<strong>е</strong>ржится<br />

в пол<strong>е</strong> Exi'tsO). Так как<br />

в производных клас -<br />

сах описани<strong>е</strong> буд<strong>е</strong>т<br />

м<strong>е</strong>няться, свойство<br />

тр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>крыть, j<br />

}<br />

}<br />

^<br />

поля name, которо<strong>е</strong> явля<strong>е</strong>тся<br />

'пр<strong>е</strong>дназнач<strong>е</strong>нным только для<br />

чт<strong>е</strong>ния пол<strong>е</strong>м свойства Name.<br />

Открыто<strong>е</strong> пол<strong>е</strong> Exits явля<strong>е</strong>тся<br />

массивом ссылок Location,<br />

который отсл<strong>е</strong>жива<strong>е</strong>т, каки<strong>е</strong><br />

пом<strong>е</strong>ш,<strong>е</strong>ния связаны с т<strong>е</strong>м, в<br />

котором находит<strong>е</strong>сь вы.<br />

s t r i n g d e s c r i p t i o n = "Вы н аходи т<strong>е</strong>сь в "<br />

+ ". Вы видит<strong>е</strong> д в <strong>е</strong>р и , в<strong>е</strong>дущи<strong>е</strong> в: ";<br />

f o r ( i n t i = 0; i < E x it s .L e n g t h ; i++ ) {<br />

d e s c r i p t i o n += " " + E x i t s [ i] .N a m e ;<br />

i f ( i != E x it s .L e n g t h - 1)<br />

d e s c r i p t i o n +=<br />

}<br />

d e s c r i p t i o n +=<br />

r e t u r n d e s c r i p t i o n ;<br />

+ name<br />

Помнит<strong>е</strong>, что от<br />

класса Location можно<br />

ссылочны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

типа Location, но<br />

- Класс Room<br />

п<strong>е</strong>р<strong>е</strong>крыва -<br />

<strong>е</strong>т и расширя<strong>е</strong>т<br />

м<strong>е</strong>тод<br />

Description,<br />

добавляя к<br />

н<strong>е</strong>му инт <strong>е</strong>­<br />

рь<strong>е</strong>р. К м<strong>е</strong>тоду<br />

Outside он добавит<br />

т <strong>е</strong>м п<strong>е</strong>ратуру.<br />

Создани<strong>е</strong> классов<br />

Начн<strong>е</strong>м с классов Room и O u t s i d e . Зат<strong>е</strong>м создадим <strong>е</strong>щ<strong>е</strong> два класса: O u t s id e W it h D o o r ,<br />

насл<strong>е</strong>дующий от класса O u t s i d e и р<strong>е</strong>ализующий инт<strong>е</strong>рф<strong>е</strong>йс I H a s E x t e r io r D o o r ,<br />

и R o om W ith D oor, который явля<strong>е</strong>тся производным от класса Room и такж<strong>е</strong> р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс<br />

I H a s E x t e r i o r D o o r . л „<br />

дополнит<strong>е</strong>льную информацию вы<br />

Вот как выглядит описани<strong>е</strong> этих классов: получит<strong>е</strong> на сл<strong>е</strong>дующ<strong>е</strong>й страниц<strong>е</strong>.<br />

d a s s O u tsid eW ith D o o r : O u t s id e ,<br />

{<br />

IH a sE x te r io r D o o r<br />

/ / Тут б у д <strong>е</strong>т св о й ств о D o o r L o c a tio n (Полож<strong>е</strong>ни<strong>е</strong> дв<strong>е</strong>ри)<br />

/ / А з д <strong>е</strong> с ь св о й ств о D o o r D e s c r ip t io n (Описани<strong>е</strong> дв<strong>е</strong>ри)<br />

c l a s s RoomWithDoor : Room,<br />

/ /<br />

/ /<br />

IH a sE x te r io r D o o r<br />

Тут б у д <strong>е</strong>т св о й ств о D o o r L o c a tio n (Полож<strong>е</strong>ни<strong>е</strong> дв<strong>е</strong>ри)<br />

А з д <strong>е</strong> с ь св о й ств о D o o r D e s c r ip t io n (Описани<strong>е</strong> дв<strong>е</strong>ри)<br />

/<br />

Это буд<strong>е</strong>т оч<strong>е</strong>нь<br />

большо<strong>е</strong> упражн<strong>е</strong>ни<strong>е</strong>...<br />

но мы об<strong>е</strong>ща<strong>е</strong>м,<br />

что вы получит<strong>е</strong><br />

удовольстви<strong>е</strong>! и обязат<strong>е</strong>льно<br />

запомнит<strong>е</strong><br />

новый мат<strong>е</strong>риал.<br />

IJefeBefHuirie aßpaHulU) u чродолжим!<br />

дальш<strong>е</strong> У 323


понаблюда<strong>е</strong>м за пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>м объ<strong>е</strong>ктов<br />

Длинны<strong>е</strong><br />

упражн<strong>е</strong>ния<br />

Пришло вр<strong>е</strong>мя создать объ<strong>е</strong>кты, пр<strong>е</strong>дставляющи<strong>е</strong> различны<strong>е</strong> части дома, и добавить<br />

форму для работы с ними.<br />

Как работаю т объ<strong>е</strong>кты<br />

Рассмотрим архит<strong>е</strong>ктуру объ<strong>е</strong>ктов f r o n t Y a r d и d in in g R o o m . Из-за наличия дв<strong>е</strong>р<strong>е</strong>й они должны<br />

быть экз<strong>е</strong>мплярами класса, р<strong>е</strong>ализующ<strong>е</strong>го I H a s E x t e r i o r D o o r . Свойство D o o r L o c a t i o n<br />

хранит ссылку на пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>, располож<strong>е</strong>нно<strong>е</strong> по другую стороны дв<strong>е</strong>ри.<br />

F ro n tV a rd - это<br />

объ<strong>е</strong>кт класса<br />

f OutsideWithDoor,<br />

производного от<br />

класса Outside<br />

и р<strong>е</strong>ализующ<strong>е</strong>го<br />

IHasExteriorDoor.<br />

LivinßRoom это экз<strong>е</strong>мпляр<br />

класса RoomVJithDoor,<br />

производного от класса<br />

Room и р<strong>е</strong>ализующ<strong>е</strong>го<br />

IHasExteriorDoor.<br />

DoorLocation<br />

О<br />

DoorLocation<br />

ExitsO<br />

Ви начали создани<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йса \ Exitsfl !<br />

IHasExteriorDoor и добавили два р<strong>е</strong>али<br />

J<br />

зующих <strong>е</strong>го класса. Один из них насл<strong>е</strong>ду- £)àts — массив ссылок на<br />

<strong>е</strong>т от класса Room, другой—от класса прил<strong>е</strong>жащи<strong>е</strong> пом<strong>е</strong>щ<strong>е</strong>ния.<br />

Outside.<br />

Обь<strong>е</strong>кт LivingRoom им<strong>е</strong><strong>е</strong>т<br />

Закончим создани<strong>е</strong> классов и создадим и х экз<strong>е</strong>мпляры р Т б н Т і,<br />

Практич<strong>е</strong>ски вс<strong>е</strong> готово для постро<strong>е</strong>ния объ<strong>е</strong>ктов. Вам осталось:<br />

★ Уб<strong>е</strong>диться, что конструктор класса O u t s i d e зада<strong>е</strong>т пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> только для чт<strong>е</strong>ния<br />

свойство H o t и п<strong>е</strong>р<strong>е</strong>крыва<strong>е</strong>т свойство D e s c r i p t i o n , добавляя т<strong>е</strong>кст «Тут оч<strong>е</strong>нь жарко»,<br />

когда п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная H o t им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true. Ж арко должно быть на задн<strong>е</strong>м двор<strong>е</strong>, но н<strong>е</strong> на<br />

лужайк<strong>е</strong> и н<strong>е</strong> в саду.<br />

★ Конструктор класса Room долж<strong>е</strong>н задавать свойство D é c o r a t i o n и п<strong>е</strong>р<strong>е</strong>крывать свойство<br />

D e s c r i p t i o n , добавляя «Зд<strong>е</strong>сь вы видит<strong>е</strong> (инт<strong>е</strong>рь<strong>е</strong>р)». В гостиной находится старинный ков<strong>е</strong>р,<br />

в столовой —хрустальная люстра, а на кухн<strong>е</strong> —плита из н<strong>е</strong>ржав<strong>е</strong>ющ<strong>е</strong>й стали и с<strong>е</strong>тчатая<br />

дв<strong>е</strong>рь, в<strong>е</strong>дущая на задний двор.<br />

★ Форма должна создавать объ<strong>е</strong>кты и хранить на них ссылки. Добавьт<strong>е</strong> м<strong>е</strong>тод C r e a t e -<br />

O b j e c t s О , который буд<strong>е</strong>т вызываться конструктором формы. к д<br />

^ Создайт<strong>е</strong> по экз<strong>е</strong>мпляру для ш<strong>е</strong>сти пом<strong>е</strong>щ<strong>е</strong>ний дома. Вот прим<strong>е</strong>р для гостиной:<br />

Exits (массив<br />

R o o m W ith D o o r l i v i n g R o o m = n e w R o o m W ith D o o r ( " Г о с т и н а я " ,<br />

ссылок Location),<br />

" ст а р и н н ы й к о в <strong>е</strong> р " , " д у б о в а я д в <strong>е</strong> р ь с л а т у н н о й р у ч к о й " ) ;<br />

созда<strong>е</strong>т массив<br />

из двух строк. М<strong>е</strong>тод C r e a t e O b j e c t s {) долж<strong>е</strong>н добавлять пол<strong>е</strong> E x i t s [] к каждому объ<strong>е</strong>кту:<br />

м<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> буд<strong>е</strong>т<br />

им<strong>е</strong>ть собств<strong>е</strong>нно<strong>е</strong><br />

пол<strong>е</strong> 6<br />

класс<strong>е</strong> формы.<br />

324 глава 7<br />

f r o n t Y a r d . E x i t s = n e w L o c a t i o n [ ] ^ ^ b a c k Y a r d ,<br />

^<br />

^<br />

g a r d e n Q ^<br />

Зд<strong>е</strong>сь нужны фи-<br />

-гурны<strong>е</strong> скобки.


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

о П о стро<strong>е</strong>ни<strong>е</strong> qx>pMu<br />

Создадим простую форму для экскурсии по дому. Потр<strong>е</strong>бу<strong>е</strong>тся большо<strong>е</strong> т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong><br />

d e s c r i p t i o n , в котором будут появляться описания пом<strong>е</strong>щ<strong>е</strong>ния. Эл<strong>е</strong>м<strong>е</strong>нт C om boBox<br />

с им<strong>е</strong>н<strong>е</strong>м e x i t s сод<strong>е</strong>ржит список выходов из комнаты. Кнопка д о Н <strong>е</strong> г <strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ща<strong>е</strong>т вас<br />

в пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>, выбранно<strong>е</strong> в C om boBox, а кнопка g o T h r o u g h T h e D o o r появля<strong>е</strong>тся при наличии<br />

выхода наружу.<br />

І^нопка доН<strong>е</strong>г<strong>е</strong><br />

позволя<strong>е</strong>м<br />

п<strong>е</strong>р<strong>е</strong>йти в друго<strong>е</strong><br />

пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>.<br />

V<br />

О<br />

W Вфз» the Hause<br />

Это многосмрочно<strong>е</strong><br />

т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong> с<br />

им<strong>е</strong>н<strong>е</strong>м description,<br />

отображающ<strong>е</strong><strong>е</strong> описани<strong>е</strong><br />

т<strong>е</strong>кущ<strong>е</strong>го пом<strong>е</strong>щ<strong>е</strong>ния.<br />

Gohere. 11 Эл<strong>е</strong>м<strong>е</strong>нт ComboBox<br />

Go<br />

the door<br />

Заставим форму работать!<br />

Осталось со<strong>е</strong>динить друг с другом отд<strong>е</strong>льны<strong>е</strong> части.<br />

★<br />

★<br />

Г Г Й Ь в о .<br />

зада<strong>е</strong>тся зЭ<strong>е</strong>с&-<br />

Эл<strong>е</strong>м<strong>е</strong>нт ComboBox сод<strong>е</strong>ржит<br />

список выходов,<br />

поэтому присвоим <strong>е</strong>му<br />

имя exits. Выб<strong>е</strong>рит<strong>е</strong> для<br />

свойства DropPownStyle<br />

вариант PropPownList.<br />

Кнопка goThroughTheDoor<br />

появля<strong>е</strong>тся, <strong>е</strong>сли вы нахо-<br />

■дит<strong>е</strong>сь в комнат<strong>е</strong> с дв<strong>е</strong>рью<br />

на улицу. Для изм<strong>е</strong>н<strong>е</strong>ния<br />

видимости присвойт<strong>е</strong><br />

свойству Visible знач<strong>е</strong>ни<strong>е</strong><br />

true или false.<br />

Форм<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся пол<strong>е</strong> с им<strong>е</strong>н<strong>е</strong>м c u r r e n t L o c a t i o n , опр<strong>е</strong>д<strong>е</strong>ляющ<strong>е</strong><strong>е</strong> т<strong>е</strong>кущ<strong>е</strong><strong>е</strong> полож<strong>е</strong>ни<strong>е</strong>.<br />

^<br />

Добавьт<strong>е</strong> м<strong>е</strong>тод M o v e T o A N e w L o c a tio n () с парам<strong>е</strong>тром L o c a t i o n , присваивающий<br />

свойству c u r r e n t L o c a t i o n ново<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. Зат<strong>е</strong>м он буд<strong>е</strong>т очищать раскрывающийся<br />

список при помощи м<strong>е</strong>тода I t e m s . C l e a r () и добавлять новы<strong>е</strong><br />

им<strong>е</strong>на из массива E x i t s [ ] при помощи м<strong>е</strong>тода I t e m s .A d d (). Након<strong>е</strong>ц остан<strong>е</strong>тся<br />

отобразить п<strong>е</strong>рвый пункт раскрывающ<strong>е</strong>гося списка, присвоив <strong>е</strong>го свойству<br />

S e l e c t e d l n d e x знач<strong>е</strong>ни<strong>е</strong> ноль.<br />

В т<strong>е</strong>кстовом пол<strong>е</strong> должно появиться описани<strong>е</strong> т<strong>е</strong>кущ<strong>е</strong>го пом<strong>е</strong>щ<strong>е</strong>ния.<br />

Оп<strong>е</strong>ратор i s пров<strong>е</strong>ря<strong>е</strong>т наличи<strong>е</strong> дв<strong>е</strong>р<strong>е</strong>й в пом<strong>е</strong>щ<strong>е</strong>нии. При их обнаруж<strong>е</strong>нии нужно<br />

отобразить кнопку Со through the door, воспользовавшись свойством Visible.<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> Go here долж<strong>е</strong>н п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щать в пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>, выбранно<strong>е</strong> в раскрывающ<strong>е</strong>мся<br />

списк<strong>е</strong>.<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> Go through the door долж<strong>е</strong>н приводить к п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>нию ч<strong>е</strong>р<strong>е</strong>з<br />

дв<strong>е</strong>рь.<br />

t<br />

Л<br />

UoAe формы currentLocation — это ссылка<br />

класса Location. Хотя она указыва<strong>е</strong>т на объ<strong>е</strong>кт<br />

Инд<strong>е</strong>кс эл<strong>е</strong>м<strong>е</strong>нта, выбранда<strong>е</strong>т<br />

списк<strong>е</strong>, совпар<strong>е</strong>ализующий<br />

инт<strong>е</strong>рф<strong>е</strong>йс IHasExteriorDoor написать<br />

«currentLocation.PoorLocation» н<strong>е</strong>льзя<br />

Оа<strong>е</strong>т с инд<strong>е</strong>ксом соотв<strong>е</strong>тствиюшЛп<br />

•пом<strong>е</strong>щ<strong>е</strong>ния в массив<strong>е</strong> ExitsU<br />

так как PoorLocation н<strong>е</strong> явля<strong>е</strong>тся пол<strong>е</strong>м класса<br />

Location. Вам потр<strong>е</strong>бу<strong>е</strong>тся нисходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>дальш<strong>е</strong><br />

> 325


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

"ргш<strong>е</strong>ни<strong>е</strong><br />

длинных<br />

ПраЖН<strong>е</strong>НИЙ Вот код для мод<strong>е</strong>ли дома. Комнаты и други<strong>е</strong> пом<strong>е</strong>щ<strong>е</strong>ния пр<strong>е</strong>дставл<strong>е</strong>ны с помощью<br />

классов, в то вр<strong>е</strong>мя как инт<strong>е</strong>рф<strong>е</strong>йс соотв<strong>е</strong>тству<strong>е</strong>т дв<strong>е</strong>рям.<br />

i n t e r f a c e IH a sE x te r io r D o o r {<br />

s t r i n g D o o r D e s c r ip tio n { g e t ; }<br />

L o c a tio n D o o r L o c a tio n { g e t ; s e t ; }<br />

}<br />

c l a s s Room : L o c a t io n {<br />

p r i v a t e s t r i n g d e c o r a t io n ;<br />

p u b l i c R o o m (str in g name, s t r i n g d e c o r a t io n )<br />

: b a se(n am e) {<br />

t h i s . d e c o r a t i o n = d e c o r a t io n ;<br />

}<br />

Это инт<strong>е</strong>рф<strong>е</strong>.йс<br />

iHasExteriorPoor.<br />

^ласс Room насл<strong>е</strong>ду<strong>е</strong>т от<br />

вспом<br />

добавля<strong>е</strong>т<br />

вспомогат<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong> для<br />

у&дназнач<strong>е</strong>нного только для<br />

чт<strong>е</strong>ния свойства Decoration.<br />

конст^^иконструктор<br />

класса.<br />

}<br />

p u b l i c o v e r r id e s t r i n g D e s c r i p t i o n {<br />

g e t {<br />

r e t u r n b a s e . D e s c r i p t i o n + " Вы видит<strong>е</strong> " + d e c o r a t io n +<br />

}<br />

}<br />

c l a s s RoomWithDoor : Room, IH a sE x te r io r D o o r {<br />

p u b l i c R o o m W ith D o o r(strin g name, s t r i n g d e c o r a t io n , s t r i n g d o o r D e s c r ip tio n )<br />

: b a se(n a m e, d e c o r a t io n )<br />

{<br />

}<br />

t h i s . d o o r D e s c r ip t io n = d o o r D e s c r ip tio n ;<br />

p r i v a t e s t r i n g d o o r D e s c r ip tio n ;<br />

p u b l i c s t r i n g D o o r D e s c r ip t io n {<br />

g e t { r e t u r n d o o r D e s c r ip tio n ;<br />

}<br />

p r i v a t e L o c a tio n d o o r L o c a tio n ;<br />

p u b l i c L o c a tio n D o o r L o c a tio n {<br />

g e t { r e t u r n d o o r L o c a tio n ; }<br />

s e t { d o o r L o c a tio n = v a lu e ; }<br />

Класс RoomWithDoor насл<strong>е</strong>ду<strong>е</strong>т от<br />

класса Room и р<strong>е</strong>ализу<strong>е</strong>т инт <strong>е</strong>рф<strong>е</strong>йс<br />

iHasExteriorPoor. ß дополн<strong>е</strong>ни<strong>е</strong><br />

к функциям класса Room в конструктор<br />

добавля<strong>е</strong>тся описани<strong>е</strong><br />

вн<strong>е</strong>илн<strong>е</strong>й дв<strong>е</strong>ри. Появля<strong>е</strong>тся ссылка<br />

PoorLocation, указывающая, куда<br />

им<strong>е</strong>нно в<strong>е</strong>д<strong>е</strong>т дв<strong>е</strong>рь. Инт<strong>е</strong>рф<strong>е</strong>йс<br />

IHasExteriorPoor тр<strong>е</strong>бу<strong>е</strong>т м<strong>е</strong>тодов<br />

PoorPescription и PoorLocation.<br />

326 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

c l a s s O u tsid e ; L o c a tio n<br />

p r i v a t e b o o l h o t;<br />

p u b l i c b o o l Hot { g e t { r e t u r n h o t ; } }<br />

p u b l i c O u t s i d e ( s t r i n g name, b o o l h o t)<br />

{<br />

: base(n am e)<br />

t h i s . h o t = h o t;<br />

p u b l i c o v e r r id e s t r i n g D e s c r i p t i o n<br />

g e t {<br />

s t r i n g N e w D e s c r ip tio n = b a s e . D e s c r ip t io n ;<br />

i f<br />

(hot)<br />

N e w D e s c r ip tio n += " Оч<strong>е</strong>нь ж арк о.";<br />

r e t u r n N e w D e s c r ip tio n ;<br />

Класс Outside во многом<br />

подоб<strong>е</strong>н классу Room. Он<br />

тож<strong>е</strong> явля<strong>е</strong>тся производным<br />

от класса Location<br />

и добавля<strong>е</strong>т вспомогат<strong>е</strong>льно<strong>е</strong><br />

пол<strong>е</strong> для свойства<br />

Hot. Это свойство<br />

использу<strong>е</strong>тся в м<strong>е</strong>тод<strong>е</strong><br />

DescriptionQ.<br />

}<br />

c l a s s O u tsid eW ith D o o r : O u ts id e ,<br />

IH a sE x te r io r D o o r<br />

p u b l i c O u ts id e W ith D o o r (s tr in g name, b o o l h o t , s t r i n g d o o r D e s c r ip tio n )<br />

: b a se(n a m e, h o t)<br />

t h i s . d o o r D e s c r ip t io n = d o o r D e s c r ip tio n ;<br />

p r i v a t e s t r i n g d o o r D e s c r ip tio n ;<br />

p u b l i c s t r i n g D o o r D e s c r ip t io n {<br />

}<br />

g e t { r e t u r n d o o r D e s c r ip tio n ; }<br />

p r i v a t e L o c a tio n d o o r L o c a tio n ;<br />

p u b l i c L o c a t io n D o o r L o c a tio n {<br />

}<br />

g e t { r e t u r n d o o r L o c a tio n ; }<br />

s e t { d o o r L o c a tio n = v a lu e ; }<br />

p u b l i c o v e r r id e s t r i n g D e s c r i p t i o n<br />

}<br />

g e t {<br />

}<br />

r e t u r n b a s e . D e s c r ip t io n +<br />

\ /<br />

{<br />

Класс OutsideWithDoor<br />

тсл<strong>е</strong>ду<strong>е</strong>т от класса<br />

Outside и р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс<br />

IHasExteriorDoor.<br />

По биду он напомина<strong>е</strong>т<br />

класс RoomWithDoor.<br />

Свойство Description базового<br />

класса получа<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> в зависимости<br />

от того, буд<strong>е</strong>т ли<br />

жарко в рассматрива<strong>е</strong>мом пом<strong>е</strong>ш,<strong>е</strong>нии.<br />

Оно зависит от исходного<br />

свойства Description класса<br />

Location и поэтому включа<strong>е</strong>т<br />

информацию о пом<strong>е</strong>щ<strong>е</strong>нии и выходах.<br />

Вы видит<strong>е</strong> " + d o o r D e s c r ip t io n +<br />

IJepeBej^Hurae стр а н и ц у и г^ододжим!<br />

дальш<strong>е</strong> ► 327


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

длинных<br />

ПраЖН<strong>е</strong>НИЙ Это код формы, располож<strong>е</strong>нный в файл<strong>е</strong> Form1.cs, внутри объявл<strong>е</strong>ния Forml<br />

p u b l i c p a r t i a l c l a s s Forml : Form<br />

{<br />

L o c a t io n c u r r e n t L o c a t io n ; 1<br />

форма отсл<strong>е</strong>жива<strong>е</strong>т, б какой<br />

' комнат<strong>е</strong> вы находит<strong>е</strong>сь<br />

в данный мом<strong>е</strong>нт.<br />

RoomWithDoor liv in g R o o m ;<br />

Room diningR oom ;<br />

RoomWithDoor k it c h e n ;<br />

O u tsid eW ith D o o r fr o n tY a r d ;<br />

O u tsid eW ith D o o r backY ard;<br />

O u tsid e g a rd en ;<br />

p u b l i c F o r m lО {<br />

}<br />

I n it ia liz e C o m p o n e n t О ;<br />

C r e a t e O b j e c t s ();<br />

M oveT oA N ew L ocation(livingR oom ) J<br />

p r i v a t e v o id C r e a t e O b j e c t s О {<br />

При помощи этих ссылочных<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных форма сл<strong>е</strong>дит за<br />

каждым пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>м в дом<strong>е</strong><br />

^<br />

^<br />

Конструктор формы<br />

созда<strong>е</strong>т объ<strong>е</strong>кт<br />

и использу<strong>е</strong>т м<strong>е</strong>тод<br />

MoveToANewLocation<br />

для п<strong>е</strong>р<strong>е</strong>хода в друго<strong>е</strong><br />

пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>.<br />

Создани<strong>е</strong> объ<strong>е</strong>ктов начина<strong>е</strong>тся<br />

с создания<br />

экз<strong>е</strong>мпляров и п<strong>е</strong>р<strong>е</strong>дачи<br />

конструкторам этих<br />

экз<strong>е</strong>мпляров нужной информации.<br />

liv in g R o o m = new Room W ithDoor{"Гостиная", "старинный ков<strong>е</strong>р",<br />

"дубовая дв<strong>е</strong>рь с латунной ручкой");<br />

diningR oom = new Room( "Столовая", "хрустальная люстра");<br />

k i t c h e n = new Room W ithDoor("Кухня", "плита из н<strong>е</strong>ржав<strong>е</strong>ющ<strong>е</strong>й стали", "с<strong>е</strong>тчатая дв<strong>е</strong>рь")<br />

fro n tY a rd = new O u tsid eW ith D o o r("лужайка", f a l s e , "дубовая дв<strong>е</strong>рь с латунной ручкой");<br />

backY ard = new O u tsid e W ith D o o r("Задний двор", t r u e , "с<strong>е</strong>тчатая дв<strong>е</strong>рь");<br />

g a r d e n = new O u t s i d e ("Сад", f a l s e ) ;<br />

d in in g R o o m .E x its = new L o c a t i o n [] { liv in g R o o m , k i t c h e n };<br />

liv in g R o o m .E x it s = new L o c a t i o n [] { diningR oom };<br />

k i t c h e n . E x i t s = new L o c a t io n [ ] { diningR oom };<br />

f r o n t Y a r d .E x it s = new L o c a t i o n [] { backY ard, g a r d e n }<br />

b a c k Y a r d .E x its = new L o c a t io n [] { fr o n tY a r d , g a r d e n }<br />

g a r d e n .E x it s = new L o c a t i o n [] { backY ard, fr o n tY a r d }<br />

liv in g R o o m .D o o r L o c a tio n = fr o n tY a r d ;<br />

f r o n t Y ard. D o o r L o c a tio n = liv in g R o o m ; / Аля объ<strong>е</strong>ктов<br />

> IH asExteriorD oor нцж-<br />

У‘^^^ать полож<strong>е</strong>ни<strong>е</strong><br />

J дв<strong>е</strong>р<strong>е</strong>й.<br />

k it c h e n .D o o r L o c a t io n = backY ard;<br />

b a c k Y a rd .D o o rL o c a tio n = k it c h e n ;<br />

Зд<strong>е</strong>сь мы п<strong>е</strong>р<strong>е</strong>да- ^<br />

<strong>е</strong>м описани<strong>е</strong> дв<strong>е</strong>р<strong>е</strong>й<br />

конструкторам<br />

Outside\лJitШoor.<br />

Зд<strong>е</strong>сь заполня<strong>е</strong>тся массив<br />

Ехіі£[] для каждого из<br />

экз<strong>е</strong>мпляров. Данная проц<strong>е</strong>дура<br />

возможна только<br />

посл<strong>е</strong> создания вс<strong>е</strong>х экз<strong>е</strong>мпляров!<br />

328 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

p r i v a t e v o id M oveT oA N ew L ocation(L ocation n ew L o ca tio n )<br />

'<br />

c u r r e n t L o c a t io n = n ew L o c a tio n ;<br />

e x i t s . Ite m s . C le a r () ;<br />

f o r ( i n t 1 = 0 ; i < c u r r e n t L o c a t io n .E x it s .L e n g t h ; i++ ) P<br />

MemodMoveToANewLocationO<br />

показыва<strong>е</strong>т в форм<strong>е</strong> ново<strong>е</strong><br />

>лом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>.<br />

e x i t s . I te m s. Add ( c u r r e n t L o c a t io n . E x i t s [i] .Name) ; f ^^УЖно о ч и с т и т ь<br />

e x i t s . s e l e c t e d l n d e x = 0;<br />

d e s c r i p t io n . T ex t = c u r r e n t L o c a t io n .D e s c r ip t io n ;<br />

^ ^ ^^М <strong>е</strong> го Т о ж ^<br />

заново заполни<br />

i f ( c u r r e n t L o c a t io n i s IH a sE x te r io r D o o r ) ------ ---------------^ ноль<br />

g o T h r o u g h T h e D o o r .V isib le = tr u e ;<br />

e l s e<br />

^ 'Г gornrougniiiejjuux g o T h r o u g h T h e D o o .vi.bj.xj±t3 r .V isib le = i.ctxöc; f a l s e ;<br />

V Д <strong>е</strong>ла<strong>е</strong>т кнопку Go through, the door н<strong>е</strong>видимой, <strong>е</strong>сли<br />

т<strong>е</strong>куия,<strong>е</strong><strong>е</strong> пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> н<strong>е</strong> р<strong>е</strong>ализу<strong>е</strong>т IHasExteriorPoor.<br />

p r i v a t e v o i d g o H e r e _ C l i c k ( o b j e c t sender, E v e n t A r g s e) {<br />

}<br />

M o v e T o A N e w L o c a t i o n ( c u r r e n t L o c a t i o n . E x i t s [ e x i t s .S e l e c t e d l n d e x ] );<br />

p r i v a t e v o i d g o T h r o u g h T h e D o o r _ C lic k (o b je c t se n d e r , E ven tA rgs e) {<br />

}<br />

IH a sE x te r io r D o o r hasD oor = c u r r e n t L o c a t io n a s IH a sE x te r io r D o o r ;<br />

M oveT oA N ew L ocation(hasD oor. D o o r L o c a tio n ) ;<br />

^Mu >^0М <strong>е</strong>щ <strong>е</strong>ни^п'^^^а‘^^‘^~<br />

\ ‘^^р<strong>е</strong>м <strong>е</strong>нн^ S e k c tld T i''^''<br />

J знач<strong>е</strong>ния нолТ. I<br />

•^^рвый п ункт Т ^^<br />

будьт<strong>е</strong> Z T rT n We за-<br />

^'^opO ownStuleT^<br />

^'^^pOownList<br />

зоват<strong>е</strong>ли н<strong>е</strong> L n<br />

Оп<strong>е</strong>ратор as осущ<strong>е</strong>ствля<strong>е</strong>т нис-<br />

)содящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> currentLocation<br />

к IHasExteriorDoor, что да<strong>е</strong>т нам<br />

доступ к полю DoorLocation.<br />

^<br />

^<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong><br />

Qo here: п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ща<strong>е</strong>т<br />

в выдранно<strong>е</strong><br />

пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>.<br />

Работа <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> законч<strong>е</strong>на!<br />

Нашу зам<strong>е</strong>чат<strong>е</strong>льную мод<strong>е</strong>ль дома можно пр<strong>е</strong>вратить в игру! Хотит<strong>е</strong> поиграть<br />

с компьют<strong>е</strong>ром в прятки? Нам потр<strong>е</strong>бу<strong>е</strong>тся класс O pponent (Соп<strong>е</strong>рник) и возможность<br />

прятать <strong>е</strong>го в комнатах. Ну и, кон<strong>е</strong>чно, большой дом, в котором<br />

удобно прятаться! Мы добавим новый инт<strong>е</strong>рф<strong>е</strong>йс, описывающий укромны<strong>е</strong><br />

м<strong>е</strong>ст<strong>е</strong>чки. И обновим форму, чтобы получить возможность пров<strong>е</strong>рять наличи<strong>е</strong><br />

укромных м<strong>е</strong>ст и отсл<strong>е</strong>живать, сколько ходов вы сд<strong>е</strong>лали, пытаясь найти соп<strong>е</strong>рника!<br />

И ш а к , начн<strong>е</strong>м!<br />

дальш<strong>е</strong> > 329


создай с<strong>е</strong>б<strong>е</strong> соп<strong>е</strong>рника<br />

Вр<strong>е</strong>мя сыграть в прятки! Создадим дополнит<strong>е</strong>льны<strong>е</strong> комнаты, укромны<strong>е</strong> м<strong>е</strong>ст<strong>е</strong>чки<br />

.н<strong>е</strong>ни<strong>е</strong> и соп<strong>е</strong>рника в игр<strong>е</strong>. Создайт<strong>е</strong> новый про<strong>е</strong>кт и воспользуйт<strong>е</strong>сь<br />

_<br />

командой Add Existing Item, чтобы добавить<br />

О Инт<strong>е</strong>рф <strong>е</strong>йс IH idingPlace<br />

Вам н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся нич<strong>е</strong>го особ<strong>е</strong>нного. Любой класс, производный от L o c a t i o n и р<strong>е</strong>ализующий<br />

I H i d i n g P l a c e , им<strong>е</strong><strong>е</strong>т м<strong>е</strong>сто, гд<strong>е</strong> мож<strong>е</strong>т спрятаться соп<strong>е</strong>рник. Потр<strong>е</strong>бу<strong>е</strong>тся только строка,<br />

хранящая информацию о том, гд<strong>е</strong> он пряч<strong>е</strong>тся («в шкафу», «под кроватью»...)<br />

★ Добавьт<strong>е</strong> только м<strong>е</strong>тод чт<strong>е</strong>ния, так как при наличии в комнат<strong>е</strong> укромного м<strong>е</strong>ста, вам уж<strong>е</strong><br />

н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся нич<strong>е</strong>го м<strong>е</strong>нять.<br />

<strong>е</strong> Классы , р<strong>е</strong>ализую щ и<strong>е</strong> IH idingPlace<br />

Потр<strong>е</strong>буются два класса: O u t s i d e W i t h H i d i n g P l a c e (насл<strong>е</strong>дующий от класса O u t s i d e )<br />

и R o o m W it h H id in g P la c e (насл<strong>е</strong>дующий от класса Room). Укромны<strong>е</strong> м<strong>е</strong>ста должны быть<br />

в любой комнат<strong>е</strong> с наружной дв<strong>е</strong>рью, поэтому насл<strong>е</strong>довани<strong>е</strong> буд<strong>е</strong>т осущ<strong>е</strong>ствляться от класса<br />

R o o m W it h H id in g P la c e , а н<strong>е</strong> от класса Room.<br />

О Класс, описы ваю щ ий соп<strong>е</strong>рника<br />

Объ<strong>е</strong>кт O pponent буд<strong>е</strong>т прятаться, а вы <strong>е</strong>го искать.<br />

★<br />

★<br />

★<br />

★<br />

Ему потр<strong>е</strong>бу<strong>е</strong>тся закрыто<strong>е</strong> пол<strong>е</strong> L o c a tio n (myLocat ion) для отсл<strong>е</strong>живания <strong>е</strong>го полож<strong>е</strong>ния<br />

и закрыто<strong>е</strong> пол<strong>е</strong> Random (random) для поиска случайного укромного м<strong>е</strong>ста.<br />

Конструктор присваива<strong>е</strong>т начально<strong>е</strong> полож<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной myLocat ion, а п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

random - новому экз<strong>е</strong>мпляру Random. Игра начина<strong>е</strong>тся на п<strong>е</strong>р<strong>е</strong>дн<strong>е</strong>м двор<strong>е</strong>, а зат<strong>е</strong>м<br />

случайным образом выбира<strong>е</strong>тся м<strong>е</strong>сто для укрытия. Соп<strong>е</strong>рник д<strong>е</strong>ла<strong>е</strong>т 10 ходов. Оказываясь<br />

п<strong>е</strong>р<strong>е</strong>д вн<strong>е</strong>шн<strong>е</strong>й дв<strong>е</strong>рью, он подбрасыва<strong>е</strong>т мон<strong>е</strong>ту, чтобы опр<strong>е</strong>д<strong>е</strong>лить, нужно ли ч<strong>е</strong>р<strong>е</strong>з<br />

н<strong>е</strong><strong>е</strong> проходить.<br />

М<strong>е</strong>тод Move () п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ща<strong>е</strong>т соп<strong>е</strong>рника. Если random . N ext (2) им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> 1, соп<strong>е</strong>рник<br />

проходит в дв<strong>е</strong>рь. Зат<strong>е</strong>м он случайным образом выбира<strong>е</strong>т один из выходов из нового<br />

пом<strong>е</strong>щ<strong>е</strong>ния и проходит сквозь н<strong>е</strong>го. Если в пом<strong>е</strong>щ<strong>е</strong>нии н<strong>е</strong>гд<strong>е</strong> спрятаться, соп<strong>е</strong>рник<br />

снова случайным образом выбира<strong>е</strong>т дв<strong>е</strong>рь и уходит в друго<strong>е</strong> м<strong>е</strong>сто.<br />

М<strong>е</strong>тод Check () с парам<strong>е</strong>тром location возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true, когда соп<strong>е</strong>рник пряч<strong>е</strong>тся.<br />

О Д ополнит<strong>е</strong>льны <strong>е</strong> колонаты<br />

Обновит<strong>е</strong> м<strong>е</strong>тод C reateO bj e c ts (), чтобы создать больш<strong>е</strong> комнат:<br />

★ Добавьт<strong>е</strong> л<strong>е</strong>стницу с д<strong>е</strong>р<strong>е</strong>вянными п<strong>е</strong>рилами, со<strong>е</strong>диняющую гостиную с к о р и д о р о м в т о ­<br />

р о г о э т а ж а , гд<strong>е</strong> висит картина с собакой и стоит шкаф.<br />

★<br />

★<br />

В<strong>е</strong>рхний коридор в<strong>е</strong>д<strong>е</strong>т в три комнаты: г л а в н у ю с п а л ь н ю с большой кроватью, в т о р у ю<br />

с п а л ь н ю с мал<strong>е</strong>нькой кроватью и в а н н у ю с раковиной и туал<strong>е</strong>том. Прятаться можно как<br />

под кроватями, так и в душ<strong>е</strong>.<br />

П<strong>е</strong>р<strong>е</strong>дний и задний дворы со<strong>е</strong>дин<strong>е</strong>ны п р о <strong>е</strong> з д о м с гаражом, пригодным для укрытия.<br />

Прятаться можно и в сара<strong>е</strong>.<br />

330 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

О Обновля<strong>е</strong>м qx>pмy<br />

Создадим н<strong>е</strong>сколько новых кнопок. Они будут появляться и исч<strong>е</strong>зать, в зависимости от<br />

того, на какой стадии находится игра.<br />

Гю<strong>е</strong>дтя кнопка называ<strong>е</strong>тся<br />

В<strong>е</strong>рхни<strong>е</strong> дв<strong>е</strong> кноп ^ А<br />

ки и<br />

список бцдут видимы<br />

только 0 игр<strong>е</strong>- ^<br />

°^о5ража<strong>е</strong>тся<br />

^^олько кнопка Hide (Прячься!).<br />

Посл<strong>е</strong> щ<strong>е</strong>лчка на н<strong>е</strong>й в т <strong>е</strong>кстовом<br />

пол<strong>е</strong> ид<strong>е</strong>т отсч<strong>е</strong>т<br />

м д<strong>е</strong>сять<br />

раз вызыва<strong>е</strong>тся м<strong>е</strong>тод Movef)<br />

В глав<strong>е</strong> 2 t<br />

уж<strong>е</strong> вст р<strong>е</strong>чали<br />

м <strong>е</strong>т о­<br />

ды DoEventsO<br />

и SleepO, которы<strong>е</strong><br />

будут<br />

использоваться<br />

в данном случа<strong>е</strong>.<br />

Заставим кнопки работать<br />

Появились дв<strong>е</strong> новы<strong>е</strong> кнопки.<br />

г<br />

сваива<strong>е</strong>тся<br />

г г ^ о р ^ м Гл<strong>е</strong>Эу<strong>е</strong>^ " 1 ? Г х о Э и -<br />

м<strong>е</strong>ста. Наприм<strong>е</strong>р, появится<br />

S u l ? e<br />

триМ под кроватью).<br />

Ц<strong>е</strong>нтральная кнопка становится видимой только когда вы находит<strong>е</strong>сь в комнат<strong>е</strong><br />

с м<strong>е</strong>стом для укрытия. Она ищ<strong>е</strong>т соп<strong>е</strong>рника при помощи м<strong>е</strong>тода C h e c k { ) . Если<br />

вы <strong>е</strong>го находит<strong>е</strong>, игра п<strong>е</strong>р<strong>е</strong>запуска<strong>е</strong>тся.<br />

Нижняя кнопка запуска<strong>е</strong>т игру. В т<strong>е</strong>кстовом пол<strong>е</strong> с зад<strong>е</strong>ржкой 200 миллис<strong>е</strong>кунд<br />

появляются цифры от 1 до 10. Посл<strong>е</strong> каждой из них соп<strong>е</strong>рник п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ща<strong>е</strong>тся<br />

при помощи м<strong>е</strong>тода M ove (). Зат<strong>е</strong>м на полс<strong>е</strong>кунды появля<strong>е</strong>тся надпись «Я иду искать!»,<br />

и игра начина<strong>е</strong>тся.<br />

О М <strong>е</strong>тод, п<strong>е</strong>р<strong>е</strong>рисовывающий дю рму, и м <strong>е</strong>тод, п<strong>е</strong>р<strong>е</strong>запускаю щ ий игру<br />

М<strong>е</strong>тод R ed ra w F o rm () отв<strong>е</strong>ча<strong>е</strong>т за появл<strong>е</strong>ни<strong>е</strong> нужного т<strong>е</strong>кста в т<strong>е</strong>кстовом пол<strong>е</strong>, видимость<br />

кнопок и ярлык на ср<strong>е</strong>дн<strong>е</strong>й кнопк<strong>е</strong>. М<strong>е</strong>тод R e se tG a m e () запуска<strong>е</strong>тся посл<strong>е</strong> обнаруж<strong>е</strong>ния<br />

соп<strong>е</strong>рника. Он возвраща<strong>е</strong>т соп<strong>е</strong>рника на п<strong>е</strong>р<strong>е</strong>дний двор и позволя<strong>е</strong>т начать<br />

игру заново посл<strong>е</strong> щ<strong>е</strong>лчка на кнопк<strong>е</strong> «Hide!» Р<strong>е</strong>зультатом <strong>е</strong>го работы явля<strong>е</strong>тся пустая<br />

форма с т<strong>е</strong>кстовым пол<strong>е</strong>м и кнопкой «Hide!» В т<strong>е</strong>кстовом пол<strong>е</strong> должна быть информация,<br />

гд<strong>е</strong> и за сколько ходов вы обнаружили соп<strong>е</strong>рника.<br />

О О тсл<strong>е</strong>живани<strong>е</strong> числа ходов<br />

В т<strong>е</strong>кстовом пол<strong>е</strong> должно отображаться колич<strong>е</strong>ство пров<strong>е</strong>р<strong>е</strong>нных<br />

укромных м<strong>е</strong>ст и п<strong>е</strong>р<strong>е</strong>ходов из одного пом<strong>е</strong>щ<strong>е</strong>ния в<br />

друго<strong>е</strong>. Посл<strong>е</strong> обнаруж<strong>е</strong>ния соп<strong>е</strong>рника должно появляться сообщ<strong>е</strong>ни<strong>е</strong><br />

«Ты наш<strong>е</strong>л м<strong>е</strong>ня за X ходов!»<br />

О Вид яэормы в начал<strong>е</strong> работы проградлмы<br />

Изначально форма должна сод<strong>е</strong>ржать пусто<strong>е</strong> т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong><br />

и кнопку «Hide!», щ<strong>е</strong>лчок на которой начина<strong>е</strong>т игру!<br />

дальш<strong>е</strong> ► 331


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

іа ж н <strong>е</strong> н и <strong>е</strong><br />

І'^<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong><br />

Вот как выглядит программа посл<strong>е</strong> создания новых комнат, укромных<br />

м<strong>е</strong>ст и соп<strong>е</strong>рника, с которым вы буд<strong>е</strong>т<strong>е</strong> играть в прятки.<br />

i n t e r f a c e I H id in g P la c e {<br />

}<br />

s t r i n g H id in gP laceN am e { g e t ;<br />

Новый инт<strong>е</strong>рф<strong>е</strong>йс IHidingPlace сод<strong>е</strong>ржим<br />

вс<strong>е</strong>го одно пол<strong>е</strong> мипа string с м <strong>е</strong> м о д о !Г<br />

чт<strong>е</strong>ния, возвращающим названи<strong>е</strong> м<strong>е</strong>ста<br />

гд<strong>е</strong> можно спрятаться. м<strong>е</strong>.ста,<br />

}<br />

c l a s s R oom W ithH idingP lace : Room, I H id in g P la c e {<br />

p u b l i c R o o m W ith H id in g P la c e (str in g name, s t r i n g<br />

{<br />

}<br />

: b a se(n a m e, d e c o r a t io n )<br />

th is .h id in g P la c e N a m e = h id in g P la ce N a m e ;<br />

p r i v a t e s t r i n g h id in g P la ce N a m e ;<br />

p u b l i c s t r i n g H id in gP laceN am e {<br />

g e t { r e t u r n h id in g P la ce N a m e ; }<br />

}<br />

p u b l i c o v e r r id e s t r i n g D e s c r i p t i o n {<br />

g e t {<br />

r e t u r n b a s e . D e s c r i p t i o n + " Спрятаться<br />

}<br />

) }<br />

d e c o r a t io n , s t r i n g h id in g P la ceN a m e)<br />

К л а сс RoomWithHidingPlace<br />

насл<strong>е</strong>ду<strong>е</strong>т от класса Room<br />

и р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс ^<br />

IHidingPlace, добавляя свойство<br />

HidingPlaceName. Данно<strong>е</strong> вспомогат<br />

<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong> зада<strong>е</strong>тся<br />

конст рукт ором.<br />

c l a s s RoomWithDoor : R oom W ithH idingP lace, IH a sE x te r io r D o o r {<br />

p u b l i c R o o m W ith D o o r(strin g name, s t r i n g d e c o r a t io n ,<br />

{<br />

}<br />

s t r i n g h id in g P la ce N a m e , s t r i n g d o o r D e s c r ip tio n )<br />

: b a se(n a m e, d e c o r a t i o n , h id in g P la ceN a m e)<br />

t h i s .d o o r D e s c r ip t io n = d o o r D e s c r ip t io n ;<br />

p r i v a t e s t r i n g d o o r D e s c r ip tio n ;<br />

p u b l i c s t r i n g D o o r D e s c r ip t io n {<br />

}<br />

g e t { r e t u r n d o o r D e s c r ip tio n ; }<br />

p r i v a t e L o c a tio n d o o r L o c a tio n ;<br />

p u b l i c L o c a t io n D o o r L o c a tio n {<br />

}<br />

g e t { r e t u r n d o o r L o c a tio n ; }<br />

s e t { d o o r L o c a tio n = v a lu e ; }<br />

укрымия было р<strong>е</strong>ш<strong>е</strong>но<br />

в Комнаты с вн<strong>е</strong>шними<br />

дв<strong>е</strong>рями, мы сд<strong>е</strong>лали н Класс<br />

RoomWithDoor производным от<br />

RoomWithHidingPlace. Т<strong>е</strong>п<strong>е</strong>рь<br />

конструктор этого производ-<br />

Т к 7 о м Т п Т<br />

названи<strong>е</strong><br />

укромного м<strong>е</strong>ста констриктору<br />

R-oomWithHidingPlace<br />

332 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

c l a s s O u tsid e W ith H id in g P la c e : O u ts id e , I H id in g P la c e {<br />

p u b l i c O u t s id e W it h H id in g P la c e ( s t r in g name, b o o l h o t , s t r i n g h id in g P la ceN a m e)<br />

: b a se(n a m e, h o t)<br />

{ t h is .h id in g P la c e N a m e = h id in g P la ce N a m e ; }<br />

}<br />

p r i v a t e s t r i n g h id in g P la ce N a m e ;<br />

p u b l i c s t r i n g H id in gP laceN am e {<br />

}<br />

g e t { r e t u r n h id in g P la ce N a m e ; }<br />

p u b l i c o v e r r id e s t r i n g D e s c r i p t i o n {<br />

}<br />

g e t {<br />

}<br />

c l a s s O pponent {<br />

r e t u r n b a s e . D e s c r i p t i o n +<br />

p r i v a t e Random random;<br />

p r i v a t e L o c a tio n m y L o ca tio n ;<br />

p u b l i c O p p o n e n t(L o c a tio n s t a r t i n g L o c a t io n )<br />

m y L o ca tio n = s t a r t i n g L o c a t io n ;<br />

random = new Random( );<br />

p u b l i c v o i d MoveO {<br />

i f (m yL ocation i s IH a sE x te r io r D o o r ) {<br />

IH a sE x te r io r D o o r L o ca tio n W ith D o o r<br />

i f (r a n d o m .N e x t(2) == 1)<br />

m y L o ca tio n a s<br />

Класс OutsideWithHidingPlace насл<strong>е</strong>ду<strong>е</strong>т<br />

от класса Outside и р<strong>е</strong>ализу<strong>е</strong>т<br />

м<strong>е</strong>тод IHidingPlace аналогично классу<br />

RoomWithHidingPlace.<br />

Можно сп ря таться " + h id in g P la ce N a m e +<br />

Конструктор класса Opponent 6 кач<strong>е</strong>ств<strong>е</strong><br />

парам<strong>е</strong>тра б<strong>е</strong>р<strong>е</strong>т начально<strong>е</strong> пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>.<br />

Он созда<strong>е</strong>т экз<strong>е</strong>мпляр Random,<br />

при помощи которого случайным образом<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> из<br />

одного м<strong>е</strong>ста в друго<strong>е</strong>.<br />

i<br />

М<strong>е</strong>тод MoveQ при помощи оп<strong>е</strong>ратора<br />

IS пров<strong>е</strong>ря<strong>е</strong>т наличи<strong>е</strong> вн<strong>е</strong>шн<strong>е</strong>й дв<strong>е</strong>ри<br />

в комнат<strong>е</strong>. При <strong>е</strong><strong>е</strong> наличии с 50%-й<br />

в<strong>е</strong>роятностью он ч<strong>е</strong>р<strong>е</strong>з н<strong>е</strong><strong>е</strong> проходит.<br />

Таким способом он случайным образом<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ща<strong>е</strong>тся по дому, пока н<strong>е</strong> находит<br />

м<strong>е</strong>сто, гд<strong>е</strong> можно спрятаться.<br />

I H a s E x te r io r D o o r ;<br />

m y L o ca tio n = L o c a tio n W ith D o o r .D o o r L o c a tio n ;<br />

} Этот цикл while продолжа<strong>е</strong>тся, пока п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

hidden н<strong>е</strong> прим<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true. Это произойд<strong>е</strong>т<br />

b o o l h id d e n = f a l s e ;<br />

при попадании в пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>, пригодно<strong>е</strong> для<br />

w h ile ( ! h id d en ) {<br />

укрытия.<br />

}<br />

i n t rand = r a n d o m .N e x t(m y L o c a tio n .E x its .L e n g th )<br />

m y L o ca tio n = m y L o c a t io n .E x it s [ r a n d ] ;<br />

i f (m yL ocation i s I H id in g P la c e )<br />

h id d e n = tr u e ;<br />

}<br />

p u b l i c b o o l C h e c k (L o c a tio n lo c a tio n T o C h e c k )<br />

}<br />

i f (lo c a tio n T o C h e c k != m yL ocation )<br />

e l s e<br />

r e t u r n f a l s e ;<br />

r e t u r n t r u e ;<br />

М<strong>е</strong>тод CheckQ сравнива<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной location<br />

класса opponent со знач<strong>е</strong>ни -<br />

<strong>е</strong>м ссылки Location. Если об<strong>е</strong><br />

ссылки указывают на один<br />

объ<strong>е</strong>кт, значит, соп<strong>е</strong>рник<br />

найд<strong>е</strong>н!<br />

Ц <strong>е</strong> р <strong>е</strong> ^ <strong>е</strong> р н и т п <strong>е</strong> о и р а н и Щ ) U и р о Д о л ж и м !<br />

дальш<strong>е</strong> ► 333


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

іажн<strong>е</strong>ни<strong>е</strong><br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Это код формы. Н<strong>е</strong>изм<strong>е</strong>нными в н<strong>е</strong>м<br />

остались только м<strong>е</strong>тоды доН<strong>е</strong>г<strong>е</strong>_С11ск()<br />

и доТЬгоидЬТ11<strong>е</strong>Ооог_СНск().<br />

Список пол<strong>е</strong>й класса Form i. Им<strong>е</strong>нно с их<br />

помощью отсл<strong>е</strong>живаются пом<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>,<br />

соп<strong>е</strong>рник и колич<strong>е</strong>ство п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ний, сд<strong>е</strong>ланных<br />

игроком.<br />

^ —.К онст рукт ор Form l созда<strong>е</strong>т объ<strong>е</strong>кты<br />

Ґ опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т полож<strong>е</strong>ни<strong>е</strong> соп<strong>е</strong>рника и п<strong>е</strong>ю<strong>е</strong>-<br />

i n t M oves;<br />

L o c a t io n c u r r e n t L o c a t io n ;<br />

RoomWithDoor liv in g R o o m ;<br />

R oom W ithH idingP lace diningR oom ;<br />

RoomWithDoor k it c h e n ;<br />

Room s t a i r s ;<br />

R oom W ithH idingP lace h a llw a y ;<br />

R oom W ithH idingP lace bathroom ;<br />

R oom W ithH idingP lace m asterB edroom ;<br />

R oom W ithH idingP lace secondB edroom ;<br />

\ > ^ной дв<strong>е</strong>ри или укрш нТго<br />

334 глава 7


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

Аобавив вс<strong>е</strong>го пару строк, вы пристроит<strong>е</strong> к дому ц<strong>е</strong>ло<strong>е</strong> крыло!<br />

Видит<strong>е</strong>, как пол<strong>е</strong>зна инкапсуляция классов и оо-ь<strong>е</strong>ктов?<br />

p r i v a t e v o i d C r e a t e O b j e c t s О {<br />

l i v i n g R o o m = n e w R o o m W i t h D o o r (" Г о с т и н а я " , " с т а р и н н ы й ков<strong>е</strong>р",<br />

"в г а р д<strong>е</strong>роб<strong>е</strong>", " д у б о в а я д в <strong>е</strong> р ь с л а т у н н о й ручкой");<br />

d i n i n g R o o m = n e w R o o m W i t h H i d i n g P l a c e (" С т о л о в а я " , " х р у с т а л ь н а я люстра",<br />

"в в ы с о к о м ш к а ф у " );<br />

k i t c h e n = n e w R o o m W i t h D o o r (" К у х н я " , " п р и б о р ы и з н <strong>е</strong> р ж а в <strong>е</strong> ю щ <strong>е</strong> й стали",<br />

"в сундук<strong>е</strong>", " с <strong>е</strong> т ч а т а я д в <strong>е</strong> рь");<br />

stairs = n e w R o o m (" Л <strong>е</strong> с т н и ц а " , " д <strong>е</strong> р <strong>е</strong> в я н н ы <strong>е</strong> п <strong>е</strong> р ила");<br />

h a l l w a y = n e w R o o m W i t h H i d i n g P l a c e (" В <strong>е</strong> р х н и й коридор", " к а р т и н а с собакой",<br />

"в г а р д <strong>е</strong> р о б <strong>е</strong> " ) ;<br />

b a t h r o o m = n e w R o o m W i t h H i d i n g P l a c e (" В а н н а я " ,<br />

" р а к о в и н а и туал<strong>е</strong>т",<br />

"в дущ<strong>е</strong>");<br />

m a s t e r B e d r o o m = n e w R o o m W i t h H i d i n g P l a c e (" Г л а в н а я спальня", " б о л ь щ а я кровать",<br />

"под к р о в а т ь ю " );<br />

s e c o n d B e d r o o m = n e w R o o m W i t h H i d i n g P l a c e (" В т орая спальня", " м а л <strong>е</strong> н ь к а я кровать",<br />

"под к р о в а т ь ю " );<br />

f r o n t Y a r d = n e w O u t s i d e W i t h D o o r (" л у ж а й к а " , false, " т я ж <strong>е</strong> л а я д у б о в а я д в <strong>е</strong> рь");<br />

b a c k Y a r d = n e w O u t s i d e W i t h D o o r (" З а д н и й двор", true, " с <strong>е</strong> т ч а т а я д в <strong>е</strong> рь");<br />

g a r d e n = n e w O u t s i d e W i t h H i d i n g P l a c e (" С а д " , false, "в сара<strong>е</strong>");<br />

d r i v e w a y = n e w O u t s i d e W i t h H i d i n g P l a c e (" П о д ъ <strong>е</strong> з д " , true, "в гараж<strong>е</strong>");<br />

d i n i n g R o o m . E x i t s = n e w L o c a t i o n [] { l i v ingRoom, k i t c h e n };<br />

l i v i n g R o o m . E x i t s = n e w Location[] { d i n i n g R o o m , stairs };<br />

k i t c h e n . E x i t s = n e w Location[] { d i n i n g R o o m };<br />

s t a i r s . E x i t s = n e w Location[] { livingRoom, h a l l w a y };<br />

h a l l w a y . E x i t s = n e w L o c a t i o n [] { stairs, bathroom, m a s t e r B e d r o o m , s e c o n d B e d r o o m<br />

b a t h r o o m . E x i t s = n e w L o c a t i o n [] { h a l l w a y };<br />

m a s t e r B e d r o o m . E x i t s = n e w L o c ation[] { h a l l w a y };<br />

s e c o n d B e d r o o m . E x i t s = n e w L o c a t i o n [] { h a l l w a y };<br />

f r o n t Y a r d . E x i t s = n e w L o c ation[] { backYard, garden, d r i v e w a y };<br />

b a c k Y a r d . E x i t s = n e w L o c ation[] { frontYard, garden, d r i v e w a y };<br />

g a r d e n . E x i t s = n e w Location[] { b a c kYard, f r o n t Y a r d };<br />

d r i v e w a y . E x i t s = n e w L o c ation[] { backYard, f r o n t Y a r d };<br />

l i v i n g R o o m . D o o r L o c a t i o n = f r o ntYard;<br />

f r o n t Y a r d . D o o r L o c a t i o n = livingRoom;<br />

k i t c h e n . D o o r L o c a t i o n = b a c k Y a r d ;<br />

b a c k Y a r d . D o o r L o c a t i o n = k i t chen;<br />

Новый м<strong>е</strong>тод CreateObjects() созда<strong>е</strong>т<br />

объ<strong>е</strong>кты, из которых состоит доМ-<br />

От старого м<strong>е</strong>тода он отлича<strong>е</strong>тся<br />

большим колич<strong>е</strong>ством вариантов.<br />

- Ц<strong>е</strong>р<strong>е</strong>Б<strong>е</strong>рнит<strong>е</strong> сшраниЦу и прододжим!<br />

дальш<strong>е</strong> > 335


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

н<strong>е</strong>нк<strong>е</strong><br />

)'^<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

p r i v a t e v o i d R esetG a m e(b o o l d is p la y M e s s a g e ) {<br />

i f (d isp la y M e ssa g e ) {<br />

^<br />

f<br />

Это остальной код формы. Обработчики событий<br />

кнопок доН<strong>е</strong>г<strong>е</strong> и goThroughTheDoor ид<strong>е</strong>нтичны<br />

своим собратьям из п<strong>е</strong>рвой части упражн<strong>е</strong>ния,<br />

Вы найд<strong>е</strong>т<strong>е</strong> их, в<strong>е</strong>рнувшись на н<strong>е</strong>сколько страниц<br />

назад.<br />

M essa g eB o x .S h o w ("М<strong>е</strong>ня нашли за " + M oves + " х о д о в !" );<br />

I H id in g P la c e fo u n d L o c a tio n = c u r r e n t L o c a t io n ^ ^ I H i d i n g P l a c e ;<br />

d e s c r i p t i o n .T e x t = "Соп<strong>е</strong>рник найд<strong>е</strong>н з а " + Moves<br />

+ " ходов ! Он прятался " + fo u n d L o c a t io n . H idin gP laceN am e<br />

}<br />

M oves = 0;<br />

h i d e . V i s i b l e = tr u e ;<br />

g o H e r e .V i s i b l e = f a l s e ;<br />

c h e c k .V i s i b l e = f a l s e ;<br />

g o T h r o u g h T h e D o o r .V isib le = f a l s e ;<br />

e x i t s . V i s i b l e = f a l s e ;<br />

«Hide!», н<strong>е</strong>видимыми<br />

Нам нужно отобразить имя<br />

кнопки<br />

p r i v a t e v o id c h e c k _ C lic k ( o b j e c t s e n d e r ,<br />

M oves++;<br />

i f (o p p o n e n t. C h e c k ( c u r r e n t L o c a t io n ) )<br />

R e s e tG a m e (tr u e );<br />

e l s e<br />

RedrawForm ( );<br />

}<br />

p r i v a t e v o id h i d e _ C l i c k ( o b j e c t se n d e r , E v en tA rg s e) {<br />

h i d e . V i s i b l e = f a l s e ;<br />

Кнопка check пров<strong>е</strong>ря<strong>е</strong>т, н<strong>е</strong><br />

пряч<strong>е</strong>тся ли соп<strong>е</strong>рник в комнат<strong>е</strong>,<br />

гд<strong>е</strong> вы находит<strong>е</strong>сь. При <strong>е</strong>го<br />

обнаруж<strong>е</strong>нии п<strong>е</strong>р<strong>е</strong>загружа<strong>е</strong>т<br />

игру. Н<strong>е</strong> обнаружив <strong>е</strong>го, п<strong>е</strong>р<strong>е</strong>рисовыва<strong>е</strong>т<br />

форму (чтобы обновить<br />

число ходов).<br />

f o r ( i n t i = 1; i


инт<strong>е</strong>рф<strong>е</strong>йсы и абстрактны<strong>е</strong> классы<br />

І^<strong>е</strong>іИ<strong>е</strong>ни<strong>е</strong> Б басс<strong>е</strong>йн<strong>е</strong> со с. ^ 9<br />

Вам тр<strong>е</strong>бовалось взять фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна<br />

и пом<strong>е</strong>стить их на пусты<strong>е</strong> строки таким образом,<br />

чтобы получить показанный ниж<strong>е</strong> р<strong>е</strong>зультат.<br />

К-ласс Acts вызыва<strong>е</strong>т конструктор базооого<br />

для н<strong>е</strong>го класса Picasso. Он п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т<br />

конструктору п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную Acts,<br />

которая сохраня<strong>е</strong>тся в свойств<strong>е</strong> face.<br />

}<br />

interface N ose {<br />

int ÉarO<br />

s t r i n g F ace { g e t ; }<br />

Picasso : Мот<strong>е</strong><br />

p u b l i c v i r t u a l i n t E ar()<br />

a b s t r a c t c l a s s<br />

}<br />

{<br />

r e t u r n 7;<br />

}<br />

p u b l i c P i c a s s o ( s t r i n g fa c e )<br />

this.face = f a c e ;<br />

r OHM Л<br />

p u b l i c v i r t u a l s t r i n g F ace { сб<strong>е</strong>рКЦ, HO о<br />

}<br />

get { ....retHrP.-f!“?.®<br />

___ _ ! _________ _________ . 1 ^ АЛІ<br />

s t r i n g f a c e ;<br />

c l a s s Clowns : Picasso {<br />

p u b l i c Clowns О : b a s e ( "C low ns") { }<br />

}<br />

c l a s s . Acts , : Picasso.....{<br />

p u b l i c A c t s O : b a s e ("A cts" ) { }<br />

p u b l i c o v e r r id e int EarQ {<br />

r e t u r n 5;<br />

}<br />

}<br />

c l a s s ,Pf7^..:..<br />

p u b l i c o v e r r id e s t r i n g F ace {<br />

С во й ст ва м о г у т ^ g e t { r e t u r n "Of76"; }<br />

появит ся в 1лро ^ ^ ^ s t a t i c v o i d M ain ( s t r i n g [] a r g s) {<br />

извоАШом ..ойллпиллл м<strong>е</strong>ст<strong>е</strong>й<br />

<strong>е</strong>^<br />

класса! К-оЗ прощ<strong>е</strong><br />

читать, <strong>е</strong>сли<br />

они соср<strong>е</strong>дотодаиноМ<br />

случа<strong>е</strong> Mt>i<br />

пом<strong>е</strong>стили сбоиство<br />

face в нижнюю<br />

часть класса<br />

Picasso.<br />

s t r i n g r e s u l t = "";<br />

N o s e [] i = new N o se [3 ] ;<br />

i [0] = new A c t s ( );<br />

i [1] = new Clow ns 0 ;<br />

i [ 2 ] = new Of 76 0 ;<br />

f o r ( i n t X = 0; X < 3; x++) {<br />

r e s u l t += ( ..iM-.Eqr.O........+ " "<br />

+ i[xi.Face )<br />

}<br />

M e s s a g e B o x .S h o w ( r e s u lt ) ;<br />

"\п"<br />

Face -- это м<strong>е</strong>тод записи,<br />

возвраш,аюш,ий знач<strong>е</strong>ния свойства<br />

face. И м<strong>е</strong>тод, и свойство<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ны в класс<strong>е</strong><br />

Picasso и насл<strong>е</strong>дуются производными<br />

классами.<br />

дальш<strong>е</strong> ► 337


8 п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> и Колл<strong>е</strong>кции<br />

Больши<strong>е</strong> объ<strong>е</strong>мы данных<br />

^<br />

П р и ш л а б <strong>е</strong> д а — о тв о р яй в о р о та.<br />

в р<strong>е</strong>альном мир<strong>е</strong> данны<strong>е</strong>, как правило, н<strong>е</strong> хранятся мал<strong>е</strong>нькими<br />

кусочками. Д анны <strong>е</strong> приходят вагонами, ш таб<strong>е</strong>лям и и кучами.<br />

Д ля их сист<strong>е</strong>матизации нужны м ощ ны <strong>е</strong> инструм<strong>е</strong>нты, и тут вам на<br />

пом ощ ь приходят колл<strong>е</strong>кции. О ни позволяю т хранить, сортировать<br />

и р<strong>е</strong>дактировать данны<strong>е</strong>, которы<strong>е</strong> обрабаты ва<strong>е</strong>т программа.<br />

В р<strong>е</strong>зультат<strong>е</strong> вы мож<strong>е</strong>т<strong>е</strong> соср<strong>е</strong>доточиться на основной ид<strong>е</strong><strong>е</strong><br />

программирования, оставив задачу отсл<strong>е</strong>живания данны х колл<strong>е</strong>кциям.


акула-нянюшка и плотник-мурав<strong>е</strong>й<br />

Кат<strong>е</strong>гории данных н<strong>е</strong> бс<strong>е</strong>гда мо)кно сохранять 6 п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных типа string<br />

Пр<strong>е</strong>дположим, у вас <strong>е</strong>сть н<strong>е</strong>сколько рабочих пч<strong>е</strong>л из класса<br />

Worker. Как написать конструктор, который в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра<br />

б<strong>е</strong>р<strong>е</strong>т работу? Если названия работ пом<strong>е</strong>щать в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

типа string, получится прим<strong>е</strong>рно такой код;<br />

Наш<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong> для управл<strong>е</strong>ния<br />

пч<strong>е</strong>лами оплсл<strong>е</strong>живало радоту<br />

каждой из них при помош,и строк<br />

вида Stiny Patrol или Nectar<br />

Collector.<br />

Код позволя<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дать эти<br />

знач<strong>е</strong>ния в конструктор, даж<strong>е</strong><br />

<strong>е</strong>сли программа подд<strong>е</strong>ржива<strong>е</strong>т<br />

только таки<strong>е</strong> занятия как<br />

Sting Patrol (Охранник), Nectar<br />

Collector (Сдорищк н<strong>е</strong>ктара)<br />

и други<strong>е</strong>, привычны<strong>е</strong> для пч<strong>е</strong>л<br />

варианты работы.<br />

Worker buzz = new Worker("Прокурор");<br />

Worker clover = new Worker("Кинолог");<br />

Worker gladys = new Worker("Диктор");<br />

К конструктору W orker можно добавить код, пров<strong>е</strong>ряющий<br />

корр<strong>е</strong>ктность каждой строчки. Но тогда, чтобы расширить<br />

список доступных для пч<strong>е</strong>л занятий вам прид<strong>е</strong>тся отр<strong>е</strong>дактировать<br />

данный код и п<strong>е</strong>р<strong>е</strong>компилировать класс W orker. Так что<br />

это н<strong>е</strong>дальновидно<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>. А что д<strong>е</strong>лать при наличии других<br />

классов, пров<strong>е</strong>ряющих типы работ, которы<strong>е</strong> могут выполнять<br />

рабочи<strong>е</strong> пч<strong>е</strong>лы? Вы получит<strong>е</strong> дублирующийся код, затрудняющий<br />

вашу работу.<br />

Фактич<strong>е</strong>ски нам нужно объявить: «Зд<strong>е</strong>сь могут использоваться<br />

только строго опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong> знач<strong>е</strong>ния». И п<strong>е</strong>р<strong>е</strong>числить эти<br />

знач<strong>е</strong>ния.<br />

340 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния<br />

Э т о имя п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния.<br />

enum Job {<br />

Каждая<br />

Посл<strong>е</strong> посл<strong>е</strong>дн<strong>е</strong>го NectarCollector, ^ .м ож <strong>е</strong>т бьітТв^поАиГ^<br />

^инкта списка<br />

^^чeлoй. И ви,<br />

З А іл я т у ю cm «6w m & StingPatrol,<br />

t - і c r P a t r o l . -чіС— ^<br />

< .^ ,^ л а Л і в і л а . п О<br />

ГлїХГ<strong>е</strong>"««"« HiveMaintenance,”^ знач<strong>е</strong>ния Jobs^^'^^~<br />

r » P a K f w « e S " BabyBeeTutoring,<br />

^ Е д д С а а г <strong>е</strong> ,;^ «.— ---------------------- Знач<strong>е</strong>ния разд<strong>е</strong>ляются<br />

-^HoneyManufacturing, запятыми, а 6 конц<strong>е</strong><br />

' ^ ставится фигурная скобка.<br />

} 341


им<strong>е</strong>на лучш<strong>е</strong> цифр<br />

Присвоим числам им<strong>е</strong>на<br />

Иногда удобн<strong>е</strong><strong>е</strong> работать с им<strong>е</strong>нованными числами - сопоставить их эл<strong>е</strong>м<strong>е</strong>нтам п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и обращаться<br />

к ним по им<strong>е</strong>нам. Это позволит изб<strong>е</strong>жать н<strong>е</strong>понятных цифр, разбросанных по вс<strong>е</strong>му коду. Вот<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> для оц<strong>е</strong>нки кач<strong>е</strong>ства выполн<strong>е</strong>ния собаками различных команд:<br />

Порядок сл<strong>е</strong>дования<br />

н<strong>е</strong> и м <strong>е</strong>­<br />

<strong>е</strong>т знач<strong>е</strong>ния.<br />

Кром<strong>е</strong> того,<br />

одно и то ж<strong>е</strong><br />

число можно<br />

сопоставит ь<br />

разным им<strong>е</strong><br />

намpublic<br />

enum TrickScore {<br />

^ S i t = 7,<br />

Beg = 2 5 ,<br />

Rollover = 50,<br />

Fetch = 10,<br />

ComeHere = 5,<br />

- \<br />

Speak = 30,<br />

}<br />

Вот фрагм<strong>е</strong>нт м<strong>е</strong>тода, использующ<strong>е</strong>го п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

T ric k S c o re пут<strong>е</strong>м прив<strong>е</strong>д<strong>е</strong>ния к знач<strong>е</strong>нию<br />

типа i n t и обратно:<br />

П о у м о л ч а н и ю б а з о в ы м<br />

д л я э л <strong>е</strong> м <strong>е</strong> н т о в п <strong>е</strong> р <strong>е</strong> ч и с ­<br />

л <strong>е</strong> н и я я в л я <strong>е</strong> т с я ти п int.<br />

Укажит<strong>е</strong> зат<strong>е</strong>м . \<br />

^ ЗйИА<strong>е</strong>Л1 число<br />

объявить и п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

от врт г^^а^'^° со - ' т ипа, наприм<strong>е</strong>р hyte или<br />

‘^о <strong>е</strong>т ст ву<strong>е</strong>т .<br />

как это сд<strong>е</strong>лано 6 нижн<strong>е</strong>й<br />

части страницы.<br />

Такая запись за с тавля<strong>е</strong>т к о м ­<br />

пилят ор использовать число,<br />

кот орому соот в<strong>е</strong>т ст ву<strong>е</strong>т<br />

эл<strong>е</strong>м <strong>е</strong>нт п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния. 8 данном<br />

случа<strong>е</strong> ХО.<br />

int value = (jint^rickScore.Fetch * 3;<br />

MessageBox.Show(value.ToStringO);<br />

TrickScore score = (TrickScore)value; ^<br />

MessageBox.Show(score.ToStringO);<br />

Этот оп<strong>е</strong>ратор присваива<strong>е</strong>т<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

value знач<strong>е</strong>ни<strong>е</strong> ъо.<br />

Числ<strong>е</strong>нно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> Мо<br />

ж <strong>е</strong> т быть пр<strong>е</strong>образовано<br />

обратно в эл<strong>е</strong>м<strong>е</strong>нт<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния. Так как<br />

value = З Л score п р и -<br />

сваиава<strong>е</strong>тся знач<strong>е</strong>ни<strong>е</strong><br />

T r i c k S c o r e . f e t c K С о -<br />

^...йг-иллтб<strong>е</strong>нно м<strong>е</strong>той<br />

а<br />

отб <strong>е</strong>тстб<strong>е</strong>н н о м<strong>е</strong>тис,<br />

с^л<strong>е</strong>м<strong>е</strong>нты п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния можно использовать как числа и производить с ними ^core.ToStringO возвра<br />

разнообразны<strong>е</strong> вычисл<strong>е</strong>ния, а можно воспользоваться м<strong>е</strong>тодом T o S trin g O и^а<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> Fetch,<br />

и рассматривать их как строки. При отсутствии явного присво<strong>е</strong>ния, эл<strong>е</strong>м<strong>е</strong>нты<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния получают знач<strong>е</strong>ния по умолчанию. П<strong>е</strong>рвому эл<strong>е</strong>м<strong>е</strong>нту присваива<strong>е</strong>тся<br />

О, второму —1 и т. д.<br />

342 глава 8<br />

А что д<strong>е</strong>лать, <strong>е</strong>сли нужно присвоить эл<strong>е</strong>м<strong>е</strong>нту п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния оч<strong>е</strong>нь большо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>? По умолчанию<br />

вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты принадл<strong>е</strong>жат к типу i n t , поэтому нужно пом<strong>е</strong>нять тип п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния при помощи оп<strong>е</strong>ра-<br />

тора<br />

public enum TrickScore ; long {<br />

Sit = 7,<br />

Beg = 2500000000025<br />

} Если принадл<strong>е</strong>жность эл<strong>е</strong>м<strong>е</strong>нт ов п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния к т ипу long явно<br />

н<strong>е</strong> указана, при компиляции появится сообщ<strong>е</strong>ни<strong>е</strong>:<br />

Cannot implicitly convert type 'long' to 'int'.<br />

'<br />

заставля<strong>е</strong>т<br />

компилятор относить эл<strong>е</strong>-


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

• п ^ а Ж <strong>е</strong> н и г<br />

Воспользу<strong>е</strong>мся получ<strong>е</strong>нными св<strong>е</strong>д<strong>е</strong>ниями для постро<strong>е</strong>ния класса, описывающ<strong>е</strong>го игральны<strong>е</strong><br />

карты<br />

Создайт<strong>е</strong> новый про<strong>е</strong>кт и добавьт<strong>е</strong> класс Card<br />

Вам нуж ны два откры ты х поля; S u i t ( S p a d e s , C lu b s , D ia m o n d s,<br />

H e a r t s ) и V a lu e (A ce, Two, T h r e e ...T e n , J a c k , Q u een , K in g ), a такж <strong>е</strong><br />

пр<strong>е</strong>дн азнач<strong>е</strong>нны <strong>е</strong> только для чт<strong>е</strong>ния поля Name (А с<strong>е</strong> o f S p a d e s (туз<br />

пик), F i v e o f D ia m o n d s (пят<strong>е</strong>рка буб<strong>е</strong>й )).<br />

О<br />

Задайт<strong>е</strong> Аласти и карты с помощ ью двух п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ний<br />

Воспользуйт<strong>е</strong>сь уж<strong>е</strong> знакомой вам командой A d d » Class, зам<strong>е</strong>няя слово c l a s s на enum.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что ( i n t ) S u i t s . S p a d e s = О, C lu b s = 1, D ia m o n d s = 2, a H e a r t s = 3. Bo втором<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>нии: ( i n t ) V a l u e s .А с <strong>е</strong> должно быть = 1, Two = 2, T h r e e = 3 и т. д. J a c k<br />

(вал<strong>е</strong>т) = 11, Q u e e n (дама) = 12, а K in g (король) = 13.<br />

Добавим картам свойство<br />

С вой ство Name д о ст у п н о только для чт<strong>е</strong>ни я. М <strong>е</strong>т о д ч т<strong>е</strong>н и я д о л ж <strong>е</strong>н возвращ ать строку<br />

с названи <strong>е</strong>м карты. Э то т код вы зы ва<strong>е</strong>т св о й ств о Name и о т о б р а ж а <strong>е</strong>т р<strong>е</strong>зультат:<br />

Card c a r d = new C a r d ( S u i t s . S p a d e s , V a lu e s .A c e ) ;<br />

s t r i n g cardName = card .N am e;<br />

П <strong>е</strong>р <strong>е</strong>м <strong>е</strong> н н а я ca rd N a m e д о л ж н а и м <strong>е</strong>ть зн а ч <strong>е</strong>н и <strong>е</strong> “А с <strong>е</strong> o f S p a d e s ”.<br />

4mO$fc>i э т о заработало.<br />

в класс C a rd нуж но п о ­<br />

м <strong>е</strong> т и т ь к о н с т р у к т о р<br />

с Эбумя п а р а м <strong>е</strong> т р а м и .<br />

Кнопка, отображающоя названи<strong>е</strong> случайной карты<br />

Буд<strong>е</strong>м выбирать карту, случайным образом присваивая число от О до 3 п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

S u i t s , а числа от 1 до 13 - п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной V a l u e s . Воспользу<strong>е</strong>мся встро<strong>е</strong>нным классом<br />

Random , позволяющим вызвать м<strong>е</strong>тод N e x t () тр<strong>е</strong>мя способами:<br />

В озм ож н ост ь iRandom random = new Random( );<br />

вы зы в а т ь один i n t num berBetw een0and3 = r a n d o m .N e x t(4 );<br />

M tm o d р а зн ы м и i___ n t __________________________<br />

n u m b erB etw een la n d l3 = random . N e x t (1, 14)<br />

сп особам и н а з ы a n yR an d om ln teger = random . N e x t О ; Г*”<br />

^<br />

в а <strong>е</strong>т ся п<strong>е</strong>р<strong>е</strong>груз-^<br />

ком (overloading).<br />

З д <strong>е</strong>сь случ ай н ы м о б р а зо м вы б и р а <strong>е</strong>т ся число о т г до<br />

О н<strong>е</strong>й м ы п о го в о ­<br />

р и м позж<strong>е</strong>... Часто<br />

При набор<strong>е</strong> м<strong>е</strong>тода Random. N ex t ( ) появилось ОКНО<br />

IntelliSense с надписью «3 of 3». Что это значит?<br />

Q; Вы увид<strong>е</strong>ли м<strong>е</strong>тод, который был п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>н. Возможность<br />

вызывать один м<strong>е</strong>тод н<strong>е</strong>сколькими способами называ<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>грузкой.<br />

При работ<strong>е</strong> с классом, в состав<strong>е</strong> которого присутствуют<br />

подобны<strong>е</strong> м<strong>е</strong>тоды, ИСР показыва<strong>е</strong>т вам вс<strong>е</strong> возможны<strong>е</strong> варианты.<br />

В рассматрива<strong>е</strong>мом случа<strong>е</strong> класс Random им<strong>е</strong><strong>е</strong>т три м<strong>е</strong>тода<br />

N ext ( ) . Когда вы п<strong>е</strong>чата<strong>е</strong>т<strong>е</strong> random.Next(), появля<strong>е</strong>тся окно<br />

IntelliSense с парам<strong>е</strong>трами вс<strong>е</strong>х вариантов. Сл<strong>е</strong>ва и справа<br />

З а д а в а <strong>е</strong> м ы <strong>е</strong><br />

Боцр>ос:ь1<br />

от записи «3 of 3» находятся стр<strong>е</strong>лки, которы<strong>е</strong> позволяют выбирать<br />

варианты. Это пол<strong>е</strong>зно в случаях, когда м<strong>е</strong>тод им<strong>е</strong><strong>е</strong>т<br />

множ<strong>е</strong>ство опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ний. Вам ж<strong>е</strong> важно выбрать правильный<br />

вариант м<strong>е</strong>тода N ex t () I Бол<strong>е</strong><strong>е</strong> подробно об этом мы поговорим<br />

чуть позж<strong>е</strong>.<br />

randoffi.Mextd<br />

_____________ _____ ___________________ __<br />

Rando«,H€Xt(int siinValue, int maxValue)<br />

Returns 3 random number within з specified range.<br />

minValue; The mdusim lower bound cfthemnilannartierr^umed.<br />

дальш<strong>е</strong> ► 343


массивы... ному они нужны?<br />

^ажн<strong>е</strong>ни<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

enum S u i t s {<br />

Колода карт позволя<strong>е</strong>т проиллюстрировать важность огранич<strong>е</strong>ния знач<strong>е</strong>ний. Было бы<br />

странно обнаружить джок<strong>е</strong>ра кр<strong>е</strong>ст<strong>е</strong>й или 13 ч<strong>е</strong>рв<strong>е</strong>й. Вот как выглядит код класса Card.<br />

}<br />

D iam ond s, \<br />

H e a r ts<br />

к <strong>е</strong>динщ<strong>е</strong>, тр<strong>е</strong>тий к двойк<strong>е</strong> и т. д.<br />

В данном случа<strong>е</strong> знач<strong>е</strong>ния по<br />

умолчанию п<strong>е</strong>р<strong>е</strong>опр<strong>е</strong>д<strong>е</strong>ляются<br />

и \/


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Создать колоду карт мо)кно было при помои^и массиба..<br />

Как создать класс, пр<strong>е</strong>дставляющий собой колоду карт? Нужно<br />

отсл<strong>е</strong>живать каждую карту в колод<strong>е</strong> и их порядок. Данная задача<br />

р<strong>е</strong>ша<strong>е</strong>тся при помощи массива Card: п<strong>е</strong>рвой карт<strong>е</strong> присваива<strong>е</strong>тся<br />

знач<strong>е</strong>ни<strong>е</strong> О, сл<strong>е</strong>дующ<strong>е</strong>й — 1 и т. д. Отправной точкой сд<strong>е</strong>ла<strong>е</strong>м<br />

класс Deck, описывающий полную колоду (52 карты).<br />

class Deck {<br />

private Card[] cards = {<br />

new Card(Suits-Spades, Values.Ace),<br />

new Card (Suits. Spades, Values .Two) ,<br />

new C a r d ( S u i t s .Spades, V a l u e s .T h r e e ) ,<br />

/ / . . .<br />

new Card(Suits.Diamonds, V a l u e s .Q u e e n ) ,<br />

n e w Card(Suits.Diamonds, V a l u e s .K i n g ) ,<br />

Объявл<strong>е</strong>ни<strong>е</strong> массива<br />

сокращ<strong>е</strong>но для<br />

экономии м<strong>е</strong>ста на<br />

^^Раниц<strong>е</strong>. Но зд<strong>е</strong>сь<br />

^^<strong>е</strong>числ<strong>е</strong>нь, вс<strong>е</strong><br />

5^2 карты в колод<strong>е</strong>.<br />

public void P r i n t C a r d s O {<br />

for (int 1 = 0; i < cards .Length; i-i--i-;<br />

}<br />

C o n s o l e . W r i t e L i n e ( c a r d s [ i ] . N a m e ()]<br />

... но что <strong>е</strong>сли бам захоч<strong>е</strong>тся больш<strong>е</strong>го?<br />

Пр<strong>е</strong>дставьт<strong>е</strong> вс<strong>е</strong>, что можно д<strong>е</strong>лать с карточной колодой. Наприм<strong>е</strong>р,<br />

для мод<strong>е</strong>лирования игры нужно м<strong>е</strong>нять порядок карт, а такж<strong>е</strong><br />

добавлять их в колоду и убирать из н<strong>е</strong><strong>е</strong>. Эти задачи уж<strong>е</strong> н<strong>е</strong> р<strong>е</strong>шить<br />

при помощи массива.<br />

ШТУРМ<br />

Как бы вы добавили м<strong>е</strong>тод s h u f f l e О , мод<strong>е</strong>лирующ ий проц<strong>е</strong>сс тасования<br />

колоды ? Как смод<strong>е</strong>лировать проц<strong>е</strong>сс сдачи кар т? Каким образом<br />

добавить карты в колоду?<br />

дальш<strong>е</strong> > 345


пр<strong>е</strong>дм<strong>е</strong>ты колл<strong>е</strong>кционирования<br />

Пробл<strong>е</strong>мы работы с массивами<br />

Массивы пр<strong>е</strong>красно подходят для хран<strong>е</strong>ния фиксированного списка знач<strong>е</strong>ний или ссылок. Но как только<br />

возника<strong>е</strong>т н<strong>е</strong>обходимость пом<strong>е</strong>нять эл<strong>е</strong>м<strong>е</strong>нты м<strong>е</strong>стами или добавить новы<strong>е</strong> знач<strong>е</strong>ния, ситуация осложня<strong>е</strong>тся.<br />

Каждый массив им<strong>е</strong><strong>е</strong>т длину, которую вы должны знать. Для получ<strong>е</strong>ния пустых<br />

эл<strong>е</strong>м<strong>е</strong>нтов можно воспользоваться ссылкой на н<strong>е</strong>опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> null:<br />

П а р а м <strong>е</strong> т р L en g th э т о ­<br />

го м а сси ва р а в<strong>е</strong>н 7, но<br />

в н <strong>е</strong>м х р а н и т ся и н ф о р ­<br />

м аци я т о л ьк о о т р <strong>е</strong> х<br />

к а р т а х .<br />

О<br />

Чтобы отсл<strong>е</strong>дить колич<strong>е</strong>ство им<strong>е</strong>ющихся карт, создадим пол<strong>е</strong> t o p C a r d типа<br />

i n t для хран<strong>е</strong>ния информации об инд<strong>е</strong>кс<strong>е</strong> посл<strong>е</strong>дн<strong>е</strong>й карты. Парам<strong>е</strong>тр L e n g t h<br />

наш<strong>е</strong>го массива им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> 7, в то вр<strong>е</strong>мя как t o p C a r d равно 3.<br />

^ m L о т сл <strong>е</strong>ж и ва <strong>е</strong>т к о л и ч <strong>е</strong>-<br />

c ^ H d S Z ,<br />

эл <strong>е</strong> м <strong>е</strong> н т ы<br />

с сы л а ю т ся на знач<strong>е</strong>ни<strong>е</strong> null.<br />

о<br />

Можно добавить м<strong>е</strong>тод Р <strong>е</strong> <strong>е</strong> к {), возвращающий ссылку на в<strong>е</strong>рхнюю карту, сымитировав<br />

взяти<strong>е</strong> в<strong>е</strong>рхн<strong>е</strong>й карты из колоды. А как добавить карту? Если парам<strong>е</strong>тр<br />

t o p C a r d м<strong>е</strong>ньш<strong>е</strong> длины массива, карта добавля<strong>е</strong>тся в массив, а знач<strong>е</strong>ни<strong>е</strong><br />

t o p C a r d ув<strong>е</strong>личива<strong>е</strong>тся на 1. В противном случа<strong>е</strong> нужно создать новый, больший<br />

массив и скопировать туда им<strong>е</strong>ющи<strong>е</strong>ся карты. Удаляя"кЕфтуГвы вычита<strong>е</strong>т<strong>е</strong>'<br />

1 из to p C ard и возвраща<strong>е</strong>т<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нту массива знач<strong>е</strong>ни<strong>е</strong> null. А как удалить карту<br />

из с<strong>е</strong>р<strong>е</strong>дины? Посл<strong>е</strong> удал<strong>е</strong>ния карты 4 нужно см<strong>е</strong>стить вниз карту 5, зат<strong>е</strong>м<br />

карту 6 и т. д.<br />

Это мож<strong>е</strong>т сд<strong>е</strong>лать<br />

встро<strong>е</strong>нный м<strong>е</strong>тод<br />

.NET A rray.R esizeQ .<br />

346 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Колл<strong>е</strong>кции<br />

в .NET Framework сущ<strong>е</strong>ству<strong>е</strong>т множ<strong>е</strong>ство классов колл<strong>е</strong>кций (collection), позволяющих л<strong>е</strong>гко р<strong>е</strong>шить<br />

вопросы с добавл<strong>е</strong>ни<strong>е</strong>м и удал<strong>е</strong>ни<strong>е</strong>м эл<strong>е</strong>м<strong>е</strong>нтов массива. Чащ<strong>е</strong> вс<strong>е</strong>го использу<strong>е</strong>тся колл<strong>е</strong>кция L ist.<br />

L ist< T > позволя<strong>е</strong>т л<strong>е</strong>гко добавить, удалить, выбрать эл<strong>е</strong>м<strong>е</strong>нт и даж<strong>е</strong> пом<strong>е</strong>нять порядок сл<strong>е</strong>дования<br />

эл<strong>е</strong>м<strong>е</strong>нтов.<br />

О<br />

Н ачн<strong>е</strong>м с создания нового экз<strong>е</strong>мпляра List<br />

Колл<strong>е</strong>кции, как и массивы, принадл<strong>е</strong>жат к опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нному типу. Тип объ<strong>е</strong>ктов<br />

или знач<strong>е</strong>ний, которы<strong>е</strong> должны там храниться, указыва<strong>е</strong>тся в мом<strong>е</strong>нт созда- Иногда для<br />

ния колл<strong>е</strong>кции в угловых скобках о с помощью оп<strong>е</strong>ратора new. ста^(^упро -<br />

L ist< C a rd > c a r d s = new L ist< C a rd > {)<br />

Tun был указан<br />

в мом<strong>е</strong>нт создания<br />

колл<strong>е</strong>кции, так что<br />

т<strong>е</strong>п<strong>е</strong>рь там хранятся<br />

только ссылки на объ<strong>е</strong>кты<br />

типа Card.<br />

Символ указыва<strong>е</strong>т на<br />

обобщ<strong>е</strong>нную колл<strong>е</strong>кцию.<br />

щ<strong>е</strong>ния код <br />

буд<strong>е</strong>т опу­<br />

скаться-<br />

Символ Т зам<strong>е</strong>ня<strong>е</strong>тся типом,<br />

L is t< in t> означа<strong>е</strong>т L i s t знач<strong>е</strong>ний<br />

типа in t.<br />

Добавл<strong>е</strong>ни<strong>е</strong> в колл<strong>е</strong>кц ию List<br />

В колл<strong>е</strong>кцию L ist< T > можно добавить произвольно<strong>е</strong> колич<strong>е</strong>ство эл<strong>е</strong>м<strong>е</strong>нтов<br />

(главно<strong>е</strong>, чтобы они были полиморфны с типом указанным при создании<br />

^ ^ ^ L ist< T > ).<br />

Они могут ca rd s.A d d (n e w C a r d (S u its.D ia m o n d s , V a l u e s .K in g ) ;<br />

быть Card ( S u i t s , c lu b s . V a lu e s .T h ree) ;<br />

инт<strong>е</strong>рф<strong>е</strong>йсам,<br />

абстрактным c a rd s.A d d (n e w C a r d ( S u it s .H e a r t s , V a l u e s . A c e ) ;<br />

классам, базовым<br />

классам<br />

к<br />

и т. п. /<br />

В колл<strong>е</strong>кцию List можно<br />

добавить произвольно<strong>е</strong><br />

число карт, достаточно<br />

воспользоваться м<strong>е</strong>тодом<br />

AddQ. Если колич<strong>е</strong>ство<br />

объ<strong>е</strong>ктов пр<strong>е</strong>выила<strong>е</strong>т колич<strong>е</strong>ство<br />

свободных м<strong>е</strong>ст,<br />

разм<strong>е</strong>р колл<strong>е</strong>кции ув<strong>е</strong>личива<strong>е</strong>тся.<br />

в колл<strong>е</strong>кции, как<br />

и в массив<strong>е</strong>, эл<strong>е</strong>м<strong>е</strong>нты<br />

хранятся в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нном<br />

порядк<strong>е</strong>. Сначала<br />

король буб<strong>е</strong>й, зат<strong>е</strong>м<br />

тройка кр<strong>е</strong>ст<strong>е</strong>й и посл<strong>е</strong>дним<br />

— т у з ч<strong>е</strong>рв<strong>е</strong>й.<br />

^<strong>е</strong>нт<br />

дальш<strong>е</strong> > 347


какой прогр<strong>е</strong>сс!<br />

Колл<strong>е</strong>кции List<br />

lOiacc L i s t встро<strong>е</strong>н в .NET Framework и позволя<strong>е</strong>т д<strong>е</strong>лать в<strong>е</strong>щи,<br />

о которых вы н<strong>е</strong> могли даж<strong>е</strong> м<strong>е</strong>чтать, им<strong>е</strong>я в арс<strong>е</strong>нал<strong>е</strong> только стары<strong>е</strong><br />

добры<strong>е</strong> массивы. П<strong>е</strong>р<strong>е</strong>числим новы<strong>е</strong> возможности:<br />

О М ож но создать колл<strong>е</strong>кц ию<br />

L i s t < E g g > m y C a r to n = n ew L i s t < E g g > ( ) ;<br />

List 6<br />

^ g объ<strong>е</strong>кт<strong>е</strong><br />

о Добавить в н<strong>е</strong><strong>е</strong> объ<strong>е</strong>кт<br />

E g g X = n ew E g g ( ) ;<br />

m y C a r t o n . A d d ( x ) ;<br />

©<br />

Т<strong>е</strong>п<strong>е</strong>рь в ко л л <strong>е</strong> кц и и<br />

им<strong>е</strong><strong>е</strong>тся объ<strong>е</strong>кт В 3 3 -<br />

О Добавить <strong>е</strong>щ <strong>е</strong> один объ<strong>е</strong>кт<br />

E g g у = new E g g {);<br />

m yC arton.A dd(у);<br />

Узнать колич<strong>е</strong>ство объ<strong>е</strong>ктов в колл<strong>е</strong>кции<br />

©<br />

i n t t h e S i z e = m y C a r t o n .C o u n t ;<br />

ув<strong>е</strong>личива<strong>е</strong>тся<br />

принят ь ^<br />

0


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Возьми в руку карандаш<br />

Заполнит<strong>е</strong> таблицу, св<strong>е</strong>ряясь с располож<strong>е</strong>нным сл<strong>е</strong>ва кодом. Вам нужно<br />

показать, как выгляд<strong>е</strong>л бы код, <strong>е</strong>сли бы вм<strong>е</strong>сто колл<strong>е</strong>кции использовался<br />

массив. Мы н<strong>е</strong> ожида<strong>е</strong>м от вас 100% правильных р<strong>е</strong>зультатов, просто попытайт<strong>е</strong>сь<br />

догадаться.<br />

Пр<strong>е</strong>дположим, ч т о эти<br />

оп<strong>е</strong>раторы выполняются<br />

по порядку.<br />

\ Колл<strong>е</strong>кция<br />

L is t < S t r in g > m y L ist =<br />

new L i s t < S t r in g > ( ) ;<br />

Мы начали выполнять<br />

упражн<strong>е</strong>ни<strong>е</strong>...<br />

N /<br />

Обычный массив<br />

S tr in g и m y L is t = n e w S tn n g [Z ];<br />

S t r i n g a = "Yay!"; S tr in g a = " У д у /” ;<br />

m y L is t .A d d ( a ) ;<br />

S t r i n g b = "Bummer"; S tr in g b = ''B u m m e r ”;<br />

m y L is t .A d d ( b ) ;<br />

i n t t h e S i z e = m y L ist.C o u n t;<br />

Guy о = m y L is t [1 ];<br />

b o o l i s I n = m y L i s t .C o n t a i n s ( b ) ;<br />

Подсказка: П от р<strong>е</strong>бу<strong>е</strong>тся<br />

бол<strong>е</strong><strong>е</strong> одной<br />

строки кода.<br />

дальш<strong>е</strong> > 349


один разм<strong>е</strong>р для вс<strong>е</strong>го<br />

щЫьт в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Итак, вот как выглядит правильный вариант кода с использовани<strong>е</strong>м<br />

вм<strong>е</strong>сто колл<strong>е</strong>кций обычных массивов.<br />

Колл<strong>е</strong>кция<br />

L is t < S t r in g > m y L ist =<br />

new L i s t < S t r in g > { ) ;<br />

Обычный массив<br />

String [] myList = new String [2];<br />

S t r i n g a = "Yay!"<br />

m y L is t .A d d ( a ) ;<br />

String a = "Yay!";<br />

m y L i s t [ 0 ] = aj<br />

S t r i n g b = "Bummer";<br />

m y L is t .A d d ( b ) ;<br />

string b = "Bummer";<br />

m y L i s t [ l ] = b;<br />

i n t t h e S i z e = m y L is t . C o u n t;<br />

i n t t h e S i z e - m y L i St. L e n g th ;<br />

Guy o = m y L is t [1 ];<br />

G u y 0 - m y L i s t [ l ] ;<br />

b o o l i s i n = m y L is t . C o n t a in s ( b );<br />

b o o l isin = false;<br />

f o r ( i n t i ■= O; i < m y L is t.<br />

L e n g th ; (V+) {<br />

if ( b == m y L i s t [ i] ) {<br />

isin = tr u e ;<br />

Колл<strong>е</strong>кции используют м<strong>е</strong>тоды, как и уж<strong>е</strong> знакомы<strong>е</strong><br />

вам классы. Чтобы увид<strong>е</strong>ть список доступных<br />

м<strong>е</strong>тодов, вв<strong>е</strong>дит<strong>е</strong> . посл<strong>е</strong> им<strong>е</strong>ни L is t.<br />

Парам<strong>е</strong>тры м<strong>е</strong>тодам п<strong>е</strong>р<strong>е</strong>даются так ж<strong>е</strong>, как<br />

это д<strong>е</strong>лалось для созданных вами классов.<br />

Массивы довольно сильно вас ограничивают.<br />

В мом<strong>е</strong>нт создания массива тр<strong>е</strong>бу<strong>е</strong>тся указать<br />

<strong>е</strong>го разм<strong>е</strong>р, а код для нужных проц<strong>е</strong>дур приходится<br />

писать вручную.<br />

/К<br />

в .NET Fmmework сущ<strong>е</strong>ству<strong>е</strong>м<br />

класс Array, упрощающий н<strong>е</strong>которы<strong>е</strong><br />

оп<strong>е</strong>рации, но колл<strong>е</strong>кции вс<strong>е</strong> равно дол<strong>е</strong><strong>е</strong><br />

просты в использовании, поэтому мы<br />

сконц<strong>е</strong>нтриру<strong>е</strong>мся в основном на них.<br />

350 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Динамич<strong>е</strong>ско<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> разм<strong>е</strong>ров<br />

.у п р а ж н <strong>е</strong> н и <strong>е</strong> ! ^<br />

в мом<strong>е</strong>нт создания колл<strong>е</strong>кции вы н<strong>е</strong> указыва<strong>е</strong>т<strong>е</strong> информацию о <strong>е</strong><strong>е</strong> длин<strong>е</strong>.<br />

Она раст<strong>е</strong>т или сжима<strong>е</strong>тся в соотв<strong>е</strong>тствии с колич<strong>е</strong>ством объ<strong>е</strong>ктов внутри.<br />

Рассмотрим это на прим<strong>е</strong>р<strong>е</strong>. С о з д а й т <strong>е</strong> к о н с о л ь н о <strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> и добавьт<strong>е</strong><br />

код в м<strong>е</strong>тод Main (). Мы буд<strong>е</strong>м и с п о л ь з о в а т ь о т л а д ч и к для пошагового просмотра<br />

кода и отсл<strong>е</strong>живания происходяш;<strong>е</strong>го.<br />

L ist< S h o e > s h o e C lo s e t = new L ist< S h o e > {<br />

s h o e C lo s e t .Add (new S h o eO<br />

{ S t y l e = S t y l e . S n e a k e r s, C o lo r =<br />

s h o e C lo s e t .Add (new S h o eO<br />

Ч<strong>е</strong>рный" } ) ; ^<br />

{ S t y l e = S t y l e .C l o g s , C o lo r = "Коричн<strong>е</strong>вый ' } ) ;<br />

s h o e C lo s e t .Add (new S h o eO<br />

{ S t y l e = S t y l e .W i n g t i p s , C o lo r = "Ч<strong>е</strong>рный"<br />

s h o e C lo s e t .Add (new S h o eO<br />

{ S t y l e = S t y l e .L o a f e r s , C o lo r = "Б<strong>е</strong>лый" } ) ;<br />

s h o e C lo s e t .Add (new S h o eO<br />

{ S t y l e = S t y l e .L o a f e r s , C o lo r = "Красный" } ) ;<br />

s h o e C lo s e t .Add (new S h o eO<br />

});<br />

{ S t y l e = S t y l e . S n e a k e r s, C o lo r = "З<strong>е</strong>л<strong>е</strong>ный" } ) ;<br />

i n t num berO fShoes = s h o e C l o s e t . C o u n t;<br />

(fo r e a c h (Shoe sh o e i n sh o e C lo se 'O ' {<br />

}<br />

s h o e . S t y l e = S t y l e . F l i p f l o p s ;<br />

s h o e . C o lo r = "Оранж<strong>е</strong>вый"<br />

М<strong>е</strong>тод RemoveQ удаля<strong>е</strong>т<br />

объ<strong>е</strong>кт по ссылк<strong>е</strong>, м<strong>е</strong>тод — ^<br />

RemoveAtQ — по инд<strong>е</strong>ксу. ^<br />

s h o e C l o s e t . R em oveA t(4)<br />

Shoe th ir d S h o e = s h o e C lo s e t [3 ];<br />

Shoe se co n d S h o e = s h o e C lo s e t [2 ];<br />

s h o e C l o s e t . C l e a r ( );<br />

s h o e C lo s e t .A d d ( t h ir d S h o e ) ;<br />

i f ( s h o e C lo s e t .C o n t a in s ( s e c o n d S h o e ) )<br />

' C o n s o le . W r it e L in e ( "У дивит<strong>е</strong>льно!"<br />

Возвраща<strong>е</strong>т число<br />

^ объ<strong>е</strong>ктов Shoe<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>нии.<br />

Цикл foreach<br />

просматрива<strong>е</strong>т<br />

всю обувь в шкафу.<br />

М<strong>е</strong>тод ClearQ<br />

удаля<strong>е</strong>т из<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния вс<strong>е</strong><br />

объ<strong>е</strong>кты.<br />

До удал<strong>е</strong>ния в<strong>е</strong><strong>е</strong>к<br />

эл<strong>е</strong>м<strong>е</strong>нтов п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния<br />

мы сохранили<br />

дв<strong>е</strong> ссылки на обувь.<br />

Одна из них была возоращ<strong>е</strong>на,<br />

а вторая ~<br />

н<strong>е</strong>т.<br />

Эта строчка н<strong>е</strong> буд<strong>е</strong>т запускаться, потому что м<strong>е</strong>тод ContalnsQ<br />

возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> false. В пусто<strong>е</strong> п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> мы добавили<br />

только эл<strong>е</strong>м<strong>е</strong>нт thirdShoe, но н<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт fifthShoe.<br />

объявля<strong>е</strong>м колл<strong>е</strong>к-<br />

Shoe<br />

(ОдувнойШ каф).<br />

Оп<strong>е</strong>ратор new можно<br />

использовать внутри<br />

м<strong>е</strong>тода List-AddQ.<br />

J<br />

f o r e a c h — это сп<strong>е</strong>циальны й<br />

цикл, работаю щ ий с колл<strong>е</strong>кциям<br />

и. Он использу<strong>е</strong>т оп<strong>е</strong>раторы<br />

для каж дого эл<strong>е</strong>м <strong>е</strong>нта<br />

колл<strong>е</strong>кции. В данном случа<strong>е</strong><br />

созда<strong>е</strong>тся ид<strong>е</strong>нтиф икатор<br />

с им<strong>е</strong>н<strong>е</strong>м shoe, которому<br />

присваиваю тся эл<strong>е</strong>м<strong>е</strong>нты<br />

колл<strong>е</strong>кции по оч<strong>е</strong>р<strong>е</strong>ди.<br />

7<br />

Цикл foreach работа<strong>е</strong>т<br />

и с массивами тож<strong>е</strong>.<br />

Это класс Shoe<br />

и п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> Style.<br />

c l a s s S h o e ^<br />

}<br />

p u b l i c S t y l e S t y l e ;<br />

p u b lic s t r i n g C o lo r;<br />

enum S t y l e {<br />

}<br />

S n e a k e r s,<br />

L o a fe r s ,<br />

S a n d a ls,<br />

F l i p f l o p s ,<br />

W in g t ip s ,<br />

C lo g s,<br />

дальш<strong>е</strong> > 351


привил<strong>е</strong>гии чл<strong>е</strong>нства<br />

Обобщ<strong>е</strong>нны<strong>е</strong> колл<strong>е</strong>кции<br />

Вы уж<strong>е</strong> вид<strong>е</strong>ли, что колл<strong>е</strong>кция мож<strong>е</strong>т состоять как из<br />

строк, так и из ботинок. Можно пом<strong>е</strong>стить туда ц<strong>е</strong>лы<strong>е</strong><br />

числа или произвольны<strong>е</strong> созданны<strong>е</strong> вами объ<strong>е</strong>кты.<br />

Им<strong>е</strong>нно поэтому класс L i s t явля<strong>е</strong>тся обобщ <strong>е</strong>нной<br />

колл<strong>е</strong>кци<strong>е</strong>й. В мом<strong>е</strong>нт <strong>е</strong>го создания нужно указать<br />

тип знач<strong>е</strong>ний, которы<strong>е</strong> могут храниться внутри.<br />

Эта запись н<strong>е</strong> означа<strong>е</strong>т, что вы добавля<strong>е</strong>т<strong>е</strong> букву Т.<br />

Она вс<strong>е</strong>го лииль показыва<strong>е</strong>т, что класс или инт <strong>е</strong>рф<strong>е</strong>йс<br />

мож<strong>е</strong>т работать со знач<strong>е</strong>ниями любого типа,<br />

(достаточно указать этот тип в скобках). Запись<br />

List означа<strong>е</strong>т, что колл<strong>е</strong>кция сод<strong>е</strong>ржит<br />

только эл<strong>е</strong>м<strong>е</strong>нты класса Shoe.<br />

_<br />

List name = new List()<br />

Класс<br />

KUM (^озволяю<br />

List<br />

и^м людш m<br />

оч<strong>е</strong>нь<br />

^ Т м о Т у т ^ а с с и в ы (плюс eu,e ко<strong>е</strong>-что).<br />

В .NET Framework сущ<strong>е</strong>ствуют обобщ<strong>е</strong>нны<strong>е</strong> инт<strong>е</strong>р)-<br />

ф<strong>е</strong>йсы, позволяющи<strong>е</strong> созданным вами колл<strong>е</strong>кциям<br />

работать с любыми типами. Класс L i s t р<strong>е</strong>ализу<strong>е</strong>т<br />

эти инт<strong>е</strong>рф<strong>е</strong>йсы, им<strong>е</strong>нно поэтому работа с колл<strong>е</strong>кци<strong>е</strong>й<br />

ц<strong>е</strong>лых чис<strong>е</strong>л практич<strong>е</strong>ски н<strong>е</strong> отлича<strong>е</strong>тся от работы<br />

с колл<strong>е</strong>кци<strong>е</strong>й объ<strong>е</strong>ктов класса Shoe.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь самостоят<strong>е</strong>льно. Наб<strong>е</strong>рит<strong>е</strong> L i s t в ИСР,<br />

щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши и выб<strong>е</strong>рит<strong>е</strong> команду<br />

Go То Définition. Вы увидит<strong>е</strong> объявл<strong>е</strong>ни<strong>е</strong><br />

класса L i s t . Он р<strong>е</strong>ализу<strong>е</strong>т н<strong>е</strong>сколько инт<strong>е</strong>рф<strong>е</strong>йсов:<br />

Отсюда б<strong>е</strong>рутся<br />

м<strong>е</strong>тоды RemoveAtÇj,<br />

IndexOfO w InsertQ.<br />

c l a s s L i s t < ' ^ :<br />

^ C o l 1 e с t io n < T > b<br />

fL ist< T ^ ^<br />

ÊEnum eraEXë> I L i s t ,<br />

Г I C o l l e c t i o n , l E n u m e r a b le ^<br />

0 означа<strong>е</strong>т, что в<br />

колл<strong>е</strong>кции L i s t могут храниться только<br />

объ<strong>е</strong>кгы класса F ro g .<br />

М<strong>е</strong>тод In d e x O f () опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т инд<strong>е</strong>кс<br />

для заданного объ<strong>е</strong>кта.<br />

Узнать колич<strong>е</strong>ство эл<strong>е</strong>м<strong>е</strong>нтов класса L i s t<br />

можно при помощи свойства Count.<br />

М<strong>е</strong>тод C o n t a in s () пров<strong>е</strong>ря<strong>е</strong>т<br />

колл<strong>е</strong>кцию на наличи<strong>е</strong> объ<strong>е</strong>ктов.<br />

fo r e a c h — это цикл, п<strong>е</strong>р<strong>е</strong>бирающий<br />

эл<strong>е</strong>м<strong>е</strong>нты колл<strong>е</strong>кции и выполняющий<br />

для каждого указанный код. Его<br />

синтаксис: fo r e a c h ( s t r i n g s<br />

i n S t r i n g L i s t ) . Вам н<strong>е</strong> нужно<br />

заботиться об инкр<strong>е</strong>м<strong>е</strong>нтном ув<strong>е</strong>лич<strong>е</strong>нии<br />

на <strong>е</strong>диницу, п<strong>е</strong>р<strong>е</strong>бор эл<strong>е</strong>м<strong>е</strong>нтов колл<strong>е</strong>кции<br />

выполня<strong>е</strong>тся автоматич<strong>е</strong>ски.<br />

352 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

| ^ а Г н и т ь 1 С К о Д » М<br />

В осп ользуй т<strong>е</strong> сь ф рагм <strong>е</strong>нтам и кода<br />

для р<strong>е</strong>конструкции ф орм ы с кнопкой,<br />

наж ати<strong>е</strong> которой буд<strong>е</strong>т вы вод и ть показанно<strong>е</strong><br />

ниж<strong>е</strong> окно с сообщ <strong>е</strong>ни<strong>е</strong>м .<br />

a.RemoveAt(2);<br />

List ^^^ie^List<br />

private void buttonl_Click(object<br />

sender, EventArgs e ) {<br />

p u b l i c v o i d p r i n t L ( L i s t < s t r i n q > a ) ( 1<br />

if (a.Contains("two")) {<br />

a.Add(twopointtwo) ;<br />

a . A d d ( f i r s t ) ;<br />

a . A d d ( s e c o n d ) ;<br />

a.Add(third)_;^______<br />

..- ...........г<strong>е</strong>зи 1Г Т ~ ^Г Г Г ~ |<br />

if (a.Contains ("three") ){ Iswu^l<br />

-1 _T / w ^ ____ \ -<br />

a.Add("four");<br />

}<br />

{<br />

r e s u l t<br />

i n a)<br />

MessageBox.Show(result:<br />

(a.indexOf("four") ГГ"<br />

^ a.Add(fourth);<br />

zero<br />

one<br />

three<br />

four<br />

42<br />

li^ 5 5<br />

I OK 1<br />

[ p r i ^ t L T ^<br />

string zilch = "zero";<br />

string first = "one";<br />

string second = "two";<br />

string third = "three";<br />

string fourth = "4.2";<br />

string twopointtwo = "2.2";<br />

дальш<strong>е</strong> ► 353


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

l^e^eHue 5аДаЧи<br />

с МаГнищаМи<br />

Помнит<strong>е</strong>, в глав<strong>е</strong> 3 говорилось об интуитивно<br />

понятны х им <strong>е</strong>нах? С <strong>е</strong>йчас мы их сознат<strong>е</strong>л<br />

ьно изб<strong>е</strong>га<strong>е</strong>м, так как это слиш ком<br />

уп рощ а<strong>е</strong>т р<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong> р<strong>е</strong>буса. Но в ж изни таки<strong>е</strong><br />

им<strong>е</strong>на, как рпп1Ь(), использовать н<strong>е</strong> стоит!<br />

private void buttonl_Click(object sender, EventArgs e)<br />

{<br />

List а = new List<br />

zero<br />

one<br />

three<br />

four<br />

4.2<br />

OK<br />

string zilch = "zero";<br />

string first = "one";<br />

string second = "two";<br />

string third = "three";<br />

string fourth = "4.2";<br />

string twopointtwo = "2.2";<br />

W W 'fi'r"'""<br />

a . Add(second) ;<br />

- ------ I<br />

if (a.Contains("three")){<br />

a.Add("four");<br />

}<br />

Sb/ понима<strong>е</strong>т<strong>е</strong>,<br />

поч<strong>е</strong>му « z .z »<br />

никогда н<strong>е</strong> попад<strong>е</strong>т<br />

в колл<strong>е</strong>кцию.<br />

н<strong>е</strong>смотря<br />

на то что<br />

этот эл<strong>е</strong>м<strong>е</strong>нт<br />

оыл объявл<strong>е</strong>н?<br />

Memo? RemoveAtQ<br />

удаля<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нт,<br />

сл<strong>е</strong>дующий за эл<strong>е</strong>м<strong>е</strong>нтом<br />

То <strong>е</strong>сть<br />

тр<strong>е</strong>тий эл<strong>е</strong>м<strong>е</strong>нт<br />

колл<strong>е</strong>кции.<br />

if (a.IndexOf("four") i=<br />

4) {<br />

a.Add(fourth);<br />

}<br />

М<strong>е</strong>тод printLQ использу<strong>е</strong>т<br />

цикл<br />

foreach для просмотра<br />

колл<strong>е</strong>кции<br />

строк, добавл<strong>е</strong>ния<br />

каждого эл<strong>е</strong>м<strong>е</strong>нта<br />

общую строку ы<br />

отображ<strong>е</strong>ния р<strong>е</strong>зультата<br />

8 окн<strong>е</strong> диалога.<br />

Цикл foreach<br />

по оч<strong>е</strong>р<strong>е</strong>ди<br />

отобража<strong>е</strong>т<br />

вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

колл<strong>е</strong>кции.<br />

public void printL (List


Разв<strong>е</strong> п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и класс L i s t<br />

ВЫ1 выполняют н<strong>е</strong> одну и ту ж<strong>е</strong> задачу?<br />

0^<br />

I Основным и главным отличи<strong>е</strong>м<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ний явля<strong>е</strong>тся то, что они относятся<br />

к типам, в то вр<strong>е</strong>мя как колл<strong>е</strong>кции<br />

L i s t — это объ<strong>е</strong>кты.<br />

П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> явля<strong>е</strong>тся удобным<br />

способом хран<strong>е</strong>ния списков констант,<br />

дающим возможность обращаться к ним<br />

по им<strong>е</strong>ни. П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния ув<strong>е</strong>личивают читаб<strong>е</strong>льность<br />

кода и гарантируют ислользовани<strong>е</strong><br />

корр<strong>е</strong>ктных им<strong>е</strong>н для доступа<br />

к нужным вам знач<strong>е</strong>ниям.<br />

В колл<strong>е</strong>кцию L i s t можно записать практич<strong>е</strong>ски<br />

вс<strong>е</strong>. Так как р<strong>е</strong>чь ид<strong>е</strong>т о списк<strong>е</strong><br />

объ<strong>е</strong>ктов, каждый эл<strong>е</strong>м<strong>е</strong>нт мож<strong>е</strong>т им<strong>е</strong>ть<br />

собств<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды и свойства. П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ниям<br />

ж<strong>е</strong> можно назначать только<br />

значимы<strong>е</strong> типы (наприм<strong>е</strong>р, из п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>нных<br />

в начал<strong>е</strong> главы 4), хранить в них<br />

ссылочны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> н<strong>е</strong>льзя.<br />

П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния н<strong>е</strong> могут динамич<strong>е</strong>ски м<strong>е</strong>нять<br />

разм<strong>е</strong>р. Они н<strong>е</strong> р<strong>е</strong>ализуют инт<strong>е</strong>рф<strong>е</strong>йсов,<br />

н<strong>е</strong> им<strong>е</strong>ют м<strong>е</strong>тодов, а для сохран<strong>е</strong>ния<br />

знач<strong>е</strong>ния из п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

другого типа потр<strong>е</strong>бу<strong>е</strong>тся оп<strong>е</strong>рация прив<strong>е</strong>д<strong>е</strong>ния.<br />

Как видит<strong>е</strong>, это разны<strong>е</strong> способы<br />

хран<strong>е</strong>ния данных.<br />

Зач<strong>е</strong>м при таком мощном инструм<strong>е</strong>нт<strong>е</strong>,<br />

как L is t , мн<strong>е</strong> могут потр<strong>е</strong>боваться<br />

массивы?<br />

0:<br />

; Бывают случаи, когда работать приходится<br />

с фиксированным колич<strong>е</strong>ством<br />

эл<strong>е</strong>м<strong>е</strong>нтов или с посл<strong>е</strong>доват<strong>е</strong>льностью<br />

знач<strong>е</strong>ний фиксированной длины.<br />

у ' Массивы занимают м<strong>е</strong>ньил<strong>е</strong><br />

/ м<strong>е</strong>ста в памяти и быстр<strong>е</strong><strong>е</strong><br />

{ обрабатываются проц<strong>е</strong>ссором,<br />

впроч<strong>е</strong>м, выигрыил о производит<strong>е</strong>льности<br />

получа<strong>е</strong>тся<br />

н<strong>е</strong>значит<strong>е</strong>льным- Если ваила<br />

программа работа<strong>е</strong>т слиш ­<br />

ком м<strong>е</strong>дл<strong>е</strong>нно, вряд ли пробл<strong>е</strong>му<br />

м о ж н о р<strong>е</strong>шить п<strong>е</strong>р<strong>е</strong>ходом<br />

от колл<strong>е</strong>кций к массивам.<br />

Част»<br />

ЧаДаБа<strong>е</strong>Мы<strong>е</strong><br />

Б о и р о с :^ ,!<br />

Вы мож<strong>е</strong>т<strong>е</strong> пр<strong>е</strong>образовать колл<strong>е</strong>кцию<br />

в массив при помощи м<strong>е</strong>тода<br />

ТоАггау () ...обратно<strong>е</strong> пр<strong>е</strong>образовани<strong>е</strong><br />

сов<strong>е</strong>рша<strong>е</strong>тся при помощи одного из<br />

п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нных конструкторов объ<strong>е</strong>кга<br />

LІSt.<br />

Поч<strong>е</strong>му колл<strong>е</strong>кция называ<strong>е</strong>тся<br />

Обобщ<strong>е</strong>нной»?<br />

; Обобщ<strong>е</strong>нная колл<strong>е</strong>кция — это объ<strong>е</strong>кт<br />

(или встро<strong>е</strong>нный объ<strong>е</strong>кт, позволяющий<br />

хранить множ<strong>е</strong>ство других объ<strong>е</strong>ктов), который<br />

настраива<strong>е</strong>тся под хран<strong>е</strong>ни<strong>е</strong> одного<br />

типа данных.<br />

Вы объяснили, что тако<strong>е</strong> «колл<strong>е</strong>кция».<br />

Но поч<strong>е</strong>му «обобщ<strong>е</strong>нная»?<br />

;в суп<strong>е</strong>рмарк<strong>е</strong>ты товар доставляют<br />

в'однотипных коробках, на которых написано<br />

названи<strong>е</strong> сод<strong>е</strong>ржимого («Чипсы»,<br />

«Кола», «Мыло» и т. п.). Важно, что внутри<br />

коробки, а н<strong>е</strong> то, как это выглядит.<br />

Так ж<strong>е</strong> и с обобщ<strong>е</strong>нными типами данных.<br />

Объ<strong>е</strong>кт L ist< T > , наполн<strong>е</strong>нный объ<strong>е</strong>ктами<br />

Shoe, объ<strong>е</strong>ктами Card, ц<strong>е</strong>лыми<br />

числами или даж<strong>е</strong> другими колл<strong>е</strong>кциями,<br />

служит таким ж<strong>е</strong> конт<strong>е</strong>йн<strong>е</strong>ром. Вы мож<strong>е</strong>т<strong>е</strong><br />

добавлять, удалять, вставлять эл<strong>е</strong>м<strong>е</strong>нты<br />

вн<strong>е</strong> зависимости от их типа. ff<br />

Т<strong>е</strong>рмин «обобщ<strong>е</strong>нный» yKaj<br />

зыва<strong>е</strong>т, что хотя каждый<br />

экз<strong>е</strong>мпляр List мож<strong>е</strong>т сохранять<br />

данны<strong>е</strong> только одного<br />

типа, класс List работа<strong>е</strong>т<br />

с любыми типами данных.<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Возможна ли колл<strong>е</strong>кция, н<strong>е</strong> им<strong>е</strong>ющая<br />

ща5 типа?<br />

Н<strong>е</strong>т. Любая обобщ<strong>е</strong>нная колл<strong>е</strong>кция<br />

должна принадл<strong>е</strong>жать опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нному<br />

типу. В <strong>C#</strong> им<strong>е</strong>ются и колл<strong>е</strong>кции<br />

A rra y L istS , хранящи<strong>е</strong> объ<strong>е</strong>кты<br />

произвольного типа. Чтобы воспользоваться<br />

ими, нужно включить в в<strong>е</strong>рхнюю<br />

часть кода строчку u s in g S y s te m .<br />

C o l l e c t i o n s ;. Но вряд ли это вам<br />

когда-либо потр<strong>е</strong>бу<strong>е</strong>тся, так как колл<strong>е</strong>кция<br />

L is t < o b j e c t > в большинств<strong>е</strong> случа<strong>е</strong>в<br />

зам<strong>е</strong>чат<strong>е</strong>льно работа<strong>е</strong>т!<br />

0^!<br />

Создавая объ<strong>е</strong>кт<br />

list, вы вс<strong>е</strong>гда<br />

указыва<strong>е</strong>т<strong>е</strong> тип<br />

данных, которы<strong>е</strong><br />

будут в н<strong>е</strong>м храниться.<br />

Сохранять<br />

можно значимы<strong>е</strong><br />

тины (int, bool<br />

или decimal) или<br />

класс.<br />

Им<strong>е</strong>нно эту функцию выполня<strong>е</strong>т сиМ<br />

вол . Вм<strong>е</strong>сто н<strong>е</strong>го вы указыва<strong>е</strong>т<strong>е</strong>, какому<br />

типу принадл<strong>е</strong>жит рассматрива<strong>е</strong>мый<br />

обш кт List. Этим обобщ<strong>е</strong>нны<strong>е</strong> колл<strong>е</strong>кции<br />

отличаются от вс<strong>е</strong>го, что вы использовали<br />

раньил<strong>е</strong>.<br />

дальш<strong>е</strong> > 355


начн<strong>е</strong>м отсюда<br />

инициализаторы колл<strong>е</strong>кций<br />

C # п озволя<strong>е</strong>т ум <strong>е</strong> н ь ш и ть к о л и ч <strong>е</strong> ств о в в о д и м о го т<strong>е</strong> кста п р и создании ко л л <strong>е</strong> кц и и . В ы м ож <strong>е</strong>т<strong>е</strong> в оспользоваться<br />

и н и ц и а л и з а т о р о м к о л л <strong>е</strong> к ц и й ( c o lle c t io n in itia liz e r ), к о т о р ы й добавля<strong>е</strong>т эл<strong>е</strong>м <strong>е</strong>нты в к о л л <strong>е</strong> кц и ю<br />

н <strong>е</strong> п о ср <strong>е</strong> д ств <strong>е</strong> н н о в м ом <strong>е</strong>нт <strong>е</strong><strong>е</strong> создания. ^ „<br />

Этот код вы вид<strong>е</strong>ли н<strong>е</strong>сколько<br />

страниц назад. Он созда<strong>е</strong>т<br />

объ<strong>е</strong>кт List и заполня<strong>е</strong>т<br />

к / <strong>е</strong>го объ<strong>е</strong>ктами Shoe.<br />

Llst shoeCloset = new List();<br />

shoeCloset.Add(new ShoeO { Style = Style.Sneakers, Color = "Ч<strong>е</strong>рный" });<br />

shoeCloset.Add(new ShoeO { Style = Style.Clogs, Color = "Коричн<strong>е</strong>вый" });<br />

shoeCloset.Add(new ShoeO { Style = Style.Wingtips, Color = "Ч<strong>е</strong>рный" });<br />

shoeCloset.Add(new ShoeO { Style = Style.Loafers. Color = "Б<strong>е</strong>лый" });<br />

shoeCloset.Add(new ShoeO { Style = Style.Loafers, Color = "Красный" });<br />

shoeCloset.Add(new ShoeO { Style = Style.Sneakers, Color = "З<strong>е</strong>л<strong>е</strong>ный" });<br />

Обратит<strong>е</strong> внимани<strong>е</strong>:<br />

каждому объ<strong>е</strong>кту Shoe<br />

присваива<strong>е</strong>тся начально<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> при помощи<br />

инициализатора.<br />

Инициализатор колл<strong>е</strong>кции<br />

мож<strong>е</strong>т быть создан добавл<strong>е</strong>ни<strong>е</strong>м<br />

каждого получ<strong>е</strong>нного<br />

при помощи м<strong>е</strong>тода AddQ<br />

эл<strong>е</strong>м<strong>е</strong>нта к оп<strong>е</strong>ратору,<br />

формирующ<strong>е</strong>му колл<strong>е</strong>кцию.<br />

За оп<strong>е</strong>ратором<br />

создания колл<strong>е</strong>кции<br />

сл<strong>е</strong>дуют<br />

фигурны<strong>е</strong> скобки,<br />

о которых находятся<br />

разд<strong>е</strong>л<strong>е</strong>нны<strong>е</strong><br />

запятыми<br />

оп<strong>е</strong>раторы new.<br />

List shoeCloset =<br />

y new ShoeO { Style<br />

new ShoeO { Style<br />

/ new ShoeO { Style<br />

/ new ShoeO { Style<br />

{ new ShoeO { Style<br />

\ n e w ShoeO { Style<br />

new List() {<br />

= Style.Sneakers, Color = "Ч<strong>е</strong>рный" },<br />

= Style.Clogs, Color = "Коричн<strong>е</strong>вый" },<br />

= Style.Wingtips, Color = "Ч<strong>е</strong>рный" },<br />

= Style.Loafers. Color = "Б<strong>е</strong>лый" },<br />

= Style.Loafers. Color = "Красный" },<br />

= Style.Sneakers, Color = "З<strong>е</strong>л<strong>е</strong>ный" },<br />

} :<br />

Инициализатор<br />

мож<strong>е</strong>т сод<strong>е</strong>ржать<br />

н<strong>е</strong> только<br />

набор оп<strong>е</strong>раторов<br />

newJ но<br />

и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

Инициализатор колл<strong>е</strong>кций д<strong>е</strong>ла<strong>е</strong>т код компактн<strong>е</strong><strong>е</strong>,<br />

комбинируя создани<strong>е</strong> колл<strong>е</strong>кции<br />

с добавл<strong>е</strong>ни<strong>е</strong>м начального набора эл<strong>е</strong>м<strong>е</strong>нтов.<br />

356 глава 8


Колл<strong>е</strong>кция уток<br />

Ф<br />

У п р а ж н <strong>е</strong> н и <strong>е</strong> !<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Р а ссм о тр и м класс D uck, сл <strong>е</strong>дя щ и й за ваш <strong>е</strong>й кол л <strong>е</strong>к ц и <strong>е</strong>й уток. (В ы ж<strong>е</strong><br />

к ол л <strong>е</strong>к ц и он и р у<strong>е</strong>т<strong>е</strong> уток, правда?) С о з д а й т <strong>е</strong> к о н с о л ь н о <strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong><br />

и добавьт<strong>е</strong> в н <strong>е</strong>го класс D u ck и п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong>н и <strong>е</strong> K in d O f D u ck (В иды уток).<br />

К а ж д а я у т к а и м <strong>е</strong> <strong>е</strong> т р а з м <strong>е</strong> р ,<br />

э т а — 1 7 д ю й м о в .<br />

М у с к у с н ы <strong>е</strong> у т к и<br />

(M u sc o v y ).<br />

' t m<br />

i '<br />

У т к и б ы в а ю т<br />

д и к и <strong>е</strong>... ( m a lla r d s ) .<br />

И даж <strong>е</strong> д <strong>е</strong> р <strong>е</strong> в я н н ы <strong>е</strong><br />

м анки ( d e c o y s )<br />

I<br />

c l a s s D uck {<br />

}<br />

p u b l i c i n t S i z e ;<br />

p u b l i c K in d O fD u ck K in d ;<br />

К л а с с и м <strong>е</strong> <strong>е</strong> т д в а о т ­<br />

к р ы т ы х п о л я и м <strong>е</strong> т о ­<br />

д ы , к о т о р ы <strong>е</strong> з д <strong>е</strong> с ь н<strong>е</strong><br />

п о к а з ы в а ю т с я .<br />

enum K indO fD uck {<br />

инициализатор колл<strong>е</strong>кции уток<br />

у нас ш <strong>е</strong>сть уток, п о это м у мы со зд а д и м кол л<strong>е</strong>к ци ю L is t < D u c k ><br />

с со ст о я щ и м и з ш <strong>е</strong>сти о п <strong>е</strong> р а т о р о в и н и ц и а л и за т о р о м . К аж ­<br />

ды й и з э т и х о п <strong>е</strong> р а т о р о в со зд а <strong>е</strong>т новую утку, указывая зн а ч <strong>е</strong>н и я<br />

поля s i z e и K in d . Д о б а в ь т <strong>е</strong> э т о т к о д в м <strong>е</strong>т о д M a in () в ф а й л <strong>е</strong><br />

P r o g r a m .c s :<br />

L is t < D u c k > d u c k s = n e w L i s t < D u c k > О {<br />

n ew D u c k O { K in d = K in d O f D u c k .M a lla r d , S i z e = 17 } ,<br />

n ew D u c k O { K in d = K in d O fD u c k .M u s c o v y , S i z e = 18 } ,<br />

n ew D u c k O { K in d = K in d O f D u c k . D e c o y , S i z e = 14 } ,<br />

n e w D u c k O { K in d = K in d O f D u c k .M u s c o v y , S i z e = 11 } ,<br />

}<br />

M a l l a r d ,<br />

M u s c o v y ,<br />

D e c o y ,<br />

П <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и <strong>е</strong><br />

K in d O fD u c k х р а н и т и н ­<br />

ф о р м а ц и ю о в и д а х у т о к<br />

Ö к о л л <strong>е</strong> к ц и и .<br />

Д о б а в ь т <strong>е</strong> к п р о <strong>е</strong> к т у<br />

к л а с с Р и с к и п <strong>е</strong> р <strong>е</strong> ч и с ­<br />

л <strong>е</strong> н и <strong>е</strong> K in d O fD u c k .<br />

n ew<br />

D u c k O { K in d = K in d O f D u c k . M al l a r d . S i z e = 14 } ,<br />

M a in Q к о д , в ы в о д я щ и й р <strong>е</strong> з у л ь -<br />

n ew D u c k O { K in d = K in d O f D u c k . D e c o y , S i z e = 13 } , ° с т а в -<br />

^<br />

л я <strong>е</strong> т р <strong>е</strong> з у л ь т а т в и д и м ы м<br />

^ — п о к а вы н <strong>е</strong> н а ж м <strong>е</strong> т <strong>е</strong> к л а в и ш у .<br />

I I Э т о т м <strong>е</strong> т о д н <strong>е</strong> п о з в о л я <strong>е</strong> т р <strong>е</strong> з у л ь т а т у и с ч <strong>е</strong> з н у т ь ,<br />

C o n s o l e . R e a d K e y ( ) ;<br />

п о к а вы <strong>е</strong> г о н <strong>е</strong> п р о ч и т а л и<br />

дальш<strong>е</strong> > 357


расставим уток по ранжиру<br />

CopmupoBka эл<strong>е</strong>м<strong>е</strong>нтов колл<strong>е</strong>кции<br />

%<br />

С о р ти р о в к а чис<strong>е</strong>л и л и букв — вполн<strong>е</strong> о б ы ч н о <strong>е</strong> д<strong>е</strong>ло. Н о в о т ка к о т с о р т и р о ­<br />

вать объ<strong>е</strong>кты , о со б <strong>е</strong> н н о п р и н а л и ч и и н <strong>е</strong> с к о л ь к и х пол<strong>е</strong>й? М о ж н о расп о л о ­<br />

ж и т ь о б ъ <strong>е</strong> кты по им <strong>е</strong>нам , в д р у ги х случаях им <strong>е</strong><strong>е</strong>т см ы сл со р ти р о в а ть п о д л и­<br />

н<strong>е</strong> и л и п о дат<strong>е</strong> р о ж д <strong>е</strong> н и я . С ущ <strong>е</strong>ству<strong>е</strong>т м н о го спосо б о в р а сп о л о ж и ть о б ъ <strong>е</strong> кты<br />

п о порядку, и к о л л <strong>е</strong> кц и и п о д д <strong>е</strong> р ж и в а ю т вс<strong>е</strong>.<br />

У то к мо)кно располо)кить по разм<strong>е</strong>ру...<br />

мал<strong>е</strong>нькой к самой большой<br />

...UAU по Виду...<br />

с о р т и р о в к а п о в и д у у т к и . ^ _<br />

Встро<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды copmupoBku<br />

Сортировка объ<strong>е</strong>ктов<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся с помощью<br />

инт<strong>е</strong>рф<strong>е</strong>йса 1Сотраг<strong>е</strong>г,<br />

о котором мы поговорим<br />

чуть позж<strong>е</strong>...<br />

К аж дая ко л л <strong>е</strong> кц и я снабж <strong>е</strong>на м <strong>е</strong>тодом S o r t ( ) , м <strong>е</strong>няю щ и м п о р я д о к эл<strong>е</strong>м <strong>е</strong>нто<br />

в. С ущ <strong>е</strong>ствую т заданны <strong>е</strong> сп о со б ы с о р т и р о в к и б о л ь ш и н ств а в с тр о <strong>е</strong> н н ы х<br />

т и п о в и классов, кром <strong>е</strong> т о го , м о ж н о н а п и са ть способ с о р т и р о в к и ваш <strong>е</strong>го<br />

с о б с тв <strong>е</strong> н н о го класса.<br />

SortO<br />

Сортировка вс<strong>е</strong>го \<br />

лиш ь м<strong>е</strong>ня<strong>е</strong>т порядок<br />

располож<strong>е</strong>ния<br />

эл<strong>е</strong>м<strong>е</strong>нтов.<br />

17<br />

I дюймов<br />

^ <strong>е</strong> /г г Ы<br />

'<br />

358 глава 8


*<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

и н т <strong>е</strong> р ф <strong>е</strong> й с IC o m p a r a b le < D ( ie k ><br />

М <strong>е</strong> то д L i s t . S o r t О ум<strong>е</strong><strong>е</strong>т со р ти р о в а ть о б ъ <strong>е</strong> кты л ю б о го т и п а и классы ,<br />

к о то р ы <strong>е</strong> р <strong>е</strong> а л и з у ю т и н т <strong>е</strong> р ф <strong>е</strong> й с 1 С о т р а г а Ы <strong>е</strong> < Т > . В состав<strong>е</strong> э т о го и н т <strong>е</strong> р ­<br />

ф <strong>е</strong>йса н а хо д и тся то л ь ко м <strong>е</strong>тод С о т р а г<strong>е</strong> Т о { ) . S o r t ( ) , к о т о р ы й использу<strong>е</strong>т<br />

м <strong>е</strong>тод С о т р а г<strong>е</strong> Т о () объ<strong>е</strong>кта для ср а в н <strong>е</strong> н и я с д р уги м и объ<strong>е</strong>ктам и. В озвращ<br />

а<strong>е</strong>мо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> (т и п а in t) показы ва<strong>е</strong>т, к то д о л ж <strong>е</strong> н б ы ть п<strong>е</strong>рвы м .<br />

Для ко л л <strong>е</strong> кц и й объ<strong>е</strong>ктов, ко то р ы <strong>е</strong> н<strong>е</strong> р<strong>е</strong>ализую т и н т<strong>е</strong>рф <strong>е</strong>йс IC o m p a -<br />

г а Ы <strong>е</strong> < Т > , в .N E T им <strong>е</strong><strong>е</strong>тся д руго й способ. М <strong>е</strong>тод S o r t () м о ж н о п<strong>е</strong>р<strong>е</strong>дать экз<strong>е</strong>мпляру<br />

класса, р<strong>е</strong>ализую щ <strong>е</strong>го IC o m p a re r< T > . Э то т инт<strong>е</strong>рф <strong>е</strong>йс то ж <strong>е</strong> им <strong>е</strong><strong>е</strong>т<br />

вс<strong>е</strong>го один м<strong>е</strong>тод и позволя<strong>е</strong>т задавать сп<strong>е</strong>циальны <strong>е</strong> способы со р ти р о вки.<br />

М<strong>е</strong>тод Сотраг<strong>е</strong>ТоО сраВниба<strong>е</strong>т два объ<strong>е</strong>кта<br />

М о ж н о о тр <strong>е</strong> д а кти р о в а ть класс D u c k та ки м образом , ч т о б ы о н начал р<strong>е</strong>ализо<br />

в ы вать и н т<strong>е</strong> р ф <strong>е</strong> й с IC o m p a ra b le < D u c k > . Д ля э то го добавим м <strong>е</strong>тод<br />

С о т р а г<strong>е</strong> Т о ( ) , и сп о л ь зую щ и й ссы лку на объ<strong>е</strong>кт D u c k в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра.<br />

Е сли утка, взятая для сравн<strong>е</strong>ния, д о л ж н а оказаться посл<strong>е</strong> анализиру<strong>е</strong>м<br />

ой у тк и , м<strong>е</strong>тод С о т р а г<strong>е</strong> Т о {) возвращ а<strong>е</strong>т п о л о ж и т<strong>е</strong> л ь н о <strong>е</strong> число.<br />

Любой класс<br />

мож<strong>е</strong>т работать<br />

со встро<strong>е</strong>нным<br />

м<strong>е</strong>тодом<br />

Sort ( ) объ<strong>е</strong>кта<br />

List с помощью<br />

IComparable<br />

и Сотраг<strong>е</strong>То().<br />

О б н о в и т<strong>е</strong> класс D u c k пут<strong>е</strong>м р <strong>е</strong> ализа ц ии и н т<strong>е</strong> р ф <strong>е</strong> й са IC o m p a ra b le < D u c k > ,<br />

ч т о б ы о т с о р т и р о в а ть у т о к п о разм<strong>е</strong>ру:<br />

c l a s s D u c k : I C o m p a r a b l e < D u c k > {<br />

p u b l i c i n t S i z e ;<br />

p u b l i c K i n d O f D u c k K i n d ;<br />

Р<strong>е</strong>ализуя 1СомрагаЫ<strong>е</strong> J<br />

вы указыва<strong>е</strong>т<strong>е</strong> тип<br />

парам<strong>е</strong>тра, по которому<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся сравн<strong>е</strong>ни<strong>е</strong>.<br />

Т а к в ы г л я д ^ ^ о л ь ^ p u b l i c i n t С о т р а г <strong>е</strong> Т о ( D u c k d u c k T o C o m p a r e ) {<br />

Г л т » а г <strong>е</strong> Т ^ ( ) - i f ( t h i s . S i z e > d u c k T o C o m p a r e . S i z e )<br />

знам<strong>е</strong>ния п о л <strong>е</strong> й S ^ e<br />

д вц х yvn oK . Е сли<br />

m к о т о р у ю с с ы л а <strong>е</strong> т ­<br />

ся с л о в о this ^o^fc-tue.<br />

-%■<br />

A 6 случа<strong>е</strong> совпад<strong>е</strong>ния<br />

р а з м <strong>е</strong> р о в - ноль. J<br />

}<br />

r e t u r n 1 ;<br />

e l s e i f ( t h i s . S i z e < d u c k T o C o m p a r e . S i z e )<br />

r e t u r n - 1 ;<br />

, Чтобы получить ряд от самой<br />

мал<strong>е</strong>нькой до самой большой<br />

r e t u r n О ;<br />

утки, м<strong>е</strong>тод CompareToQ долж<strong>е</strong>н<br />

возвращать положит<strong>е</strong>льно<strong>е</strong> число<br />

при сравн<strong>е</strong>нии с уткой м<strong>е</strong>ньш<strong>е</strong>го<br />

разм<strong>е</strong>ра.<br />

Д о б а в ь т <strong>е</strong> э т о т к о д в ко н <strong>е</strong> ц м <strong>е</strong>тода M a in { ) до вы зова м <strong>е</strong>тода C o n s o l e .<br />

R e a d K e y О , и ко л л <strong>е</strong> кц и я у то к буд<strong>е</strong>т о тс о р т и р о в а н а п о разм<strong>е</strong>ру. П о м <strong>е</strong> сти т<strong>е</strong><br />

т о ч к у о с т а н о в а в м<strong>е</strong>тод С о т р а г<strong>е</strong> Т о () и воспользуйт<strong>е</strong>сь отл адчи ком , ч т о ­<br />

бы п о н я ть , как вс<strong>е</strong> работа<strong>е</strong>т.<br />

d u c k s . S o r t ( ) ;<br />

дальш<strong>е</strong> > 359


прим<strong>е</strong>р сортировки<br />

%<br />

Способы copmupoßku<br />

Д ля ко л л <strong>е</strong> к ц и й сущ <strong>е</strong>ству<strong>е</strong>т сп <strong>е</strong> ц и а л ь н ы й в с т р о <strong>е</strong> н н ы й в .N E T<br />

F ra m e w o rk и н т<strong>е</strong> р ф <strong>е</strong> й с, п о зв о л я ю щ и й создать о тд <strong>е</strong> л ь н ы й класс для<br />

с о р т и р о в к и со ста в л я ю щ и х объ<strong>е</strong>кта L is t < T > . Р <strong>е</strong> а л и з у я и н т <strong>е</strong> р ф <strong>е</strong> й с<br />

IC o m p a r e r < T > , в ы объясня<strong>е</strong>т<strong>е</strong> к о л л <strong>е</strong> кц и и , ка ким способом н у ж н о<br />

уп о р я д о ч и ть <strong>е</strong><strong>е</strong> сод<strong>е</strong>рж им о<strong>е</strong>. Задача в ы п о л н я <strong>е</strong> тся ср<strong>е</strong>дствам и м <strong>е</strong>тода<br />

C om pare ( ) , к о т о р ы й б <strong>е</strong>р<strong>е</strong>т п а р ам <strong>е</strong>тры двух о б ъ <strong>е</strong> кто в х и у и возвращ<br />

а<strong>е</strong>т ц<strong>е</strong>ло<strong>е</strong> число. Е сли х м <strong>е</strong>ньш <strong>е</strong>, ч<strong>е</strong>м у, возвращ а<strong>е</strong>тся о тр и ц а ­<br />

т<strong>е</strong> л ьн о<strong>е</strong> число. В случа<strong>е</strong> и х рав<strong>е</strong>нства возвращ а<strong>е</strong>тся ноль. Н у а <strong>е</strong>сли<br />

X больш <strong>е</strong>, ч<strong>е</strong>м у, буд<strong>е</strong>т возвращ <strong>е</strong>но п о л о ж и т<strong>е</strong> л ь н о <strong>е</strong> чи сло.<br />

В о т п р и м <strong>е</strong> р о б ъ я вл<strong>е</strong>ния класса, ср а в н и ваю щ <strong>е</strong> го о б ъ <strong>е</strong> кты D u c k п о<br />

разм<strong>е</strong>ру. Д обавьт<strong>е</strong> э то т класс к сво<strong>е</strong>м у про<strong>е</strong>кту,<br />

з<br />

f r “ “<br />

сортиру<strong>е</strong>мых объ<strong>е</strong>ктов- Duck<br />

Способ сортировки<br />

зависит от способа<br />

р<strong>е</strong>ализации<br />

инт<strong>е</strong>рф<strong>е</strong>йса<br />

IComparer.<br />

\<br />

class DuckComparerBySize : IComparer<br />

{<br />

public int Compare (Виск'^хГвис^^^Т^<br />

{<br />

м <strong>е</strong> т о д<br />

ц<strong>е</strong>ло<strong>е</strong> им<strong>е</strong>ло<br />

Тип сравнива<strong>е</strong>мых<br />

знач<strong>е</strong>ний вс<strong>е</strong>гда буд<strong>е</strong>т<br />

совпадать.<br />

л<br />

О т рицат <strong>е</strong>льно<strong>е</strong> число означа<strong>е</strong>т,<br />

что X долж<strong>е</strong>н ст оят ь п<strong>е</strong>р<strong>е</strong>д у,<br />

т ак как х «м<strong>е</strong>ньил<strong>е</strong>, ч<strong>е</strong>м » у.<br />

p означа<strong>е</strong>т совпад<strong>е</strong>ни<strong>е</strong><br />

р « м <strong>е</strong> р о 6<br />

^ ^ с д о в а т ь зд<br />

до л ж <strong>е</strong>н<br />

У-<br />

Это м<strong>е</strong>тод вывода уток<br />

в вид<strong>е</strong> колл<strong>е</strong>кции List.<br />

p u b l i c s t a t i c v o id P rin tD u c k s(L ist< D u c k > du ck s)<br />

{<br />

fo r e a c h (Duck duck i n du ck s)<br />

C o n s o le .W r it e L in e (duck. S i z e . T o S t r i n g ()<br />

C o n s o le .W r it e L in e ( "Утки к он чи л и сь!" );<br />

Добавьт<strong>е</strong> м<strong>е</strong>тод PnntPucks<br />

в класс Program, чтобы<br />

об<strong>е</strong>сп<strong>е</strong>чить вывод данных.<br />

\<br />

Л Обновит<strong>е</strong> м<strong>е</strong>тод MainQ<br />

таким образом, чтобы<br />

он вызывался до и посл<strong>е</strong><br />

сортировки.<br />

+ "-дюймов " + d u c k .K in d .T o S t r in g O )<br />

360 глава 8<br />

Ф


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Создадим экз<strong>е</strong>мпляр объ<strong>е</strong>кта-компаратора<br />

Д ля с о р т и р о в к и с п о м о щ ь ю IC o m p a re r< T > тр <strong>е</strong>бу<strong>е</strong>тся н о в ы й экз<strong>е</strong>м пляр<br />

р<strong>е</strong>ализую щ <strong>е</strong>го э т о т и н т<strong>е</strong> р ф <strong>е</strong> й с класса. Э т о т объ<strong>е</strong>кт п о м о га <strong>е</strong> т м<strong>е</strong>тоду<br />

L i s t . S o r t () у п о р я д о ч и ть массив. Н о ка к и в случа<strong>е</strong> с д р уги м и (н <strong>е</strong> ста ти ­<br />

ч <strong>е</strong> с к и м и ) классам и, вам н у ж н о указать начальны <strong>е</strong> знач<strong>е</strong>ния.<br />

Зд<strong>е</strong>сь н<strong>е</strong> написан код при -<br />

сваивающий эл<strong>е</strong>м<strong>е</strong>нтам<br />

колл<strong>е</strong>кции начальны<strong>е</strong> знач<strong>е</strong>ния,<br />

вы найд<strong>е</strong>т<strong>е</strong> <strong>е</strong>го н<strong>е</strong>сколькими<br />

страницами ра-<br />

'н<strong>е</strong><strong>е</strong>! Если этого н<strong>е</strong> сд<strong>е</strong>лать,<br />

ссылки будут указывать на<br />

знйчсния^<br />

DuckComparerBySize sizeComparer = new DuckComparerBySize();<br />

ducks.Sort(sizeComparer);<br />

PrintDucks (ducks) ;<br />

Г<br />

Добавьт<strong>е</strong> этот код в<br />

м<strong>е</strong>тод MainQ, чтобы<br />

бид<strong>е</strong>ть, как были о т ­<br />

сортированы утки.<br />

М<strong>е</strong>тоду ЗогЬО п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся ссылка на<br />

новый объ<strong>е</strong>кт РискСотраг<strong>е</strong>гВу51г<strong>е</strong><br />

как на парам<strong>е</strong>тр м<strong>е</strong>тода.<br />

От самой мал<strong>е</strong>нькой к самой большой..<br />

Мно)к<strong>е</strong>ств<strong>е</strong>нны<strong>е</strong> р<strong>е</strong>ализации инт<strong>е</strong>рф<strong>е</strong>йса IComparer как разны<strong>е</strong><br />

способы copmupoBku<br />

М о ж н о создать н а б о р классов IC o m p a re r< D u c k > , ка ж д ы й из ко то - ^^г^числ<strong>е</strong>нця<br />

р ы х буд<strong>е</strong>т со р ти р о в а ть у т о к по-сво<strong>е</strong>му. Вам буд<strong>е</strong>т д о ста то ч н о толь- по их ~<br />

к о вы б р а ть н у ж н ы й ком п а р а то р . Д обавим к п р о <strong>е</strong> к ту <strong>е</strong>щ <strong>е</strong> одну р<strong>е</strong>а-<br />

л и за ц и ю п р о ц <strong>е</strong> д ур ы сравн<strong>е</strong>ния:<br />

^<br />

class DuckComparerByKind : IComparer<br />

public int Compare(Duck x. Duck y) {<br />

if (x.Kind < y.Kind) М ы с р а в н и в а <strong>е</strong> м с в о й с т в о<br />

-1; . иток Kind, поэтому со<br />

ртировка происходит по<br />

> у.Kind) и н д <strong>е</strong> к с а м п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и я<br />

KlndOfPuck.<br />

}<br />

ч<strong>е</strong>м>>^и«м<strong>е</strong>тш1<br />

«больш<strong>е</strong>, J<br />

знач<strong>е</strong>ни<strong>е</strong>. Мы с п о л ь зо в а ^^ІТ<br />

оп<strong>е</strong>раторы < и > Ъло . Т ^°^'^‘^^ски<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния при copT u pS Z Z ' k ^^ ^'<br />

п р и м <strong>е</strong> р сом<br />

ч и с л <strong>е</strong> н и и<br />

DuckComparerByKind kindComparer = new DuckComparerByKind();<br />

ducks.Sort(kindComparer);<br />

PrintDucks(ducks); ----<br />

Дополнит<strong>е</strong>льный код<br />

для м<strong>е</strong>тода MainQ.<br />

С о р т и р о в к а n o в и д у<br />

у т к и ...<br />

дальш<strong>е</strong> ► 361


выб<strong>е</strong>рит<strong>е</strong> карту, любую карту<br />

Сложны<strong>е</strong> сх<strong>е</strong>мы срабн<strong>е</strong>ния<br />

О тд<strong>е</strong>л ьн ы й класс для со р т и р о в к и уток п о зв о л я <strong>е</strong>т п р и м <strong>е</strong>­<br />

ни ть б о л <strong>е</strong> <strong>е</strong> сл ож н ую логику срав н <strong>е</strong>н и я , д обав и в чл<strong>е</strong>ны ,<br />

о п р <strong>е</strong>д <strong>е</strong>л я ю щ и <strong>е</strong> м <strong>е</strong>то д со р т и р о в к и колл<strong>е</strong>кции.<br />

enum s o r t c r i t e r i a { П<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> указыва<strong>е</strong>т объ<strong>е</strong>кs<br />

iz e T h e n K in d , т у, каким им<strong>е</strong>нно способом бцдит<br />

K in d T h e n S iz e , сорт ироваться ут ки. П<strong>е</strong>рвый<br />

^<br />

разм <strong>е</strong>ру, зат <strong>е</strong>м<br />

— *^0 виду», второй —• наоборот.<br />

c l a s s DuckComparer : IComparer {<br />

p u b l i c S o r t c r i t e r i a S o r tB y = S o r t C r i t e r i a . S izeT h en K in d ; ^<br />

p u b l i c i n t C om pare(Duck x . Duck y) {<br />

i f (S o r tB y == S o r t c r i t e r i a .S iz e T h e n K i n d )<br />

e l s e<br />

i f ( x .S i z e > y . S i z e )<br />

r e t u r n 1;<br />

e l s e i f ( x .S i z e < y . S i z e )<br />

r e t u r n -1 ;<br />

e l s e<br />

i f (x .K in d > y .K in d )<br />

r e t u r n 1;<br />

e l s e i f (x .K in d < y .K in d )<br />

r e t u r n -1 ;<br />

e l s e<br />

r e t u r n 0:<br />

i f (x .K in d > y .K in d )<br />

r e t u r n 1;<br />

e l s e i f (x .K in d < y .K in d )<br />

r e t u r n -1 ;<br />

e l s e<br />

i f ( x .S i z e > y . S i z e )<br />

r e t u r n 1;<br />

e l s e i f ( x . S i z e < y . S i z e )<br />

r e t u r n -1 ;<br />

e l s e<br />

r e t u r n 0;<br />

DuckComparer com parer = new D uckC om parer() ;<br />

co m p a r er . S o r tB y = S o r t c r it e r ia .K in d T h e n S iz e ,•<br />

d u c k s .S o r t(c o m p a r e r ) ;<br />

P r in tD u c k s(d u c k s) ;<br />

c o m p a r e r .S o r tB y = S o r t c r i t e r i a . S izeT h en K in d ;<br />

d u c k s . S o r t(c o m p a r e r ) ;<br />

P r in t D u c k s ( d u c k s ) ;<br />

л<br />

Если м<strong>е</strong>тод 5ог1() для объ<strong>е</strong>кта<br />

1Сотраг<strong>е</strong>г н<strong>е</strong> указан, буд<strong>е</strong>т<br />

использован заданный по<br />

умолчанию м<strong>е</strong>тод сравн<strong>е</strong>ния<br />

значимых типов или ссылок.<br />

Класс, выполняющий сравн<strong>е</strong>ни<strong>е</strong> уток,<br />

бол<strong>е</strong><strong>е</strong> слож<strong>е</strong>н. М<strong>е</strong>тод Сотраг<strong>е</strong>()<br />

использу<strong>е</strong>т т<strong>е</strong> ж<strong>е</strong> самы<strong>е</strong> парам<strong>е</strong>тры,<br />

но сначала пров<strong>е</strong>ря<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

открытого поля ЗогЬВу, чтобы<br />

опр<strong>е</strong>д<strong>е</strong>лить способ сортировки.<br />

Оп<strong>е</strong>ратор if пров<strong>е</strong>ря<strong>е</strong>т пол<strong>е</strong><br />

Зо^В у. Если оно им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

\ 51г<strong>е</strong>Тк<strong>е</strong>пК!пс(, утки сначала будут<br />

^ упорядочиваться по разм<strong>е</strong>ру, а<br />

зат<strong>е</strong>м в пр<strong>е</strong>д<strong>е</strong>лах каждого разм <strong>е</strong>­<br />

ра пройд<strong>е</strong>т сортировка по виду.<br />

Раньил<strong>е</strong>, <strong>е</strong>сли утки им<strong>е</strong>ли один и тот<br />

ж<strong>е</strong> разм<strong>е</strong>р, возвращалось нул<strong>е</strong>во<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong>, т<strong>е</strong>п<strong>е</strong>рь ж<strong>е</strong> пров<strong>е</strong>ря<strong>е</strong>тся<br />

<strong>е</strong>щ<strong>е</strong> и видовая принадл<strong>е</strong>жность уток.<br />

В итог<strong>е</strong> О возвраща<strong>е</strong>тся н<strong>е</strong> только когда<br />

утки им<strong>е</strong>ют одинаковый разм<strong>е</strong>р, но<br />

и относятся к одному и тому ж<strong>е</strong> виду.<br />

Если знач<strong>е</strong>ни<strong>е</strong> поля ЗогіВу отлично<br />

от Віг<strong>е</strong>Тк<strong>е</strong>пКії'^сі, то сначала<br />

сортировка выполня<strong>е</strong>тся по виду<br />

утки. Обнаружив двух уток одного<br />

вида, компаратор сравнива<strong>е</strong>т их<br />

разм<strong>е</strong>р.<br />

Сначала мы, как<br />

экз<strong>е</strong>мпляр к о м п а р а т о р а З а т <strong>е</strong> м<br />

присваива<strong>е</strong>м знач<strong>е</strong>ни<strong>е</strong> п о л ю .^опт ^<br />

7оТл<strong>е</strong> ч<strong>е</strong>го можно 6bifam b м<strong>е</strong>тод<br />

ducks SortQ. Т<strong>е</strong>п<strong>е</strong>рь вы мож<strong>е</strong>т<strong>е</strong><br />

м<strong>е</strong>нять м<strong>е</strong>тод сортировки уток,<br />

р<strong>е</strong>дактируя знач<strong>е</strong>ни<strong>е</strong> одного поля.<br />

Добавьт<strong>е</strong> этот код в М ^ ^ _<br />

Тд MainQ, и вы получит<strong>е</strong> дозмож<br />

н о с т ь сортировать колл<strong>е</strong>кцию<br />

много раз!<br />

362 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Ч ^ а ж н ш<br />

<strong>е</strong><br />

С о зд ай т<strong>е</strong> пять случай н ы х карт и располож ит<strong>е</strong> их в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нном порядк<strong>е</strong>.<br />

о<br />

Код, м од<strong>е</strong>лирую щ ий набор п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ш анны х карт<br />

С оздайт<strong>е</strong> ко н со л ь н о <strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> и добавьт<strong>е</strong> в м <strong>е</strong>тод M a in () код, созд аю щ и й п я ть<br />

случайны х объ<strong>е</strong>ктов C ard. И спользуйт<strong>е</strong> в с т р о <strong>е</strong> н н ы й м <strong>е</strong>тод C o n s o l e . W r i t e L i n e ()<br />

для за п иси и м <strong>е</strong> н и ка ж д о го объ<strong>е</strong>кта в о к н <strong>е</strong> вы вода. Д обавьт<strong>е</strong> в ко н <strong>е</strong> ц п р о гр а м м ы м <strong>е</strong>тод<br />

C o n s o l e . R e a d K e y { ) , ч т о б ы э то о к н о н<strong>е</strong> исч<strong>е</strong>зало посл<strong>е</strong> о к о н ч а н и я р а б о ты п рогр а м м ы .<br />

Класс, который р<strong>е</strong>ализу<strong>е</strong>т сортирую щ ий карты инт<strong>е</strong>р(р<strong>е</strong>йс IC om parer<br />

В оспользуйт<strong>е</strong>сь ср<strong>е</strong>дствам и И С Р , со кр а щ а ю щ и м и труд озатраты . В в<strong>е</strong>дит<strong>е</strong>:<br />

c l a s s CardC om parer_byV alue : ICom parer<br />

Щ <strong>е</strong> л к н и т <strong>е</strong> на IC o m p a r e r < C a r d > и зад<strong>е</strong>рж ит<strong>е</strong> курсо р над сим волом I. П о я в и тс я ч<strong>е</strong>рта,<br />

щ <strong>е</strong> л ч ок на к о т о р о й о т к р о <strong>е</strong> т в о т тако<strong>е</strong> о кн о :<br />

Альт <strong>е</strong>рнат ивны м способом<br />

вызова этого м <strong>е</strong> н ю<br />

явля<strong>е</strong>тся клавиатурная<br />

комбинация СЬг1-точка.<br />

ICDfl>Da"e-


ищит<strong>е</strong>!<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

)‘^<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

В о т как вы глядит сортировка случайного н аб ора карт.<br />

Если X им<strong>е</strong><strong>е</strong>тл<br />

оольш<strong>е</strong><strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>,<br />

м<strong>е</strong>илод возвра -<br />

ща<strong>е</strong>т 1 . Если<br />

знач<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>ньш<strong>е</strong>,<br />

оозЬраща<strong>е</strong>тся<br />

-!■ Но оба оп<strong>е</strong>ратора,<br />

возвращающи<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong>,<br />

зав<strong>е</strong>ршают<br />

радоту м<strong>е</strong>тода.<br />

c l a s s CardC om parer_byV alue : ICom parer { ^ ^ ‘^ Р ^ <strong>е</strong> н н ы и<br />

p u b l i c i n t Com pare(Card x , Card y) {<br />

(x .V a lu e < y .V a lu e ) {<br />

r e t u r n -1 ;<br />

(x .V a lu e > y .V a lu e ) {<br />

r e t u r n 1;<br />

( x .S u i t < y . S u i t ) {<br />

r e t u r n -1 ;<br />

( x .S u i t > y . S u i t ) {<br />

r e t u r n 1;<br />

}<br />

r e t u r n 0;<br />

Э т и оп<strong>е</strong>раторы выполняются ^<br />

только при совпад<strong>е</strong>нии знач<strong>е</strong>нии<br />

хич, в<strong>е</strong>дь п<strong>е</strong>рвы<strong>е</strong> два оп<strong>е</strong>ратора,<br />

возвращающи<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>, в этом<br />

случа<strong>е</strong> н<strong>е</strong> выполняются.<br />

s t a t i c v o i d M a i n ( s t r i n g [] a r g s)<br />

{<br />

Random random = new Random() ;<br />

C o n s o le . W r it e L in e ( "Пять случайных к а р т :" );<br />

L ist< C a rd > c a r d s = new L ist< C a rd > () ;<br />

f o r ( i n t i = 0; i < 5; i++ )<br />

{<br />

}<br />

c a rd s.A d d (n e w C a r d ( ( S u it s ) r a n d o m .N e x t ( 4 ) ,<br />

C o n s o le .W r it e L in e ( c a r d s [ i] .N a m e ) ;<br />

(V a lu e s )r a n d o m .N e x t(1 , 1 4 ) ) ) ;<br />

Это обобщ<strong>е</strong>нная<br />

колл<strong>е</strong>кция объ<strong>е</strong>ктов<br />

Card. Е<strong>е</strong> л<strong>е</strong>гко сортировать<br />

с помощью<br />

инт<strong>е</strong>рф<strong>е</strong>йса<br />

IComparer.<br />

C o n s o le . W r it e L in e ( );<br />

364 глава 8<br />

C o n s o le .W r it e L in e ( "Т<strong>е</strong> ж<strong>е</strong> карты, отсор ти р ов ан н ы <strong>е</strong>:" );<br />

c a r d s . S o r t(n e w C ardC om parer_byV alu e( ) ) ;<br />

f o r e a c h (Card c a r d i n c a r d s)<br />

{<br />

C o n so le .W r ite L in e (c a r d .N a m e )<br />

}<br />

C o n so le .R e a d K e y 0 ; < ..........<br />

М<strong>е</strong>тод Console.ReadKeyO нуж<strong>е</strong>н, чтобы программа<br />

н<strong>е</strong> закрывалась посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния. Для<br />

р<strong>е</strong>альных прилож<strong>е</strong>ний он н<strong>е</strong> подходит. При запуск<strong>е</strong><br />

программы по Ctrl-F5 она начина<strong>е</strong>т работать<br />

б<strong>е</strong>з отладки. Посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния появля<strong>е</strong>тся<br />

строка Press any key to continue... и прилож<strong>е</strong>ни<strong>е</strong><br />

жд<strong>е</strong>т нажатия клавиши. Но отладки н<strong>е</strong> происходит,<br />

и точки останова с контрольными знач<strong>е</strong>ниями<br />

н<strong>е</strong> работают.


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

П<strong>е</strong>р<strong>е</strong>крыти<strong>е</strong> м<strong>е</strong>тода T oStringO<br />

Вс<strong>е</strong> объ<strong>е</strong>кты .N E T им <strong>е</strong> ю т м <strong>е</strong> т о д T o S t r i n g ( ) , п р <strong>е</strong> о б р а з у ю щ и й о б ъ <strong>е</strong> к т в ст р о к у . П о ум о л чанию о н возвращ<br />

а<strong>е</strong>т им я класса ( M y P r o j e c t .D u ck ). Э то т м<strong>е</strong>тод унасл<strong>е</strong>дован о т класса O b j e c t (к о т о р ы й явля<strong>е</strong>тся<br />

базовым для л ю б о го объ<strong>е</strong>кта). О п <strong>е</strong> р а то р +, со <strong>е</strong> д и н яю щ и й с тр о к и а в т о м а т и ч <strong>е</strong> с к и , в ы з ы в а <strong>е</strong> т м <strong>е</strong> т о д<br />

T o S t r i n g ( ) . М <strong>е</strong>тоды C o n s o l e . W r i t e L i n e () и л и S t r i n g . F o rm a t () та к ж <strong>е</strong> автом атич<strong>е</strong>ски вы зы ваю т<br />

<strong>е</strong>го п р и п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> им объ<strong>е</strong>ктов.<br />

В п р о грам м <strong>е</strong> с о р т и р о в к и у т о к п о м <strong>е</strong> сти т<strong>е</strong> то ч к у о станова в м <strong>е</strong>тод M a in () посл<strong>е</strong> и н и ц и а л и з а ц и и колл<strong>е</strong>к-<br />

ц и и и запустит<strong>е</strong> отладку п р о гр а м м ы . Зат<strong>е</strong>м н а в <strong>е</strong> д и т <strong>е</strong> у к а з а т <strong>е</strong> л ь м ы ш и н а л ю б у ю п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н у ю d u c k s ,<br />

ч т о б ы знать <strong>е</strong><strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. У ви д <strong>е</strong> ть п р и отладк<strong>е</strong> сод<strong>е</strong>рж им о<strong>е</strong> к о л л <strong>е</strong> кц и и м о ж н о , щ <strong>е</strong>лкнув на к н о п к <strong>е</strong> со<br />

знаком<br />

сл<strong>е</strong>ва о т и м <strong>е</strong> н и п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> нной:<br />

И Ф ducfes'Count = 6 )<br />

□ Ф ducks C ount = 6<br />

ш ^ т {MyProject.Dudî,}<br />

ш V [11 flHvProject.Dudt}<br />

[2] {MyProject.Duck}<br />

М<strong>е</strong>тод ToStringO вызыва<strong>е</strong>тся при от о­<br />

браж<strong>е</strong>нии обь<strong>е</strong>кта в окн<strong>е</strong> Watch. Но ш # И ^yP rojectD uck}<br />

м<strong>е</strong>тод ToStringOJ унасл<strong>е</strong>дованный классом<br />

Риск от класса Object, возвраща<strong>е</strong>т ш é т {MyProject.Dudc}<br />

ш ФЫ flHyProject.Duck><br />

только имя класса. Мы мож<strong>е</strong>м сд<strong>е</strong>лать ш # Raw View<br />

этот м<strong>е</strong>тод бол<strong>е</strong><strong>е</strong> информативным.<br />

Вм<strong>е</strong>сто п<strong>е</strong>р<strong>е</strong>дачи знач<strong>е</strong>ния<br />

м<strong>е</strong>тодам Console.<br />

WriteLineO, String.<br />

FormatQ и т. п., можно<br />

п<strong>е</strong>р<strong>е</strong>дать им обь<strong>е</strong>кт.<br />

Его м<strong>е</strong>тод ToStringO<br />

буд<strong>е</strong>т вызван автоматич<strong>е</strong>ски.<br />

(Это работа<strong>е</strong>т<br />

и для значимых типов,<br />

таких как int и enums!)<br />

х<br />

И та к , вы в и д и т<strong>е</strong> , ч т о ко л л <strong>е</strong> кц и я с о д <strong>е</strong> р ж и т ш <strong>е</strong>сть объ<strong>е</strong>кто в D u ck (M y P ro je c t — это п р о с тр а н с тв о им <strong>е</strong>н,<br />

в к о то р о м м ы н а ходим ся ). Щ <strong>е</strong> л ч о к на к н о п к <strong>е</strong> (сл<strong>е</strong>ва о т н о м <strong>е</strong> р а у гк и ) показы ва<strong>е</strong>т з н а ч<strong>е</strong>ния п арам <strong>е</strong>тров<br />

K in d и S i z e . Н о н<strong>е</strong>льзя л и сд<strong>е</strong>лать так, ч т о б ы вся и н ф о р м а ц и я показы валась одновр<strong>е</strong>м <strong>е</strong>нно?<br />

T o S t r i n g О - э то в и р т у а л ь н ы й м <strong>е</strong>тод класса Obj e c t , к о т о р ы й явля<strong>е</strong>тся базовы м п о о т н о ш <strong>е</strong> н и ю к л ю ­<br />

бому объ<strong>е</strong>кту. Т ак ч т о вам оста<strong>е</strong>тся то л ь к о п <strong>е</strong> р <strong>е</strong> к р ы т ь м <strong>е</strong> т о д T o S t r i n g O , и вы у в и д и т<strong>е</strong> р<strong>е</strong>зультаты<br />

в о кн<strong>е</strong> w atch! О т к р о й т <strong>е</strong> класс D u ck и добавьт<strong>е</strong> н о в ы й м <strong>е</strong>тод с кл ю ч <strong>е</strong> вы м словом o v e r r i d e . П о сл <strong>е</strong> наж<br />

а ти я П р о б <strong>е</strong> л а п о я в и тс я с п и с о к д о с т у п н ы х для п <strong>е</strong> р <strong>е</strong> к р ы ти я м <strong>е</strong>тодов:<br />

override<br />

= ♦ E q u a ls ( o b je c t o b j)<br />

G e tH a s h C o d e O<br />

T oStrin gO<br />

I s t r i n g o b j e c t J o S t r l n g O<br />

I Returns a System .String that represents the current S^çtem.Objsct.<br />

В ы б <strong>е</strong> р и т<strong>е</strong> в а р и а н т T o S tr in g () и зам <strong>е</strong>нит<strong>е</strong> сод<strong>е</strong>рж им о<strong>е</strong> м <strong>е</strong>тода в о т эти м :<br />

p u b l i c o v e r r id e s t r i n g T o S tr in g O<br />

{<br />

r e t u r n "A " + S i z e + " in c h " + K in d .T o S t r in g 0 ;<br />

З а пустит<strong>е</strong> п р о гр а м м у и снова п о с м о тр и т<strong>е</strong> на ко л л <strong>е</strong> кц и ю . Т <strong>е</strong>п<strong>е</strong>рь вы в и д и т<strong>е</strong> вс<strong>е</strong> св<strong>е</strong>д<strong>е</strong>ния о Duck!<br />

В # d u c k s C o u n t = 6<br />

Ш t [0] {A 17mdi Maliard}<br />

Ш<br />

{A 18 iid i №jscovy><br />

Ш 9 m {A H in d i Decoy)<br />

ffl Фт {A 11 inch Misrnvy}<br />

ШФ [4] {A 14indiMa8ard}<br />

ffl #151 {A 13 indi Decoy}<br />

Ш Ч) Raw ¥iew<br />

Чтобы показать обь<strong>е</strong>кт,<br />

отладчик вызыва<strong>е</strong>т м<strong>е</strong>тод<br />

ToStringOдальш<strong>е</strong><br />

> 365


цикл foreach<br />

Обновим цикл foreach<br />

В ы вид<strong>е</strong>ли уж <strong>е</strong> два п р и м <strong>е</strong> р а ц и к л и ч <strong>е</strong> с к о го вы зова м <strong>е</strong>тода C o n s o le . W r i t e L i n e () для вы вода инф о р м а ­<br />

ц и и об эл<strong>е</strong>м <strong>е</strong>нтах к о л л <strong>е</strong> кц и и на ко нсо л ь. В о т та к в ы в о д и л и сь св<strong>е</strong>д<strong>е</strong>ния о к о л л <strong>е</strong> кц и и L is t < C a r d > :<br />

f o r e a c h (C a rd c a r d i n c a r d s )<br />

^<br />

Умминани<strong>е</strong> о м<strong>е</strong>тод<strong>е</strong><br />

C o n s o le . W r it e L in e ( c a r d . Name) ;<br />

}<br />

-ToStringO в данном случа<strong>е</strong><br />

Можно опустить,<br />

,<br />

М <strong>е</strong> то д P r in t D u c k s () в ы п о л н я л а н а л о ги ч н ую ф ун кц и ю для объ<strong>е</strong>ктов D u ck:<br />

оп<strong>е</strong>ратор + вызов<strong>е</strong>т <strong>е</strong>го<br />

‘^отоматич<strong>е</strong>скиfo<br />

r e a c h (Duck d u ck i n d u cks) /<br />

^ C o n s o le .W r ite L in e ( d u c k .S iz e .T o S tr in g O + " - in c h " + d u c k .K in d .T o S t r in g O ) ;<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда объ<strong>е</strong>кт D u c k п о л уч и л св о й м <strong>е</strong>тод T o S t r i n g ( ) , м <strong>е</strong>тод P r in t D u c k s () долж <strong>е</strong> н и спользо ­<br />

вать это пр<strong>е</strong>им ущ <strong>е</strong>ство:<br />

p u b l i c s t a t i c v o i d P r in t D u c k s ( L is t < D u c k > d u c k s ) {<br />

f o r e a c h (D u c k d u c k i n d u c k s ) {<br />

C o n s o le . W r it e L in e (d u c k ) ; _ п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> м<strong>е</strong>тоду Console.WriteLineO<br />

} ссылки на од-ь<strong>е</strong>кт_, он автоматич<strong>е</strong>ски вызо-<br />

C o n s o le . W r it e L in e { " У т к и к о н ч и л и с ь ! " ) ; Memo ToStringO этого обь<strong>е</strong>кта-<br />

}<br />

Вв<strong>е</strong>дит<strong>е</strong> э то т код в програм м у D u c k s и запустит<strong>е</strong> <strong>е</strong><strong>е</strong>. С п и со к вы вода н<strong>е</strong> изм <strong>е</strong>нится. Н о <strong>е</strong>сли вы захоти т<strong>е</strong><br />

добавить свойство G e n d e r для уч<strong>е</strong>та пола у гк и , д оста та то чно о б н о в и ть м <strong>е</strong>тод T o S t r i n g ( ) , и вс<strong>е</strong> м <strong>е</strong>тоды ,<br />

к о то р ы <strong>е</strong> <strong>е</strong>го использую т (вклю чая м <strong>е</strong>тод P r in t D u c k s ( ) ) , изм <strong>е</strong>нятся соотв<strong>е</strong>тствую щ им образом.<br />

д ^ * т л • 1\ I •<br />

Дооаоим М<strong>е</strong>тоу ToStringO ^ объбкшу Card<br />

Вы до сих пор мож<strong>е</strong>т<strong>е</strong> вызывать<br />

м<strong>е</strong>тод ToStringO таким<br />

„<br />

С в о й ств о Name объ<strong>е</strong>кта C a rd возвращ а<strong>е</strong>т им я ка р ты :<br />

способом, но т<strong>е</strong>п<strong>е</strong>рь вы зна<strong>е</strong>т<strong>е</strong>,<br />

ч т о в этом н<strong>е</strong>т н<strong>е</strong>обходимо -<br />

p u b l i c s t r i n g Name<br />

I<br />

как оп<strong>е</strong>ратор + вызыва<strong>е</strong>т<br />

<strong>е</strong>го автоматич<strong>е</strong>ски.<br />

^ g e t { r e t u r n V a lu e . T o S t r in g O + " o f " + S u i t . T o S t r i n g O ; }<br />

В о т ч т о долж <strong>е</strong>н д<strong>е</strong>лать м<strong>е</strong>тод T o S t r i n g ( ) . П о это м у добавьт<strong>е</strong> <strong>е</strong>го к классу C a rd :<br />

p u b l i c o v e r r i d e s t r i n g T o S t r i n g O<br />

^<br />

функции м<strong>е</strong>тода ToStringO н<strong>е</strong><br />

r e t u r n N am e;<br />

ограничиваются ид<strong>е</strong>нтификаци<strong>е</strong>й<br />

} ваших объ<strong>е</strong>ктов в ИСР. В сл<strong>е</strong>дуюш,их<br />

главах мы рассмотрим пр<strong>е</strong>-<br />

Т<strong>е</strong>п<strong>е</strong>рь ваш и п р о гр а м м ы , использую щ и <strong>е</strong> о б ъ <strong>е</strong> кты C a rd , имуш,<strong>е</strong>ства, которы<strong>е</strong> да<strong>е</strong>т пр<strong>е</strong>м<br />

о ж н о л <strong>е</strong> гко отладить.<br />

образовани<strong>е</strong> объ<strong>е</strong>ктов в строки.<br />

366 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

инт<strong>е</strong>рф<strong>е</strong>йс IEnum erable<br />

Д и кЛ ГоГ<strong>е</strong>аЛ Под<br />

уБ<strong>е</strong>ЛиЧитп<strong>е</strong>ЛьНыМ свд<strong>е</strong>КЛоМ<br />

Н а й д и т<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м <strong>е</strong> н н ую L is t < D u c k > и воспользуйт<strong>е</strong>сь ф у н кц и <strong>е</strong> й In te lliS e n se<br />

A nflpaccM O T peH H H M eT O flaG etE num erator { ) . Н а п <strong>е</strong> ч а т а й т <strong>е</strong> « .G e tE n u m e ra to r»<br />

и п о с м о тр и т<strong>е</strong> на о ткр ы вш <strong>е</strong> <strong>е</strong> ся м <strong>е</strong>ню :<br />

ducks.GetEnumerator<br />

6etEftume»tor<br />

Инициализаторы<br />

колл<strong>е</strong>кций работ аю т<br />

с ЛЮБЫМ объ<strong>е</strong>ктом<br />

>Епит<strong>е</strong>тЬ1<strong>е</strong>!<br />

List .Ermmeratof List< D uck> .GetEnum eratorO<br />

Returns an enumerator that iterates through the System.CoHectrar»s.Gcneric.L»st.<br />

С оздайт<strong>е</strong> н о в ы й м ассив о б ъ <strong>е</strong> кто в Duck:<br />

D u c k [] d u c k A r r a y = n ew D u c k [ 6 ] ;<br />

Н а п <strong>е</strong> чата й т<strong>е</strong> d u c k A r r a y .G e t E n u m e r a t o r , в<strong>е</strong>дь у массива им <strong>е</strong><strong>е</strong>тся д а н н ы й м<strong>е</strong>тод. Э то связано с т<strong>е</strong>м,<br />

ч т о о б ъ <strong>е</strong> кты L i s t , как и м ассивы , р<strong>е</strong>ализую т и н т <strong>е</strong> р ф <strong>е</strong> й с 1 Е п ш п <strong>е</strong> г а Ы <strong>е</strong> < Т > , со д <strong>е</strong> рж ащ ий <strong>е</strong> д и н ств <strong>е</strong> н н ы й<br />

м<strong>е</strong>тод G e t E n u m e r a t o r { ) , во звращ а ю щ и й э л <strong>е</strong> м <strong>е</strong> н т п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и я .<br />

Э то объ<strong>е</strong>кт E n u m e r a to r , о б <strong>е</strong> сп <strong>е</strong> ч и в а ю щ и й м <strong>е</strong>ханизм п<strong>е</strong>р<strong>е</strong>бора ко л л <strong>е</strong> кц и и . Р ассм отрим ц и кл f o r e a c h ,<br />

п р о с м а тр и в а ю щ и й к о л л <strong>е</strong> кц и ю L is t < D u c k > с п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й du ck :<br />

f o r e a c h (D u ck d u c k i n d u c k s ) { Р<strong>е</strong>ализуя инт<strong>е</strong>рф<strong>е</strong>йс<br />

co „ .o ie .w rit.Li» M d u = k ),<br />

IEnumerable,<br />

К од, скр ы в а ю щ и й ся за эти м ц икл ом :<br />

I E n u m e r a to r < D u c k > e n u m e r a t o r = d u c k s . G e t E n u m e r a t o r { ) ;<br />

w h i l e ( e n u m e r a t o r .M o v e N e x t 0 ) {<br />

D u ck d u c k = e n u m e r a t o r . C u r r e n t ;<br />

C o n s o l e . W r i t e L i n e ( d u c k ) ;<br />

}<br />

I D i s p o s a b l e d i s p o s a b l e = e n u m e r a t o r a s I D i s p o s a b l e ;<br />

i f ( d i s p o s a b l e != n u l l ) d i s p o s a b l e . D i s p o s e ( ) ;<br />

колл<strong>е</strong>кция пр<strong>е</strong>доставля<strong>е</strong>т<br />

цикл, п<strong>е</strong>р<strong>е</strong>бираюпщй<br />

<strong>е</strong><strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

по оч<strong>е</strong>р<strong>е</strong>ди.<br />

(Н <strong>е</strong> б <strong>е</strong> спокойт<strong>е</strong>сь, ч т о вы н<strong>е</strong> поним а <strong>е</strong> т<strong>е</strong> п о сл<strong>е</strong>дних двух стр о к, с инт<strong>е</strong>рф <strong>е</strong>йсом^^ ^<br />

I D i s p o s a b l e вы п о зн а ко м и т<strong>е</strong> сь в глав<strong>е</strong> 9.)<br />

Зд<strong>е</strong>сь написан<br />

н<strong>е</strong> в<strong>е</strong>сь код, но<br />

Э т и два кода вы водят о д и н и т о т ж <strong>е</strong> с п и с о к уто к. М о ж <strong>е</strong> т<strong>е</strong> п р о в <strong>е</strong> р и т ь сам остоят<strong>е</strong>льно, в данном случа<strong>е</strong><br />

главно<strong>е</strong>, чтобы<br />

П р и ц и кл и ч <strong>е</strong> ско м п р о см о тр <strong>е</strong> колл<strong>е</strong>кц и и и л и м ассива м<strong>е</strong>тод M o v e N e x t () возвращ а- поняли<br />

<strong>е</strong>т зн ач<strong>е</strong>ни<strong>е</strong> true п р и н а л и ч и и сл<strong>е</strong>дую щ <strong>е</strong>го эл<strong>е</strong>м <strong>е</strong>нта и зн ач<strong>е</strong>ни<strong>е</strong> false, <strong>е</strong>сли д о с т и гн у т основную ид<strong>е</strong>Ю-<br />

п о сл<strong>е</strong>дний эл<strong>е</strong>м<strong>е</strong>нт. С во й ств о C u r r e n t вс<strong>е</strong>гда возвращ а<strong>е</strong>т ссы лку на т<strong>е</strong> к у щ и й эл<strong>е</strong>м<strong>е</strong>нт.<br />

А ц и к л f o r e a c h о б ъ <strong>е</strong>диня<strong>е</strong>т указанны <strong>е</strong> ф ун кц и и !<br />

Поэксп<strong>е</strong>тм<strong>е</strong>нтиюийт<strong>е</strong>, заставив м<strong>е</strong>тод ToStringO объ<strong>е</strong>кта Риск ув<strong>е</strong>личивать свойство Size на <strong>е</strong>динтУ-<br />

Запустит<strong>е</strong> отладку и нав<strong>е</strong>дит<strong>е</strong> указат<strong>е</strong>ль мыши на имя Риск. Прод<strong>е</strong>лайт<strong>е</strong> это н<strong>е</strong>сколько раз. ПомниmCj<br />

что кажЭь>!й рдз буд<strong>е</strong>т вi:?(3t>iвamtfcя м<strong>е</strong>тод ToSt\rmg().<br />

Как вы дума<strong>е</strong>т<strong>е</strong>, что буд<strong>е</strong>т происходить при выполн<strong>е</strong>нии цикла foreach, <strong>е</strong>сли м<strong>е</strong>тод ToStringO<br />

м<strong>е</strong>ня<strong>е</strong>т одно из пол<strong>е</strong>й объ<strong>е</strong>кта?<br />

дальш<strong>е</strong> > 367


никого кром<strong>е</strong> уток!<br />

Восходящ<strong>е</strong><strong>е</strong> прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> с помои^ью lEnumerable<br />

П о м н и т <strong>е</strong> о в о з м о ж н о с т и в о с х о д я щ <strong>е</strong> го п р и в <strong>е</strong> д <strong>е</strong> н и я о б ъ <strong>е</strong> кто в к базовом у<br />

классу? П р и р а б о т<strong>е</strong> с о б ъ <strong>е</strong> кта м и L i s t эту о п <strong>е</strong> р а ц и ю м о ж н о п р о д <strong>е</strong> л а ть для<br />

в с<strong>е</strong>й к о л л <strong>е</strong> к ц и и . Э то н азы ва<strong>е</strong>тся к о в а р и а ц и <strong>е</strong> й ( c o v a r ia n c e ), и вам п о тр <strong>е</strong> б у ­<br />

<strong>е</strong>тся т о л ь к о ссы л ка на и н т <strong>е</strong> р ф <strong>е</strong> й с I E n u m e r a b le < T > .<br />

С оздайт<strong>е</strong> консольно<strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> и в н<strong>е</strong>м базовы й класс B i r d (<strong>е</strong>го продолж <strong>е</strong>­<br />

н и<strong>е</strong>м буд<strong>е</strong>т класс D uck) и п р о и зв о д н ы й класс P e n g u in . Воспользу<strong>е</strong>мся м<strong>е</strong>тодом<br />

T o S t r i n g ( ) , ч то б ы п онять, гд<strong>е</strong> какой класс.<br />

Name<br />

FlyO<br />

_<br />

Bird<br />

c l a s s B ir d {<br />

}<br />

p u b l i c s t r i n g Name { g e t ; s e t ; }<br />

p u b l i c v o i d F ly O {<br />

}<br />

C o n s o le . W r it e L in e ( "П ол<strong>е</strong>т<strong>е</strong>ли!" );<br />

p u b l i c o v e r r id e s t r i n g T o S tr in g O {<br />

r e t u r n "Имя птицы " + Name;<br />

}<br />

c l a s s P en g u in : B ir d<br />

{<br />

p u b l i c v o i d F ly O {<br />

}<br />

C o n s o le .W r it e L in e ("Пингвины н<strong>е</strong> л<strong>е</strong>таю т!'<br />

p u b l i c o v e r r id e s t r i n g T o S tr in g O {<br />

r e t u r n "Имя пингвина " + b ase.N am e;<br />

}<br />

S ize<br />

Kind<br />

Duck<br />

Penguin<br />

Это класс Bird и насл<strong>е</strong>дующий от н<strong>е</strong>го<br />

класс Penguin. Добавьт<strong>е</strong> ик в новый<br />

про<strong>е</strong>кт типа Console Application, зат<strong>е</strong>м<br />

скопируйт<strong>е</strong> туда ж<strong>е</strong> сущ<strong>е</strong>ствующий<br />

класс Риск, пом<strong>е</strong>няв соотв<strong>е</strong>тствующим<br />

образом <strong>е</strong>го объявл<strong>е</strong>ни<strong>е</strong>.<br />

Л<br />

c l a s s Duck ; B ir d , IC om parable {<br />

/ / О стальной код б <strong>е</strong> з изм<strong>е</strong>н<strong>е</strong>ний<br />

}<br />

В о т п<strong>е</strong>рвы <strong>е</strong> с т р о к и м <strong>е</strong>тода M a in { ) , и н и ц и а л и з и р у ю щ и <strong>е</strong> ко л л <strong>е</strong> к ц и ю и о с у щ <strong>е</strong> с т в л я ю щ и <strong>е</strong> <strong>е</strong> <strong>е</strong> в о с х о д я ­<br />

щ <strong>е</strong> <strong>е</strong> п р и в <strong>е</strong> д <strong>е</strong> н и <strong>е</strong> .<br />

^ ------- ^<br />

, . , ^ , , , , ^ с к о п и р у й т <strong>е</strong> и н и ц и а л и з а т о р д л я к о л л <strong>е</strong> к ц и и ц т о к<br />

L ist< D u ck > du ck s = new L ist< D u c k > () { /* инициализируйт<strong>е</strong> о бъ <strong>е</strong>к т, как обычно * / }<br />

IE n um erab le< B ird> u p ca stD u c k s = d u ck s;<br />

П о с м о тр и т <strong>е</strong> на п о сл<strong>е</strong>дню ю строчку. С сы лку на ко л л <strong>е</strong> к ц и ю L is t < D u c k > в ы п р исваива<strong>е</strong>т<strong>е</strong> и н т <strong>е</strong> р ф <strong>е</strong> й с­<br />

н о й п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й lE n u m e r a b le < B ir d > . З апустит<strong>е</strong> отладку и уб<strong>е</strong>дит<strong>е</strong>сь, ч т о об<strong>е</strong> ссы л ки указы ваю т на<br />

о д и н и т о т ж <strong>е</strong> объ<strong>е</strong>кт.<br />

Объ<strong>е</strong>диним птиц 6 <strong>е</strong>диную колл<strong>е</strong>кцию<br />

К овариация позволя<strong>е</strong>т добавлить частную колл<strong>е</strong>кц ию к бол<strong>е</strong><strong>е</strong> общ <strong>е</strong>й. С каж<strong>е</strong>м, в колл<strong>е</strong>кц ию объ<strong>е</strong>ктов B i r d<br />

м о ж н о добавить колл<strong>е</strong>кц ию D uck. Вам п р и го д и тся м<strong>е</strong>тод L i s t . A d d R a n g e ''<br />

L is t< B ir d > b i r d s = new L i s t < B ir d > 0 ;<br />

b ir d s.A d d (n e w B ir d O { Name = "П<strong>е</strong>рнаты<strong>е</strong>" } ) ;<br />

b ir d s .A d d R a n g e (u p c a s tD u c k s );<br />

b ir d s.A d d (n e w P e n g u in () { Name = "<strong>Дж</strong>ордж" } ) ;<br />

fo r e a c h (B ird b ir d i n b ir d s ) (благодаря восходящ<strong>е</strong>му пюив<strong>е</strong>-<br />

C o n so ole l e .Wrrit i te eL Lin ine e ( biirr d ) ; д<strong>е</strong>нию y m o K К IEnumerahle


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Создани<strong>е</strong> п<strong>е</strong>р<strong>е</strong>гру)к<strong>е</strong>нньіх м<strong>е</strong>тодоВ<br />

В ы уж <strong>е</strong> исп ользовали н<strong>е</strong> т о л ь к о п <strong>е</strong> р <strong>е</strong> г р у ж <strong>е</strong> н н ы <strong>е</strong> м <strong>е</strong> т о д ы , н о и п<strong>е</strong>р<strong>е</strong>груж<br />

<strong>е</strong> н н ы й к о н с тр у к т о р , к о т о р ы й б ы л ч а стью в с т р о <strong>е</strong> н н о го класса .NET.<br />

С ловом , вы уж <strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, н аско л ь ко п о л <strong>е</strong> зн о й явля<strong>е</strong>тся эта ф ун кц и я . Х о ­<br />

т<strong>е</strong> л и б ы вы встраивать п <strong>е</strong> р <strong>е</strong> гр уж <strong>е</strong> н н ы <strong>е</strong> м <strong>е</strong>тоды в ваш и собств<strong>е</strong>нны <strong>е</strong><br />

классы? Э то л <strong>е</strong> гко м о ж н о сд<strong>е</strong>лать! Д о с та т о ч н о н а п и са ть два и бол<strong>е</strong><strong>е</strong><br />

о д н о и м <strong>е</strong> н н ы х м <strong>е</strong>тодов с р а зл и ч н ы м и парам <strong>е</strong>трам и.<br />

Вм<strong>е</strong>сто р<strong>е</strong>дактирования<br />

■ / — vt/vic-rf >^м<strong>е</strong>н лчс>; 2 ж н о<br />

спользоЬать оп<strong>е</strong>ратор.<br />

- У п р а ж н <strong>е</strong> н и <strong>е</strong> !<br />

О<br />

О<br />

Создайт<strong>е</strong> новый про<strong>е</strong>кт и добавьт<strong>е</strong> в н<strong>е</strong>го класс C ard.<br />

Э то л <strong>е</strong> гк о сд<strong>е</strong>лать, щ <strong>е</strong>лкнув п р а в о й к н о п к о й м ы ш и на и м <strong>е</strong> н и п р о <strong>е</strong> к та в о кн <strong>е</strong> S o lu tio n E x p lo re r<br />

и вы брав в а р и а н т E x is tin g Ite m в м <strong>е</strong>ню A d d . И С Р д о б а вит в п р о <strong>е</strong> к т к о п и ю класса. Н о п р и<br />

этом о н о с т а н <strong>е</strong> т с я в п р о с т р а н с т в <strong>е</strong> и м <strong>е</strong> н с т а р о го п р о <strong>е</strong> к т а , п о это м у о т к р о й т <strong>е</strong> ф айл C a r d . e s<br />

и о тр <strong>е</strong> д а кти р уй т<strong>е</strong> с тр о ч к у n a m e s p a c e . А н а л о ги ч н у ю о п <strong>е</strong> р а ц и ю прод<strong>е</strong>лайт<strong>е</strong> для V a lu e s<br />

и S u T ts ^<br />

Б<strong>е</strong>з этой оп<strong>е</strong>рации для доступа к классу Card потр<strong>е</strong>бу<strong>е</strong>т-<br />

. ся указывать пространство им<strong>е</strong>н в явном вид<strong>е</strong> (наприм<strong>е</strong>р,<br />

oldnamespace.Card).<br />

Т<strong>е</strong>п<strong>е</strong>рь добавим в класс C ard новы<strong>е</strong> п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нны <strong>е</strong> м<strong>е</strong>тоды .<br />

С оздайт<strong>е</strong> два с та т и ч <strong>е</strong> с к и х м <strong>е</strong>тода D o e s C a r d M a tc h ( ) . П <strong>е</strong> р в ы й буд<strong>е</strong>т п р о в <strong>е</strong> р я ть м асть ка р ты ,<br />

а в т о р о й - ста р ш и н ств о . О б а м <strong>е</strong>тода возвращ аю т зн ач<strong>е</strong>ни<strong>е</strong> tru e п р и со в п ад<strong>е</strong>нии карт.<br />

p u b l i c s t a t i c b o o l D oesC ardM atch(C ard cardT oC heck, S u i t s s u i t ) {<br />

i f (c a rd T o C h e ck .S u it == s u i t ) {<br />

r e t u r n tr u e ;<br />

} e l s e {<br />

r e t u r n f a l s e ;<br />

}<br />

]<br />

p u b l i c s t a t i c b o o l D oesC ardM atch(C ard cardT oC heck,<br />

}<br />

i f (ca rd T o C h eck .V a lu e == v a lu e ) {<br />

r e t u r n t r u e ;<br />

e l s e {<br />

r e t u r n<br />

f a l s e ;<br />

Добавьт<strong>е</strong> к цю рм<strong>е</strong> кнопку, использую щ ую оба м <strong>е</strong>тода.<br />

В о т код э т о й к н о п к и :<br />

П<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нны<strong>е</strong> м<strong>е</strong>тоды н<strong>е</strong> обязаны быть<br />

статич<strong>е</strong>скими, но мы р<strong>е</strong>шили, что<br />

Ьам буд<strong>е</strong>т пол<strong>е</strong>зно попрактиковаться<br />

о написании статич<strong>е</strong>ских м<strong>е</strong>тодов.<br />

V a lu e s v a lu e ) {<br />

К я к работа<strong>е</strong>т проц<strong>е</strong>дура п<strong>е</strong>р<strong>е</strong>грузки,<br />

вид<strong>е</strong>ли (и в п р о г р а м і d f рсксч<strong>е</strong>та стоимости<br />

в<strong>е</strong>ч<strong>е</strong>ринок^из главы &, там<br />

п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нный м<strong>е</strong>тод CalculateCostO о класс<br />

PinnerParty.<br />

Card cardT oC heck = new C a r d ( S u it s .C lu b s , V a l u e s .T h r e e ) ;<br />

b o o l d o e sI tM a tc h = C a r d . D oesC ardM atch(cardT oC heck, S u i t s . H e a r t s ) ;<br />

M essageB ox. Show (d o e s I tM a tc h .T o S tr in g ()A|j^^g ToStnnaO нуж<strong>е</strong>н, так как парам<strong>е</strong>тр м<strong>е</strong>тода<br />

^ ------------ MeisaqeBox.ShowQ долж<strong>е</strong>н принадл<strong>е</strong>жать к типу stn у.<br />

К а к то л ь к о буд<strong>е</strong>т н а п <strong>е</strong> чатано D o e s C a r d M a tc h ( ) , И С Р покаж <strong>е</strong>т, ч т о вы д <strong>е</strong> й ств и т<strong>е</strong> л ь н о н а п и ­<br />

сали п <strong>е</strong> р <strong>е</strong> гр у ж <strong>е</strong> н н ы й м<strong>е</strong>тод;<br />

C a rd .D o e s C a rd M a tc h (<br />

, l o f 2 ▼ b o o l C a rd .D o e s C a rd H a tc h (C a rd ca rd T o C tie ck^ S u it s s u i t ) |<br />

П о э к с п <strong>е</strong> р и м <strong>е</strong> н ти р у й т <strong>е</strong> с э ти м и м <strong>е</strong>тодам и, ч т о б ы п р и в ы к н у ть к работ<strong>е</strong>.<br />

дальш<strong>е</strong> * 369


колоду на стол<br />

і а ж н <strong>е</strong> н и <strong>е</strong><br />

П опрактику<strong>е</strong>м ся в прим <strong>е</strong>н<strong>е</strong>нии объ<strong>е</strong>ктов L i s t , созд ав класс д ля хран<strong>е</strong>ния<br />

колоды карты и форму, которая буд<strong>е</strong>т <strong>е</strong>го использовать.<br />

^ §орм а. позволяющая п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щать карты м <strong>е</strong>ж ду колодами<br />

Создадим класс D e c k (К о лода) для х р а н <strong>е</strong> н и я п р о и з в о л ь н о го ко л и ч<strong>е</strong>ства карт. В р<strong>е</strong>альной ко л о ­<br />

д<strong>е</strong> 52 ка р ты , н о в класс<strong>е</strong> D e c k м о ж <strong>е</strong> т б ы ть ско л ь ко уго д н о к а р т (и л и н<strong>е</strong> б ы ть н и о д н о й ).<br />

Зат<strong>е</strong>м вам п о тр <strong>е</strong>бу<strong>е</strong>тся ф орм а, показы ваю щ ая сод<strong>е</strong>рж им о<strong>е</strong> двух объ <strong>е</strong>ктов D eck . П р и п<strong>е</strong>рвом<br />

запуск<strong>е</strong> п р о гр а м м ы в колод<strong>е</strong> #1 м о ж <strong>е</strong> т б ы ть до 10 сл уч а й н ы х карт, а в колод<strong>е</strong> #2 — п о л н ы й наб<br />

ор (52 к а р ты ). О б <strong>е</strong> колод ы о т с о р т и р о в а н ы п о м асти и п о с та р ш и н с тв у В э то п о л о ж <strong>е</strong> н и <strong>е</strong> ко л о ­<br />

ду м о ж н о в<strong>е</strong> р н уть в л ю б о й м о м <strong>е</strong> н т щ <strong>е</strong>лчком на к н о п к <strong>е</strong> Reset. Т акж <strong>е</strong> ф орм а снабж <strong>е</strong>на кн о п ка м и<br />

« и » , ко то р ы <strong>е</strong> п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>щ а ю т к а р ты из о д н о й ко л о д ы в другую .<br />

П омнит<strong>е</strong>, что с пом ощ ью<br />

свойства Nam e эл<strong>е</strong>м <strong>е</strong>нту<br />

управл<strong>е</strong>ния можно присвоить<br />

имя, улучш ив т<strong>е</strong>м сам ы м читаб<strong>е</strong>льность<br />

кода. При двойном<br />

щ <strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> обработчику<br />

собы тий буд<strong>е</strong>т д ан о соотв<strong>е</strong>тствую<br />

щ <strong>е</strong><strong>е</strong> имя.<br />

Обратит<strong>е</strong><br />

внимани<strong>е</strong>,<br />

как карты<br />

добавляются<br />

в колл<strong>е</strong>кцию<br />

при помощи<br />

цикла foreach.<br />

Кнопки моу<strong>е</strong>ТоР<strong>е</strong>скЯ (в<strong>е</strong>рхняя) и тоу<strong>е</strong>ТоР<strong>е</strong>ск! (нижняя)<br />

п<strong>е</strong>рш<strong>е</strong>ьцаким. карты из одной колоды в другую.<br />

Кнопки reseti и resetz<br />

сначала вызывают<br />

м<strong>е</strong>тод ResetDeckQ,<br />

а потом м<strong>е</strong>тод<br />

R-edrawPeckQ.<br />

Д л я показа об<strong>е</strong>их колод используются<br />

два эл<strong>е</strong>м<strong>е</strong>нта<br />

ustBox. При щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong><br />

^o v ero P eckl выбранная карта<br />

^п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ща<strong>е</strong>тся из колоды J z<br />

о колоду<br />

Им<strong>е</strong>на этих кнопок shuffle! и<br />

shuffieZ. Они вызывают п о ­<br />

ходящий м<strong>е</strong>тод P e c k .S K M rn 6 ()j<br />

чтобы п<strong>е</strong>р<strong>е</strong>тасовать колоду,<br />

а зат<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>рисовывают <strong>е</strong><strong>е</strong>.<br />

Д обавить к ф орм<strong>е</strong> нуж н о н<strong>е</strong> только о б р а б о тчики с о б ы ти й для ш <strong>е</strong>сти к н о п о к, н о и два м<strong>е</strong>тода.<br />

Н а ч н и т<strong>е</strong> с м<strong>е</strong>тода R e s e t D e c k ( ) , возвращ аю щ <strong>е</strong>го колоду в исходно<strong>е</strong> состояни<strong>е</strong>. В кач<strong>е</strong>ств<strong>е</strong> парам<br />

<strong>е</strong>тра о н использу<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> ти п а in t: <strong>е</strong>сли <strong>е</strong>му п<strong>е</strong>р<strong>е</strong>дать 1, о н пр<strong>е</strong>вращ а<strong>е</strong>т п<strong>е</strong>рвы й объ<strong>е</strong>кт D e ck<br />

в пустую колоду, а зат<strong>е</strong>м случайны м образом назнача<strong>е</strong>т <strong>е</strong>й 10 карт; п<strong>е</strong>р<strong>е</strong>дав знач<strong>е</strong>ни<strong>е</strong> 2, вы пр<strong>е</strong>врати<br />

т<strong>е</strong> в то р о й объ<strong>е</strong>кт D e c k в упорядоч<strong>е</strong>нную колоду из 52 карт:<br />

p r i v a t e v o id R ed raw D eck (i n t DeckNumber) {<br />

i f (DeckNumber = = 1 ) { —<br />

l i s t B o x l . I t e m s . C l e a r {);<br />

f o r e a c h ( s t r i n g cardName i n d e c k l.G etC a rd N a m e s())<br />

l ^ t B o x l . Ite m s .Add (cardName) ;<br />

l a b e l l . T e x t = "Deck #1 (" + d e c k l.C o u n t + " c a r d s)<br />

} e l s e {<br />

}<br />

l i s t B o x 2 . I t e m s . C l e a r ( );<br />

f o r e a c h ( s t r i n g cardName i n d e c k 2 . G etC ardN am es())<br />

l i s t B o x 2 . Ite m s.A d d (ca r d N a m e);<br />

l a b e l 2 . T e x t = "Deck #2 (" + d e c k 2 .C o u n t + " c a r d s)<br />

М<strong>е</strong>тод RedrawPeck()<br />

Т к и 2 Т скива<strong>е</strong>т из н<strong>е</strong><strong>е</strong> случай-<br />

« обновля<strong>е</strong>т<br />

сод<strong>е</strong>ржимо<strong>е</strong> т<strong>е</strong>кстовых<br />

соотв<strong>е</strong>тствии<br />

обм<strong>е</strong>ном.


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

С о здани<strong>е</strong> к л а с с а b e c k<br />

«Основой» мы назвали объявл<strong>е</strong>ни<strong>е</strong> класса<br />

б<strong>е</strong>з <strong>е</strong>го р<strong>е</strong>ализации.<br />

П р ш а д л <strong>е</strong> ж н о с ! ^ ^<br />

В о т о сн о в а класса D eck . М ы н ап исал и за вас н<strong>е</strong>скольк о м <strong>е</strong>тодов . Вам остал ось д обав и ть м <strong>е</strong>­<br />

то д ы S h u f f l e {) и G etC a rd N a m es () и заставить р аботать м <strong>е</strong>то д S o r t ( ) . М ы д обав и л и два<br />

п <strong>е</strong> р <strong>е</strong> г р у ж <strong>е</strong> н н ы х к о н с т р у к т о р а : со зд а ю щ и й колоду и з 52 карт и загр уж аю щ ий в колоду с о ­<br />

д <strong>е</strong> р ж и м о <strong>е</strong> м ассива о б ъ <strong>е</strong>к то в C ard.<br />

^ Класс Р<strong>е</strong><strong>е</strong>к хранит объ<strong>е</strong>кмы в колл<strong>е</strong>кции List, при<br />

ш ^ t t л ^ шt ш, Л O^fy* АЛ L^t л й^1 АЛ I й<br />

f этом они являются закрытыми.<br />

c l a s s Deck {<br />

p r i v a t e L ist< C a rd > . beards; ’c a r d s ;<br />

_ „ ______ ______д<br />

p r i v a t e Random random = new Random() , создана б<strong>е</strong>з п <strong>е</strong> р <strong>е</strong> у ч и n a ~<br />

p u b lic D eck О { / рам<strong>е</strong>тров конструктору.<br />

c a r d s = new L is t< C a r d > { );<br />

парам<strong>е</strong>тра К s u i t = 0; s u i t ( i n i t i a l C a r d s ) ;<br />

цию, a н<strong>е</strong> moAix<br />

ко List или<br />

массив. p u b l i c i n t C ount { g e t { r e t u r n c a r d s .C o u n t;<br />

^<br />

p u b l i c v o id A d d (Card cardToAdd) { М<strong>е</strong>тод Peal (Раздача) ^^арты в к о л л <strong>е</strong> к ц и и . Его<br />

c a r d s .A d d (cardToAdd)<br />

Шда<strong>е</strong>т одну карту J^oжнo п<strong>е</strong>р<strong>е</strong>дать м <strong>е</strong> т о -<br />

}<br />

-------колоды, он удаля<strong>е</strong>т peai(). Если карта<br />

4 : объ<strong>е</strong>кт Card и возвра- выбрана, знач<strong>е</strong>ни<strong>е</strong><br />

( V a l u e s ) v a l u e ) )<br />

П<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нный конструктор в кач<strong>е</strong>ств<strong>е</strong><br />

парам<strong>е</strong>тра б<strong>е</strong>р<strong>е</strong>т массив<br />

{ карт, загружая <strong>е</strong>го в исходную<br />

колоду.<br />

___У Подсказка Свойство<br />

, , Selectedlndex эл<strong>е</strong>м <strong>е</strong>нi<br />

J<br />

управл<strong>е</strong>ний LiStBoK<br />

совпада<strong>е</strong>т с<br />

инд<strong>е</strong>ксом<br />

p u b l i c Card D e a l ( i n t in d ex ) { Ща<strong>е</strong>т ссылку .................... на н<strong>е</strong>го. м<strong>е</strong>ньил<strong>е</strong> нуля и м<strong>е</strong>тод<br />

Card C ardToD eal = c a r d s [ i n d e x ] ;П<strong>е</strong>р<strong>е</strong>да6 О , вы сдади-<br />

moveToPeck н<strong>е</strong> работа<strong>е</strong>т.<br />

c a r d s . R em oveA t(in dex)<br />

r e t u r n C ard T oD eal;<br />

Хотя м<strong>е</strong>тод \<br />

detCardNamesO<br />

возвраща<strong>е</strong>т p u b l i c v o id S h u f f l e () {<br />

т<strong>е</strong> в<strong>е</strong>рхнюю карту<br />

колоды. Чтобы сдать<br />

любую другую карту,<br />

укажит<strong>е</strong> <strong>е</strong><strong>е</strong> инд<strong>е</strong>кс.<br />

массив, мы I I м <strong>е</strong>тод т а с у <strong>е</strong> т карты, м<strong>е</strong>няя их порядок случайным образом<br />

да<strong>е</strong>м доступ j<br />

к lE n u m e - " '^ _________ ^<br />

r a b l e < S t r i n y > . IE n u m e ra b le < strin g > G etC ard N am es() {<br />

/ / м <strong>е</strong>тод возвращ а<strong>е</strong>т м ассив типа s t r i n g с им<strong>е</strong>нами в с <strong>е</strong> х карт<br />

}<br />

p u b l i c v o id S o r t O {<br />

c a r d s . S o r t(n e w C a rd C o m p a rer_ b y S u it())<br />

}<br />

Ещ<strong>е</strong> одна подскока: Прот<strong>е</strong>стировать м<strong>е</strong>тод SkuffleO можпомощью<br />

формы. Щ<strong>е</strong>лкайт<strong>е</strong> на кнопк<strong>е</strong> "Reset Peck<br />

пока н<strong>е</strong> получит<strong>е</strong> колоду из тр<strong>е</strong>х карт. В этом слича<strong>е</strong> л<strong>е</strong>гко<br />

уб<strong>е</strong>диться, что м<strong>е</strong>тод п<strong>е</strong>р<strong>е</strong>тасовки работа<strong>е</strong>т.<br />

Вам нужно написать м <strong>е</strong>т о-<br />

’ V ды SkuffleO и GetCardNamesQ,<br />

а такж<strong>е</strong> добавить класс, р <strong>е</strong> ­<br />

ализующий IComparer, чтобы<br />

заставить работать м<strong>е</strong>тод<br />

Sort(). Кром<strong>е</strong> того, потр<strong>е</strong>бу-^<br />

<strong>е</strong>тся добавить уж<strong>е</strong> написанный<br />

класс Card. Если вы буд<strong>е</strong>т<strong>е</strong><br />

д<strong>е</strong>лать это командой Add<br />

Existing Item, н<strong>е</strong> забудьт<strong>е</strong> о т ­<br />

р<strong>е</strong>дактировать пространство<br />

им<strong>е</strong>н.<br />

дальш<strong>е</strong> * 371


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

іажн<strong>е</strong>ни<strong>е</strong><br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

c l a s s Deck {<br />

В о т код д ля класса, хранящ <strong>е</strong>го инф о р м ацию о колод<strong>е</strong> карт, а такж<strong>е</strong> д л я использую<br />

щ <strong>е</strong>й этот класс ф орм ы<br />

p r i v a t e L ist< C a rd > c a r d s;<br />

p r i v a t e Random random = new Random( );<br />

p u b l i c D eckO {<br />

}<br />

c a r d s = new L ist () ;<br />

f o r ( i n t s u i t = 0; s u i t ( i n i t i a l C a r d s ) ;<br />

}<br />

p u b l i c i n t Count { g e t { r e t u r n c a r d s.C o u n t;<br />

p u b l i c v o id Add(Card cardToAdd) {<br />

}<br />

c a r d s.A d d (c a r d T o A d d );<br />

p u b l i c Card D e a l ( i n t in d ex ) {<br />

Card CardToDeal = c a r d s [ in d e x ]<br />

c a r d s . R e m o v e A t(in d e x );<br />

r e t u r n C ardT oD eal;<br />

}<br />

p u b lic v o id S h u f f l e 0 {<br />

}<br />

L ist< C a rd > NewCards = new L is t< C a r d > ( ) ; -----<br />

w h ile (c a r d s.C o u n t > 0 ) {<br />

i n t CardToMove = r a n d o m .N e x t(c a r d s . Count)<br />

N ew C ard s.A d d (card s[C ard T oM ove]);<br />

c a r d s . Rem oveA t(C ardT oM ove);<br />

}<br />

c a r d s = NewCards;<br />

p u b lic IE n u m e ra b le < strin g > G etC ardN am es() {<br />

}<br />

s t r i n g [] CardNames = new s t r i n g [ c a r d s . C o u n t];<br />

( i n t i = 0; i < c a r d s .C o u n t; i++ )<br />

C ardN am es[i] = c a r d s [i] .Name;<br />

r e t u r n CardNames;<br />

p u b l i c v o id S o r t O {<br />

c a r d s . S o r t(n e w C a rd C o m p a rer_ b y S u it( ) ) ;<br />

Э т о т конструктор созда<strong>е</strong>т колодц<br />

из SZ карт. Он использу<strong>е</strong>т влож<strong>е</strong>нный<br />

цикл for. Вн<strong>е</strong>шний цикл оси-<br />

^<strong>е</strong>рсбор ч<strong>е</strong>тыр<strong>е</strong>х маст<strong>е</strong>й.<br />

/ ^ ^ ‘^^<strong>е</strong>т ст в<strong>е</strong>нно, внутр<strong>е</strong>нний цикл,<br />

j п<strong>е</strong>р<strong>е</strong>бирающий 13 знач<strong>е</strong>ний карт, за<br />

разу на каждую масть.<br />

<strong>е</strong> с т ь n o<br />

Это второй конструктор.<br />

-------- Данны й класс сод<strong>е</strong>ржит<br />

два п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нных конструктора<br />

с различными<br />

J J парам<strong>е</strong>трами.<br />

^^oд Add ^ л і<strong>е</strong> -<br />

" с им<strong>е</strong>н<strong>е</strong>м NewCards<br />

ИЗ п о л я Cards и пом<strong>е</strong>ш,а<strong>е</strong>т в к м -<br />

СагГн<strong>е</strong>^‘^"^<br />

^aras н<strong>е</strong> опуст<strong>е</strong><strong>е</strong>т. Посл<strong>е</strong> этого<br />

н о в ' Л ^ Т ' ' ' ^ ^<br />

на старый экз<strong>е</strong>мпляр в итог<strong>е</strong> н<strong>е</strong><br />

оста<strong>е</strong>тся, он удаля<strong>е</strong>тся.<br />

М <strong>е</strong>т о Э й О а С а гс1 Ы а т <strong>е</strong> $ {) нуж н о с о з д а т ь<br />

Ъ ^ а т о ч н о б о л ь ш о й м а с с и в , ч т о б ы в<br />

н <strong>е</strong> го п о м <strong>е</strong> с т и л и с ь и м <strong>е</strong> н а в с <strong>е</strong> х ^<br />

Т т о г Т и с п о л ь з у <strong>е</strong> т с я ц и к л<br />

ч а р <strong>е</strong> ш а <strong>е</strong> м а и с п о М о ш р ю ц и к л а \о г<strong>е</strong>ас)л .<br />

ня<br />

372 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

c l a s s C ardC om parer_bySuit : IComparer<br />

{<br />

p u b l i c<br />

{<br />

i n t Com pare(Card x . Card y)<br />

i f ( x .S u i t > y . S u i t )<br />

r e t u r n 1;<br />

i f ( x .S u i t < y . S u i t )<br />

r e t u r n -1 ;<br />

i f (x .V a lu e > y .V a lu e )<br />

r e t u r n 1;<br />

i f (x .V a lu e < y .V a lu e )<br />

r e t u r n -1 ;<br />

r e t u r n 0;<br />

Deck d e c k l;<br />

D eck d e c k 2 ;<br />

Random random =<br />

new Random()<br />

С о р т и р о в к а no м а с т и н а т м и -<br />

н а <strong>е</strong> т с о р т и р о в к у п о с т а р ш и н ­<br />

с т в у . Е д и н с т в <strong>е</strong> н н о <strong>е</strong> о т л и ч и <strong>е</strong><br />

в т о м , ч т о м а с т и с р а в н и ­<br />

в а ю т с я п <strong>е</strong> р в ы м и , а с р а в н <strong>е</strong> н и <strong>е</strong><br />

знач<strong>е</strong>нии к д р т происходит<br />

т о л ь к о п р и с о в п а д <strong>е</strong> н и и м а с т <strong>е</strong> й .<br />

Вм<strong>е</strong>сто конструкции if/else if<br />

мы использовали набор оп<strong>е</strong>раторов<br />

if. Это работа<strong>е</strong>т, так<br />

как каждьш сл<strong>е</strong>дуюший one<br />

ратор if выполня<strong>е</strong>тся только<br />

в случа<strong>е</strong> н<strong>е</strong>выполн<strong>е</strong>ния пр<strong>е</strong>дыдущ<strong>е</strong>го.<br />

p u b l i c F o r m lО {<br />

I n it ia liz e C o m p o n e n t О ;<br />

}<br />

R e s e tD e c k (1 );<br />

R e s e tD e c k (2 );<br />

R edraw D eck(1 );<br />

R edraw D eck(2 );<br />

Конструктор формы сна<br />

чала возвраща<strong>е</strong>т колоды<br />

в исходно<strong>е</strong> состояни<strong>е</strong> —<br />

п<strong>е</strong>р<strong>е</strong>рисовыва<strong>е</strong>т их.<br />

п о т о м<br />

p r i v a t e v o id R e s e t D e c k ( in t deckNumber) {<br />

}<br />

i f (deckNumber = = 1 ) {<br />

i n t num berO fCards = random .N e x t (1 , 1 1 );<br />

d e c k l = new D eck (new C ard[] { } ) ;<br />

f o r ( i n t i = 0; i < num berO fCards; i++)<br />

d e c k l.A d d (n e w C a r d ( ( S u it s ) r a n d o m .N e x t ( 4 ) ,<br />

(V a lu e s )r a n d o m .N e x t(1, 1 4 ) ) ) ;<br />

d e c k l . S o r t ( );<br />

} e l s e<br />

d eck2 = new D e c k ()<br />

l4emod RedrawPeckQ<br />

вам уж<strong>е</strong> встр<strong>е</strong>чался.<br />

Vпользу<strong>е</strong>тся м<strong>е</strong>тод random Nextn и п . / ’<br />

созда<strong>е</strong>тся пистая<br />

посл<strong>е</strong> ч<strong>е</strong>го<br />

For туда добавляются г ‘^омощи цикла<br />

сл<strong>е</strong>док оста<strong>е</strong>тся пров<strong>е</strong>ст Тгп^',^ карты. Напостановить<br />

колоди ^с>ртировку. Воссоздать<br />

экз<strong>е</strong>мпляр D ecl^ '^Р°'Ч<strong>е</strong>. Достаточно<br />

У <strong>е</strong> р <strong>е</strong> ^ <strong>е</strong> р н и т п <strong>е</strong> с т р а н и ц у и 1 ^ о Д о Л ж и м !<br />

дальш<strong>е</strong> > 373


п<strong>е</strong>р<strong>е</strong>грузка информации<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Присво<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтам управл<strong>е</strong>ния значимых<br />

им<strong>е</strong>н обл<strong>е</strong>гча<strong>е</strong>т чт<strong>е</strong>ни<strong>е</strong> кода. Если бы эти<br />

кнопки назывались ЬиИоп1_СИск, ЬиНоп2_СИск<br />

и т. д., вы н<strong>е</strong> смогли бы сразу опр<strong>е</strong>д<strong>е</strong>лить их<br />

назнач<strong>е</strong>ни<strong>е</strong>!<br />

Э т о<br />

остаилок<br />

кода формы.<br />

p r i v a t e v o i d r e s e t l _ C l i c k ( o b j e c t s e n d e r , E ven tA rgs e)<br />

R e s e tD e c k (1 );<br />

R edraw D eck(1 );<br />

p r i v a t e v o id r e s e t 2 _ C l i c k ( o b j e c t se n d e r , E v en tA rg s e) {<br />

R e s e tD e c k (2 );<br />

R edraw D eck(2 );<br />

}<br />

p r i v a t e v o i d s h u f f l e l _ C l i c k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

d e c k l .S h u f f l e O ;<br />

R edraw D eck(1 );<br />

}<br />

Функция этих<br />

кнопок проста —<br />

сначала восстанооить<br />

или п<strong>е</strong>р<strong>е</strong>тасовать<br />

колоди^<br />

а зат<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>ри-<br />

СОбс{ІАЛ.Ь <strong>е</strong><strong>е</strong>.<br />

p r i v a t e v o id s h u f f l e 2 _ C l i c k ( o b j e c t s e n d e r , E ven tA rgs e)<br />

d e c k 2 .S h u f f le O ;<br />

R edraw D eck(2 );<br />

}<br />

p r i v a t e v o i d m o v e T o D e c k l_ C lic k (o b je c t se n d e r , E ven tA rgs e)<br />

}<br />

i f ( l i s t B o x 2 .S e l e c t e d l n d e x >= 0)<br />

i f (d eck 2 .C o u n t > 0 ) {<br />

}<br />

R edraw D eck(1 );<br />

R edraw D eck(2 );<br />

d e c k l .A d d ( d e c k 2 .D e a l( l i s t B o x 2 . S e l e c t e d l n d e x ) );<br />

p r i v a t e v o i d m o v e T o D e c k 2 _ C lic k (o b je c t se n d e r , E ven tA rgs e)<br />

i f ( l i s t B o x l . S e l e c t e d l n d e x >= 0)<br />

i f (d e c k l.C o u n t > 0)<br />

d e c k 2 . A d d ( d e c k l . D e a l ( l i s t B o x l .S e l e c t e d l n d e x ) );<br />

R edraw D eck(1 );<br />

R edraw D eck(2 );<br />

Свойство Selectedlndex<br />

эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния<br />

ListBox позволя<strong>е</strong>т понять,<br />

какую им<strong>е</strong>нно<br />

{ карту выдрал пользоват<strong>е</strong>ль.<br />

чтобы п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>стить<br />

<strong>е</strong><strong>е</strong>. (Если оно<br />

им<strong>е</strong><strong>е</strong>т отрицат<strong>е</strong>льно<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong>, значит, карта<br />

н<strong>е</strong> выбрана, и кнопка<br />

нич<strong>е</strong>го н<strong>е</strong> д<strong>е</strong>ла<strong>е</strong>т.) Посл<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ния карты<br />

тр<strong>е</strong>бу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>рисовать<br />

об<strong>е</strong> колоды.<br />

374 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Слобари<br />

К о л л <strong>е</strong> к ц и и п о д о б н ы д л и н н ы м стр а н и ц а м , заполн<strong>е</strong>нны м им <strong>е</strong>нам и. А т<strong>е</strong> п <strong>е</strong> р ь пр<strong>е</strong>дставьт<strong>е</strong>, ч т о вы х о т и т <strong>е</strong><br />

с о п о ста в и ть каж дом у и м <strong>е</strong> н и адр<strong>е</strong>с. И л и снабдить ка ж д ы й автом обиль в ваш <strong>е</strong>й ко л л <strong>е</strong> к ц и и описани<strong>е</strong>м .<br />

Для э т о го вам п о тр<strong>е</strong>бу<strong>е</strong> тся с л о в а р ь (d ic tio n a r y ). Э та стр уктур а позволя<strong>е</strong>т взять н <strong>е</strong> к и й к л ю ч (k e y ) и связать<br />

<strong>е</strong> го со з н а ч <strong>е</strong> н и <strong>е</strong> м (v a lu e). К а ж д ы й к л ю ч п р и этом появля<strong>е</strong>тся в словар<strong>е</strong> т о л ь к о о д и н р а з.<br />

3 ^ 0 ключ. Им<strong>е</strong>нно<br />

т а к и щ <strong>е</strong> т с я<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> слова<br />

о обычном словар<strong>е</strong>.<br />

сло-варь<br />

С п и с о к слов в алф авитном порядк<strong>е</strong>^<br />

с объясн<strong>е</strong>ни<strong>е</strong>м и х знач<strong>е</strong>ний.<br />

С ловарь D i c t i o n a r y в C # объявля<strong>е</strong>тся так:<br />

Dictionary kv =<br />

N---------,--------------Л<br />

К а к м в случа<strong>е</strong> с List, символ <br />

соотв<strong>е</strong>тству<strong>е</strong>т типу. К -л к видит<strong>е</strong>, вь<br />

мож<strong>е</strong>т<strong>е</strong> об-ьявить для ключа один тип,<br />

а для знач<strong>е</strong>ний — другой.<br />

Это знач<strong>е</strong>ни<strong>е</strong>, то <strong>е</strong>сть данны<strong>е</strong>,<br />

связанны<strong>е</strong> с опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным<br />

ключом.<br />

new Dictionary О<br />

г у<br />

Это снова типы. П<strong>е</strong>рвый<br />

тип в угловых скобках вс<strong>е</strong>гда<br />

соотв<strong>е</strong>тству<strong>е</strong>т ключу,<br />

а второй — знач<strong>е</strong>нию.<br />

А в о т п р и м <strong>е</strong> р р а б о ты со словар<strong>е</strong>м:<br />

p r i v a t e v o i d b u t t o n l _ C l i c k (ob j e c t senderi><br />

E v e n tA r g s e)<br />

{<br />

D i c t i o n a r y o t r i n g , s t r i n g > w o r d D e f i n it io n = ‘Принадл<strong>е</strong>жат 'T m u n ^T -^^new<br />

D i c t i o n a r y o t r i n g , s t r i n g > ( ) ; Мод<strong>е</strong>лиру<strong>е</strong>м обычный t<br />

КЛН5И1Л u<br />

знач<strong>е</strong>ния do<br />

б а в л я ю т с я<br />

в словарі><br />

помощи<br />

м<strong>е</strong>тода<br />

AddO-<br />

wordDefinitio^fГ^d^"C:лoвapь", "Книга, сод<strong>е</strong>ржащая список слов "<br />

^--- -- "в алфавитном порядк<strong>е</strong> и объяснянлцая их знач<strong>е</strong>ния");<br />

«огав<strong>е</strong>£хп 1Ь 1оп .А аа (»ключ", " ср <strong>е</strong>д ст в о, дающ<strong>е</strong><strong>е</strong> нам доступ "<br />

+ "к пониманию ч<strong>е</strong>го бы то ни бьшо.");<br />

wordDefinition.Add ("Знач<strong>е</strong>ни<strong>е</strong>", "Разм<strong>е</strong>р, колич<strong>е</strong>ство или число.");<br />

if (wordPefinitiok^ ContainsKey("Ключ'^ {<br />

MessageBox.Show(wordDefinition["Ключ"]);<br />

зволя<strong>е</strong>т<br />

и к д з й н н о го<br />

М<strong>е</strong>тод AddQ<br />

сначала б<strong>е</strong>р<strong>е</strong>т<br />

ключ, а потом<br />

знач<strong>е</strong>ни<strong>е</strong>.<br />

слова.<br />

дальш<strong>е</strong> ► 375


сопоставь что угодно ч<strong>е</strong>му угодно<br />

Функциональность слобар<strong>е</strong>й<br />

С ловари во м н о го м н а п о м и н а ю т ко л л <strong>е</strong> кц и и . О н и ги б к и , п о зволяю т вам работа ть с д а н н ы м и<br />

п р о и з в о л ь н о го т и п а и и м <strong>е</strong> ю т м н о ж <strong>е</strong> ство в с тр о <strong>е</strong> н н ы х ф ун кц и й . Р ассм отрим о с н о в н ы <strong>е</strong> м <strong>е</strong>тод<br />

ы класса D i c t i o n a r y :<br />

^Добавл<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов.<br />

Добавл<strong>е</strong>ни<strong>е</strong> осущ<strong>е</strong>ствля<strong>е</strong>тся пут<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>дачи ключа и знач<strong>е</strong>ния м<strong>е</strong>тоду Add о .<br />

D i c t i o n a r y < s t r i n g , s t r i n g > m y D ic t io n a r y = new D i c t i o n a r y < s t r x n g , s t r i n g > { ) ;<br />

m y D ic t i0n ary.A dd(" K aK 0Ü -T0 ключ", " к а к о <strong>е</strong> -т о з н а ч <strong>е</strong> н и <strong>е</strong> " );<br />

^Поиск знач<strong>е</strong>ния по ключу.<br />

Самым важным при работ<strong>е</strong> со словар<strong>е</strong>м явля<strong>е</strong>тся просмотр знач<strong>е</strong>ний — собств<strong>е</strong>нно,<br />

за этим вы их там и хранит<strong>е</strong>. Для словаря D i c t lo n a r y < s t r in g , s t r i n g > ДОСТуП<br />

К знач<strong>е</strong>нию осущ<strong>е</strong>ствля<strong>е</strong>тся по ключу типа string, возвраща<strong>е</strong>т он так ж<strong>е</strong> строку.<br />

s t r i n g lo o k u p V a lu e = m y D ic t io n a r y [" к а к о й -т о к л ю ч " ];<br />

^Удал<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов.<br />

Как и при работ<strong>е</strong> с объ<strong>е</strong>ктами L i s t , для удал<strong>е</strong>ния из словаря использу<strong>е</strong>тся м<strong>е</strong>тод<br />

Remove о . Достаточно п<strong>е</strong>р<strong>е</strong>дать <strong>е</strong>му ключ, как сам ключ и знач<strong>е</strong>ни<strong>е</strong> будут удал<strong>е</strong>ны.<br />

m y D ic t io n a r y . Remove (" к а к о й -т о к л ю ч " ); ^оизвольно<strong>е</strong>Толич<strong>е</strong>с^^^ 'лвчм<br />

♦получ<strong>е</strong>ни<strong>е</strong> списка ключ<strong>е</strong>й.<br />

Свойство K eys в комбинации с циклом f o r e a c h позволя<strong>е</strong>т получить п<strong>е</strong>р<strong>е</strong>ч<strong>е</strong>нь ключ<strong>е</strong>й<br />

словаря.<br />

f o r e a c h ( s t r i n g k e y i n m y D ic t io n a r y .K e y s ) { . . . } ;<br />

— ^ Клю чи о т н о с я т с я к свойствам словаря, ß рассматри-<br />

★ П о д с ч <strong>е</strong> т п а р . ^ ва<strong>е</strong>мом случа<strong>е</strong> они принадл<strong>е</strong>жат типу string, поэтому<br />

_ э т о набор строк.<br />

Свойство C ount возвраща<strong>е</strong>т число пар «ключ-знач<strong>е</strong>ни<strong>е</strong>», им<strong>е</strong>ющихся в словар<strong>е</strong>:<br />

int howMany = myDictionary.Covmt;<br />

Ключ u знач<strong>е</strong>ни<strong>е</strong> м огут принадл<strong>е</strong>)кать разным типам<br />

С л овари ф а к ти ч <strong>е</strong> ски ун и в<strong>е</strong>рса л ьн ы и м о гут сод<strong>е</strong>рж ать зн а ч <strong>е</strong> н и я л ю б ы х т и п о в (о т с т р о к до о б ъ <strong>е</strong>ктов).<br />

В о т п р и м <strong>е</strong> р словаря, в к о то р о м к л ю ч и о тн о с я тс я к т и п у in t, а знач<strong>е</strong>ния — к объ<strong>е</strong>ктам D u cli.<br />

D i= t i o n a r y < i n t , Duck> d u c k D ic t io n a r y = new D i c t i o n a r y < i n t , D u c k X ) ,<br />

u объ<strong>е</strong>кты, исполь- d u c k D ic t io n a r y .A d d (3 7 6 , new D uckO<br />

зуются в случаях { Kind = KindOf Duck. Mallard, Size = 15 >) ;<br />

присво<strong>е</strong>ния объ<strong>е</strong>ктам<br />

=> s ' •<br />

уникальных ид<strong>е</strong>нтификаторов.<br />

376 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

практич<strong>е</strong>ско<strong>е</strong> прим<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> слоВаря<br />

В о т н<strong>е</strong>больш ая програм м а, ко то р а я п о н р а в и т с я ф анатам б<strong>е</strong>йсбола из Н ью -<br />

Й о р к а . К а к то л ь ко и г р о к п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т вы ступ а ть за команду, ф утболка с <strong>е</strong> го ном <strong>е</strong>­<br />

ром п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т использоваться. Создадим програм м у, ко то р а я показы ва<strong>е</strong>т, каки<strong>е</strong><br />

ном <strong>е</strong>ра б ы л и у з н а м <strong>е</strong> н и ты х и гр о к о в и когд а э ти и г р о к и уш л и из б о л ь ш о го спорта.<br />

У п р а ж н <strong>е</strong> н и <strong>е</strong> !<br />

c l a s s JerseyNuitiber {<br />

p u b l i c s t r i n g P la y e r { g e t ; p r i v a t e s e t ; }<br />

p u b l i c i n t Y e a r R e tir e d { g e t ; p r i v a t e s e t ; }<br />

}<br />

p u b l i c J e r s e y N u m b e r (s tr in g p l a y e r .<br />

P la y e r = p la y e r ;<br />

Y e a r R e tir e d = n u m b erR etired ;<br />

}<br />

В о т ф орма;<br />

! Retired Jersey Numbers<br />

i n t n u m b erR etired ) {<br />

Йоги £><strong>е</strong>рра играл под * 2 за<br />

одну команду, а Карл Рипкинмладший...<br />

под т <strong>е</strong> м ж <strong>е</strong> ном<strong>е</strong>ром<br />

за другую. Но в словар<strong>е</strong><br />

одному знач<strong>е</strong>нию мож<strong>е</strong>т соотв<strong>е</strong>тствовать<br />

только один<br />

ключ, поэтому в программ<strong>е</strong> на<br />

данный мом<strong>е</strong>нт п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ны<br />

ном<strong>е</strong>ра игроков одной команды.<br />

Попытайт<strong>е</strong>сь придумать способ<br />

сохранять информацию об<br />

игроках н<strong>е</strong>скольких команд.<br />

Nufflb«- 42 was worn Jadde Rotoson and retired m 1ЭЭЗ<br />

А э то код ф орм ы :<br />

p u b l i c p a r t i a l c l a s s Forml : Form {<br />

D i e t i o n a r y < i n t , JerseyN um ber> r e tire d N u m b e r s<br />

{3 , new J ersey N u m b e r ( "Babe R uth", 1 9 4 8 ) } ,<br />

{4 , new J e rsey N u m b er{"Lou G eh rig " , 1 9 3 9 ) } ,<br />

{5 , new J ersey N u m b e r ( "Joe D iM a g g io " , 1 9 5 2 ) } ,<br />

{7 , new J ersey N u m b e r ( "M ickey M a n tle" , 1 9 6 9 ) } ,<br />

{8 , new J ersey N u m b e r ( "Yogi B e rra " , 1 9 7 2 ) } ,<br />

{lO , new J e rsey N u m b er( " P h il R iz z u to " , 1 9 8 5 ) } ,<br />

{2 3 , new J e rsey N u m b er{"Don M a t tin g ly " , 1 9 9 7 ) } ,<br />

{4 2 , new J e rsey N u m b er{" J a c k ie R o b in so n " , 1 9 9 3 ) } ,<br />

{4 4 , new J ersey N u m b e r ( "R eggie J a c k so n " , 1 9 9 3 ) } ,<br />

new D i c t i o n a r y < i n t , J ersey N u m b er> () {<br />

Объ<strong>е</strong>кты JerseyNumber<br />

п<strong>е</strong>р<strong>е</strong>даются в словарь при<br />

помои^и инициализатора<br />

колл<strong>е</strong>кции.<br />

};<br />

p u b l i c F o r m l{) {<br />

I n it ia liz e C o m p o n e n t O ;<br />

}<br />

f o r e a c h ( i n t k e y i n r e tir e d N u m b e r s . K eys) {<br />

num ber. I t e m s .A d d ( k e y ) ;<br />

}<br />

^<br />

Ключы из словаря<br />

добавляются в<br />

колл<strong>е</strong>кцию эл<strong>е</strong>м<strong>е</strong>нтов<br />

ComboBox.<br />

p r i v a t e v o id n u m b e r _ S e le c te d I n d e x C h a n g e d (o b je c t s e n d e r , E ven tA rgs e) {<br />

JerseyN um ber jerseyN u m b er = r e tir e d N u m b e r s [ (i n t ) n u m b e r .S e le c te d lte m ]<br />

nam eLabel .T e x t = je rse y N u m b e r . P la y e r ;<br />

y e a r L a b e l.T e x t = j e r s e y N u m b e r .Y e a r R e t ir e d .T o S t r in g O ;<br />

\ SelectedlndexCkanged эл<strong>е</strong>м<strong>е</strong>нта ComboBox<br />

(K одновля<strong>е</strong>т дв<strong>е</strong> м<strong>е</strong>тки на форм<strong>е</strong>, выводя знач<strong>е</strong>ни<strong>е</strong><br />

объ<strong>е</strong>кта JerseyNumber, взято<strong>е</strong> из словаря.<br />

a s JerseyN um ber;<br />

Свойство Selectedltem эл<strong>е</strong>м<strong>е</strong>нта<br />

ComboBox явля<strong>е</strong>тся<br />

объ<strong>е</strong>ктом. Так как ключ<br />

принадл<strong>е</strong>жит типу int, вам<br />

потр<strong>е</strong>бу<strong>е</strong>тся оп<strong>е</strong>рация при -<br />

в<strong>е</strong>д<strong>е</strong>ния к этому типу.


сыгра<strong>е</strong>м в карты!<br />

Длинны<strong>е</strong><br />

упражн<strong>е</strong>ния<br />

Создадим симулятор карточной игры.<br />

Это упражн<strong>е</strong>ни<strong>е</strong> сл <strong>е</strong>гка о тл и ч а<strong>е</strong>тся...<br />

Д опуска<strong>е</strong>м , ч т о вы изуча<strong>е</strong>т<strong>е</strong> C # , ч т о б ы п о то м н а й т и работу. П р о гр а м м и с ты р а б о та ю т в ком анд<strong>е</strong>,<br />

и н и к т о н<strong>е</strong> заним а<strong>е</strong>тся создани<strong>е</strong>м прогр а м м о т начала до конца. К а ж д ы й в ы п о л н я <strong>е</strong> т кусок<br />

задания. С ловом , м ы р <strong>е</strong> ш и л и п р <strong>е</strong> д о ставить вам пазл, в к о т о р о й отд<strong>е</strong>льны <strong>е</strong> ф р а гм <strong>е</strong> н ты уж <strong>е</strong> соб<br />

р аны . К од ф орм ы прив<strong>е</strong>д<strong>е</strong>н в ш аг<strong>е</strong> #3. Вам оста<strong>е</strong>тся то л ь ко вв<strong>е</strong>сти <strong>е</strong>го в И С Р . Н о п р и этом<br />

вс<strong>е</strong> классы , к о то р ы <strong>е</strong> вы п и ш и т <strong>е</strong> , должны работать с этим кодом. А в о т э т о го д о б иться н<strong>е</strong> так-то<br />

п р о с то !<br />

Сп<strong>е</strong>циф икация<br />

Работа над л ю б ы м п роф <strong>е</strong> ссиональн ы м п р о гр а м м н ы м об<strong>е</strong>сп<strong>е</strong>ч<strong>е</strong>ни<strong>е</strong>м нач<br />

и н а <strong>е</strong> тся со сп <strong>е</strong> ц и ф и ка ц и и . Вам п р <strong>е</strong> д с т о и т п о с т р о и т ь сим улято р класс<br />

и ч <strong>е</strong> с к о й к а р т о ч н о й и гр ы Go Fish! С ущ <strong>е</strong>ствую т р а зл и чны <strong>е</strong> варианты<br />

правил, в о т т<strong>е</strong>, к о то р ы <strong>е</strong> буд<strong>е</strong>т<strong>е</strong> использо вать вы :<br />

★<br />

★<br />

★<br />

★<br />

★<br />

И спользу<strong>е</strong>тся колода из 52 карт. И гр о к а м разда<strong>е</strong>тся п о п я ть<br />

карт. К а р ты , оста вш и <strong>е</strong>ся посл<strong>е</strong> раздачи, назы ваю тся з а п а с о м .<br />

И гр о к и п о оч<strong>е</strong>р<strong>е</strong>ди с п р а ш и в а ю т п р о н а л и ч и <strong>е</strong> к а р т («Е сть л и<br />

у к о го с<strong>е</strong>м <strong>е</strong>рки?»). И гр о к , им <strong>е</strong>ю ш ;ий н у ж н у ю карту, отда<strong>е</strong>т <strong>е</strong><strong>е</strong>.<br />

Е сли та к о й к а р ты н и у к о го н<strong>е</strong>т, б<strong>е</strong>р<strong>е</strong>тся одна карта из запаса.<br />

Ц <strong>е</strong> л ью и г р ы явля<strong>е</strong>тся сб ор взяток. В з я ткой счита <strong>е</strong> тся набор из<br />

ч <strong>е</strong> т ы р <strong>е</strong> х о д и н а к о в ы х карт. Д ля в ы и гр ы ш а н у ж н о со б рать м аксимально<strong>е</strong><br />

к о л и ч <strong>е</strong> ств о взяток. С о б р а н н ы й набор из ч <strong>е</strong> т ы р <strong>е</strong> х ка р т<br />

вы клады ва<strong>е</strong>тся на стол.<br />

Если вы лож <strong>е</strong>нная взятка оставля<strong>е</strong>т и гр о к а б<strong>е</strong>з карт, о н б<strong>е</strong>р<strong>е</strong>т пять<br />

карт из запаса. Если в запас<strong>е</strong> осталось м <strong>е</strong>ньш <strong>е</strong> п я ти карт, и гр о к<br />

б<strong>е</strong>р<strong>е</strong>т и х вс<strong>е</strong>. И гр а заканчива<strong>е</strong>тся как то л ько запас иссяка<strong>е</strong>т. П о ­<br />

б<strong>е</strong>дит<strong>е</strong>ль опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся п о максимальному колич<strong>е</strong>ству взяток.<br />

В наш <strong>е</strong>й в <strong>е</strong> р си и ч<strong>е</strong>лов<strong>е</strong>к в ы ступа<strong>е</strong>т п р о т и в двух к о м п ь ю т<strong>е</strong> р н ы х<br />

и гр о к о в . К аж дая п а р ти я н а чи н а <strong>е</strong> тся с в ы б о р а ч<strong>е</strong>лов<strong>е</strong>ком ка р ты ,<br />

о н а л и ч и и к о т о р о й о н буд<strong>е</strong>т спраш и вать. Зат<strong>е</strong>м два ко м п ь ю т<strong>е</strong> р ­<br />

н ы х и гр о к а сп р а ш и в а ю т п р о св о и ка р ты . Р<strong>е</strong>зультаты каж д ой<br />

п а р т и и о то б р а ж а ю тся в т<strong>е</strong> ксто во м пол<strong>е</strong>.<br />

П р о ц <strong>е</strong> д ур ы сдачи к а р т и в зя то к авто м а ти зи р о ва н ы . К а к то л ько<br />

кто -то поб<strong>е</strong>ж да<strong>е</strong>т, и гр а заканчива<strong>е</strong>тся, и в ы водится им я поб<strong>е</strong>дит<strong>е</strong>ля<br />

(и л и поб<strong>е</strong>дит<strong>е</strong> л<strong>е</strong>й в случа<strong>е</strong> н и ч ь <strong>е</strong> й ). Б ольш <strong>е</strong> н и к а к и х д<strong>е</strong>йс<br />

тв и й в ы п о л н и т ь н<strong>е</strong>льзя. И гр о к у оста<strong>е</strong>тся т о л ь ко п<strong>е</strong>р<strong>е</strong>загрузи ть<br />

програм м у, ч т о б ы начать н о вую п а р ти ю .<br />

Если задачу н<strong>е</strong><br />

сформулировать<br />

заран<strong>е</strong><strong>е</strong>,<br />

как узнать,<br />

что работа<br />

законч<strong>е</strong>на?<br />

Им<strong>е</strong>нно поэтому<br />

разработка<br />

проф<strong>е</strong>ссиональных<br />

прилож<strong>е</strong>ний<br />

начина<strong>е</strong>тся со<br />

сп<strong>е</strong>цификации,<br />

которая сообща<strong>е</strong>т<br />

вам, что<br />

должно получиться<br />

в итог<strong>е</strong>.<br />

378 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

о П о стро<strong>е</strong>ни<strong>е</strong> формы<br />

Ф о р м <strong>е</strong> нуж <strong>е</strong>н эл <strong>е</strong>м <strong>е</strong>н т управл<strong>е</strong>ния L i s t B o x для о т о б р а ж <strong>е</strong>н и я карт игрока, два эл <strong>е</strong>м <strong>е</strong>н ­<br />

та управл<strong>е</strong>ния T e x t B o x для о т о б р а ж <strong>е</strong>н и я п р о ц <strong>е</strong> сс а игры и кнопка, с п о м ощ ь ю к о т о р о й<br />

и грок буд<strong>е</strong>т спраш ивать о нал и ч и и карт.<br />

П р и с в о й т <strong>е</strong> с в о й с т в у Name э т о ­<br />

г о э л <strong>е</strong> м <strong>е</strong> н т а T ex tB o x -знач<strong>е</strong>ни<strong>е</strong><br />

и ^ Ы а т <strong>е</strong> . Ш э т о м с н и М к <strong>е</strong> э к р а н а<br />

о н о в к л ю ч <strong>е</strong> н о , но п ш з а п у с к <strong>е</strong> п р о<br />

г р а м м ы долж н о о т о б р а ж а т ь с я .<br />

Свойства Namp<br />

^;^^о игра уж<strong>е</strong> началась<br />

Эти эл<strong>е</strong>м<strong>е</strong>нты<br />

TextBox называются<br />

textProgress<br />

и textBooks.<br />

Ed ad«a t anytme has a Seven<br />

Joehas2Sevw«<br />

ВЫ5 has 0 Sev«is<br />

Joe a*s f arflfwehas a Ten<br />

Ed has 0 Tens<br />

&*ha»OTens<br />

Jse must A m from tt» stoA.<br />

, &* a ^ f anyone has a Quew<br />

ahasOQueens<br />

Joe has 0 Queens<br />

8(3b 1ШЙ *aw from the stodc.<br />

a has 7 cards.<br />

Joehas4ca*,<br />

Bobhas lOcanJs.<br />

The stodc has 4 cards Wt.<br />

ofDanonds<br />

KingrfOubs<br />

Карты на<br />

руках у игрока<br />

отображаются<br />

в пол<strong>е</strong> ListBox<br />

с им <strong>е</strong>н<strong>е</strong>м<br />

listHand.<br />

Books<br />

a has a book rf fives<br />

Joe has a ЬоЫс of Aces<br />

ahasato rfto f Fot*B<br />

BobhasabD(^!^№es<br />

Asd


код формы<br />

Длинны<strong>е</strong><br />

упражн<strong>е</strong>ния<br />

О Это код дюрмы<br />

В в<strong>е</strong>дит<strong>е</strong> <strong>е</strong>го в И С Р .<br />

p u b l i c p a r t i a l c l a s s Form l : Form {<br />

p u b l i c F o r m l() {<br />

I n it i a l iz e C o m p o n e n t () ;<br />

}<br />

p r i v a t e Game gam e;<br />

Это <strong>е</strong>динств<strong>е</strong>нный класс, с которым<br />

взаимод<strong>е</strong>йству<strong>е</strong>т фо^>ма. Им<strong>е</strong>нно он<br />

управля<strong>е</strong>т вс<strong>е</strong>й игрои.<br />

Свойство<br />

B n a b le d<br />

Включа<strong>е</strong>т и<br />

о т к л ю ч а <strong>е</strong> т<br />

э л <strong>е</strong> м <strong>е</strong> н т ы<br />

у п р а в л <strong>е</strong> н и я<br />

ф орм ьь<br />

Этот м<strong>е</strong>тод<br />

очища<strong>е</strong>т т <strong>е</strong>кстово<strong>е</strong><br />

пол<strong>е</strong><br />

от пр<strong>е</strong>дыдущ<strong>е</strong>го<br />

списка и<br />

заполня<strong>е</strong>т <strong>е</strong>го<br />

набором карт<br />

для новой игры.<br />

p r i v a t e v o id buttonStart_Click(object se n d e r , E v en tA rg s e) {<br />

i f (S tr in g .I s N u llO r E m p t y ( t e x t N a m e .T e x t ) ){<br />

M e ssa g e B o x .S h o w (" P le a se e n t e r y o u r name<br />

r e tu r n ;<br />

"C an't s t a r t t h e game y e t" )<br />

}<br />

game new G a m e(tex tN a m e.T ex t, new L i s t < s t r i n g > { "Joe", "Bob" }, t e x t P r o g r e s s )<br />

A u t t o n S t a r t .E n a b l e d = f a l s e ;<br />

(te x tN a m e .E n a b le d = f a l s e ;<br />

b u tto n A s k .E n a b le d = t r u e ;<br />

U pdateForm O ;<br />

p r i v a t e v o i d UpdateFormO {<br />

l i s t H a n d . I t e m s . C l e a r ();<br />

f o r e a c h<br />

( S t r in g cardName i n g a m e.G etP la y erC a rd N a m es()<br />

lis tH a n d .I te m s .A d d (c a r d N a m e );<br />

t e x tB o o k s .T e x t = g a m e .D e s c r ib e B o o k s 0 ;<br />

t e x t P r o g r e s s .T e x t += g a m e .D e s c r ib e P la y e r H a n d s ( ) ;<br />

t e x t P r o g r e s s . S e l e c t i o n S t a r t = t e x t P r o g r e s s .T e x t .L e n g t h ;<br />

t e x t P r o g r e s s . S c r o ll T o C a r e t ( );<br />

p r i v a t e v o i d buttonAsk_Click(object se n d e r , E v en tA rg s e) {<br />

t e x t P r o g r e s s .T e x t = "";<br />

i f ( l is t H a n d .S e le c t e d l n d e x < 0) {<br />

}<br />

i f<br />

M e ssa g e B o x .S h o w (" P le a se s e l e c t a c a r d " );<br />

r e tu r n ;<br />

При начал<strong>е</strong> новой игры созда<strong>е</strong>тся экз<strong>е</strong>мпляр<br />

класса Game, становится доступной<br />

кнопка Ask, пропада<strong>е</strong>т достцп<br />

к кнопк<strong>е</strong> S ta rt Game, посл<strong>е</strong> ч<strong>е</strong>го форма<br />

п<strong>е</strong>р<strong>е</strong>рисовыва<strong>е</strong>тся.<br />

(g a m e .P la y O n e R o u n d ( lis t H a n d .S e le c t e d ln d e x ) ) {<br />

t e x t P r o g r e s s .T e x t += "The w in n er i s . . . + gam e. G etW innerNam e()<br />

t e x t B o o k s .T e x t = g a m e .D e s c r ib e B o o k s 0 ;<br />

b u tto n A s k .E n a b le d = rf a lis e ;<br />

e l s e<br />

A<br />

UpdateForm O ;<br />

Свойство SelectionStart<br />

и м<strong>е</strong>тод ScrollToCaretO<br />

позволяют прокручи -<br />

бать т<strong>е</strong>кст, <strong>е</strong>сли он н<strong>е</strong><br />

ум<strong>е</strong>ща<strong>е</strong>тся в т<strong>е</strong>кстово<strong>е</strong><br />

) пол<strong>е</strong>.<br />

Свойство SelectionStart<br />

опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т начало выо<strong>е</strong>л<strong>е</strong>нного<br />

фрагм<strong>е</strong>нта,<br />

посл<strong>е</strong> этого м<strong>е</strong>тод<br />

ScrollToCaretQ прокручива<strong>е</strong>т<br />

сод<strong>е</strong>ржимо<strong>е</strong> т <strong>е</strong>кстового<br />

поля до м<strong>е</strong>ста<br />

нахожд<strong>е</strong>ния курсора.<br />

Игрок выбира<strong>е</strong>т карту и щ<strong>е</strong>лка<strong>е</strong>т на кнопк<strong>е</strong><br />

Ask, чтобы узнать, <strong>е</strong>сть ли данная карта<br />

У кого-нибудь из соп<strong>е</strong>рников. Класс Game игра<strong>е</strong>т<br />

с помощью м<strong>е</strong>тода PlayOneRoundQ.<br />

380 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Этот код вам тож<strong>е</strong> понадобится<br />

Вам п о т р <strong>е</strong>б у <strong>е</strong>тся у ж <strong>е</strong> н ап и сан н ы й код для класса C a rd , п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong>н и й S u i t s и V a l u e s ,<br />

класса D e c k и класса C a r d C o m p a r e r _ b y V a lu e . В классы н уж н о буд<strong>е</strong>т д обав и ть н<strong>е</strong>сколько<br />

м <strong>е</strong>тодов ... суть к о т о р ы х вы д о л ж н ы поним ать.<br />

p u b l i c Card Peek( i n t cardNumber)<br />

}<br />

r e t u r n c a r d s[c a r d N u m b e r ];<br />

4 / ------- М<strong>е</strong>тод Р<strong>е</strong><strong>е</strong>кО позволя<strong>е</strong>т взять<br />

{ карту из колоды.<br />

К т о-т о п<strong>е</strong>р<strong>е</strong>грузил м<strong>е</strong>тод PealQ, сд<strong>е</strong>лав <strong>е</strong>го<br />

p u b l i c Card D e a lO { ^ g j , восприятия. Если н<strong>е</strong> п<strong>е</strong>р<strong>е</strong>давать<br />

r e t u r n D ea l (0) ; ^ Т м у параш т рь,. буд<strong>е</strong>т сдана в<strong>е</strong>рхняя карта<br />

} в колод<strong>е</strong>.<br />

p u b l i c b o o l ContainsValue(V a lu e s v a lu e ) {<br />

f o r e a c h (Card c a r d i n c a r d s)<br />

i f (c a r d .V a lu e == v a lu e )<br />

r e t u r n t r u e ;<br />

r e t u r n f a l s e ;<br />

}<br />

М<strong>е</strong>тод ContainsValueQ ищ<strong>е</strong>т<br />

6 колод<strong>е</strong> карты опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нного<br />

старшинства и, находя их,<br />

возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true. Вы<br />

догадыва<strong>е</strong>т<strong>е</strong>сь, как он буд<strong>е</strong>т<br />

использоваться в наш<strong>е</strong>й игр<strong>е</strong>?<br />

p u b l i c D eck PullOutValues(V a lu e s v a lu e ) {<br />

}<br />

D eck d eckT oR eturn = new D eck(new Card [] { } ) ;<br />

f o r ( i n t i = c a r d s.C o u n t - 1; i >= 0;<br />

i f (c a r d s [i] .V a lu e == v a lu e )<br />

d e c k T o R e tu r n .A d d (D e a l(i ) ) ;<br />

r e t u r n deckT oR eturn;<br />

p u b l i c b o o l HasBook(V a lu e s v a lu e )<br />

}<br />

i n t NumberOfCards = 0;<br />

f o r e a c h (Card c a r d i n c a r d s)<br />

i f (c a r d .V a lu e == v a lu e )<br />

N um berofC ards++;<br />

i f (NumberOfCards == 4)<br />

e l s e<br />

r e t u r n t r u e ;<br />

r e t u r n f a l s e ;<br />

Г<br />

и зв л <strong>е</strong> ка <strong>е</strong> т ад из<br />

варіант t Z f d T e T<br />

включ<strong>е</strong>на и в з я т к ^ Р ^ ' ^<br />

М<strong>е</strong>тод HasBookQ, получив<br />

в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра<br />

карту, начина<strong>е</strong>т<br />

искать взятки.<br />

Обнаружив ч<strong>е</strong>тыр<strong>е</strong><br />

одинаковы<strong>е</strong> карты, он<br />

возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

true.<br />

p u b l i c v o id SortByValue() {<br />

}<br />

c a r d s . S o r t(n e w C ardC om parer_byV alue())<br />

М<strong>е</strong>тод SortByValuef)<br />

с о р т и р у <strong>е</strong> т к о л о д У<br />

с >ломощью класса<br />

< ^ o m p a re r^ b y V a lu e .<br />

П <strong>е</strong> р <strong>е</strong> в <strong>е</strong> р н и т <strong>е</strong> с т р а н и ц у и л р о д о д ж и м !<br />

дальш<strong>е</strong> > 381


покажи им, как надо играть!<br />

Длинны<strong>е</strong><br />

упраж н<strong>е</strong>ш я<br />

Это СЛОЖ НАЯ часть: создани<strong>е</strong> класса Player<br />

Э кз<strong>е</strong>м п ляры класса P l a y e r сущ <strong>е</strong>ствую т для в с<strong>е</strong>х игроков. О н и с о з­<br />

даю тся о б р а б о т ч и к о м со б ы т и й кн опк и b u t t o n S t a r t .<br />

c l a s s P la y e r<br />

{<br />

p r i v a t e s t r i n g name;<br />

p u b lic s t r i n g Name { g e t { r e t u r n name; } }<br />

p r i v a t e Random random;<br />

p r i v a t e Deck cards;<br />

p r i v a t e T extB ox textBoxOnForm;<br />

Внимат<strong>е</strong>льно читайт<strong>е</strong><br />

комм<strong>е</strong>нтарии, там сказано,<br />

н Х д<strong>е</strong>йствия должны<br />

выполнять м<strong>е</strong>тоды для<br />

которых вы пиш<strong>е</strong>т<strong>е</strong> код<br />

p u b l i c Player( S t r in g name, Random random, T extB ox textB oxO nForm ) {<br />

// Конструктор класса P la y e r инициализиру<strong>е</strong>т ч<strong>е</strong>тыр<strong>е</strong> закрытых поля, а зат<strong>е</strong>м<br />

// добавля<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нту управл<strong>е</strong>ния T extB ox строку "Joe h a s j u s t<br />

// j o i n e d t h e gam e", используя имя закрытого поля. Н<strong>е</strong> забудьт<strong>е</strong> поставить<br />

// знак п<strong>е</strong>р<strong>е</strong>носа в кон<strong>е</strong>ц каждой строки, добавля<strong>е</strong>мой в T ex tB o x .<br />

}<br />

p u b l i c IE n u m erab le< V alu es> PullOutBooks() {<br />

} // код на сл<strong>е</strong>дующ<strong>е</strong>й страниц<strong>е</strong><br />

p u b lic V a lu e s GetRandomValue() {<br />

// Этот м<strong>е</strong>тод получа<strong>е</strong>т случайно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>, но из числа карт колоды!<br />

p u b l i c Deck DoYouHaveAny(V a lu e s v a lu e ) {<br />

// Соп<strong>е</strong>рник спрашива<strong>е</strong>т о наличии у м<strong>е</strong>ня карты нужного достоинства<br />

// Используйт<strong>е</strong> м<strong>е</strong>тод D e c k .P u llO u t V a lu e sо для взятия карт. Добавьт<strong>е</strong> в T extB ox<br />

// строку "Joe h a s 3 s i x e s " , используйт<strong>е</strong> новый статич<strong>е</strong>ский м<strong>е</strong>тод C a r d .P l u r a l()<br />

p u b l i c v o i d A sk F o rA C a rd (L ist< P la y er> p l a y e r s , i n t m ylndex. D eck s t o c k ) {<br />

// Это п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нная в<strong>е</strong>рсия A skForA C ard() - выб<strong>е</strong>рит<strong>е</strong> случайную карту с помощью<br />

// м<strong>е</strong>тода G etR andom V alue() и спросит<strong>е</strong> о н<strong>е</strong>й м<strong>е</strong>тодом A skF orA C ard()<br />

}<br />

p u b lic v o id AskForACard(L ist< P la y e r > p la y e r s , i n t m ylndex. Deck s t o c k . V a lu es v a lu e ) {<br />

// Спросит<strong>е</strong> карту у соп<strong>е</strong>рников. Добавьт<strong>е</strong> в T extB ox т<strong>е</strong>кст: "Joe a s k s i f anyon e h as<br />

/ / a Q ueen ". В кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра вам буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дана колл<strong>е</strong>кция игроков<br />

// спросит<strong>е</strong> (с помощью м<strong>е</strong>тода DoYouHaveAny()), <strong>е</strong>сть ли у них карты<br />

// указанного достоинства. П<strong>е</strong>р<strong>е</strong>данны<strong>е</strong> им карты добавьт<strong>е</strong> в свой набор.<br />

// Сл<strong>е</strong>дит<strong>е</strong> за т<strong>е</strong>м, сколько карт было добавл<strong>е</strong>но. Если ни одной, вам нужно<br />

// взять карту из запаса (п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся как парам<strong>е</strong>тр), в т<strong>е</strong>кстово<strong>е</strong><br />

// пол<strong>е</strong> нужно добавить строку T extB ox: "Joe had t o draw from t h e sto c k "<br />

}<br />

// П<strong>е</strong>р<strong>е</strong>ч<strong>е</strong>нь свойств и коротких м<strong>е</strong>тодов, которы<strong>е</strong> уж<strong>е</strong> были написаны<br />

p u b l i c i n t CardCoiint { g e t { r e t u r n c a r d s .C o u n t; } }<br />

p u b l i c v o i d TakeCard(Card ca rd ) { c a r d s .A d d ( c a r d ) ; }<br />

p u b l i c IE n u m e ra b le < strin g > GetCardNames() { r e t u r n ca rd s.G e tC a r d N a m e s( ) ; }<br />

p u b lic Card P e e k ( i n t cardNumber) { r e t u r n c a r d s . P eek (ca rd N u m b er); }<br />

p u b l i c v o id SortHandO { c a r d s . S o r tB y V a lu e ( ); }<br />

382 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

М<strong>е</strong>тод PeekQj добавл<strong>е</strong>нный нами в класс<br />

Р<strong>е</strong><strong>е</strong>к, оч<strong>е</strong>нь пол<strong>е</strong>з<strong>е</strong>н. Он позволя<strong>е</strong>т программ<strong>е</strong><br />

посмотр<strong>е</strong>ть на карту, инд<strong>е</strong>кс к о т ^о и вы<br />

указали, но, в отличи<strong>е</strong> от м<strong>е</strong>тода PealQ, н<strong>е</strong><br />

удаля<strong>е</strong>т карту из колоды.<br />

p u b l i c IE n u m erab le< V alu es> PullOutBooks() {<br />

L is t< V a lu e s > b o o k s = new L i s t < V a lu e s > ();<br />

f o r ( i n t i = 1; i = 0; c a r d - - )<br />

c a r d s .D e a l ( c a r d ) ;<br />

Вам потр<strong>е</strong>буются ДВЕ п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нны<strong>е</strong><br />

в<strong>е</strong>рсии м<strong>е</strong>тода МкРогАСагс(0. П<strong>е</strong>рвая бу~<br />

ucnoлt>зoв£XiAлt>cя вашими conepнuкaAЛUJ<br />

она должна просматривать их карты<br />

и выбирать т у, о которой нужно спросить.<br />

Вторая в<strong>е</strong>рсия использу<strong>е</strong>тся, когда<br />

о карт<strong>е</strong> спрашива<strong>е</strong>т<strong>е</strong> вы. При этом об<strong>е</strong><br />

в<strong>е</strong>рсии опрашивают ВСЕХ игроков (как<br />

компьют<strong>е</strong>р, так и ч<strong>е</strong>лов<strong>е</strong>ка).<br />

Ещ<strong>е</strong> один м<strong>е</strong>тод для класса Card<br />

Э то т ста т и ч <strong>е</strong> с к и й м <strong>е</strong>тод возвращ а<strong>е</strong>т названи<strong>е</strong> ка р ты (во м н о ж <strong>е</strong> ств<strong>е</strong>нном<br />

числ<strong>е</strong>). Т ак ка к о н с та ти ч <strong>е</strong> с к и й , для вы зова н у ж н о указать им я класса— C a r d .<br />

P l u r a l О — и о т н <strong>е</strong> го н <strong>е</strong> возм о ж н о п о л у ч и ть экз<strong>е</strong>м пляры .<br />

p u b l i c p a r t i a l c l a s s Card {<br />

p u b l i c s t a t i c s t r i n g P lu r a l( V a lu e s v a lu e )<br />

i f (v a lu e == V a lu e s .S ix )<br />

r e t u r n " S ix e s " ;<br />

e l s e<br />

r e t u r n v a lu e .T o S t r i n g O + "s" ;<br />

}<br />

}<br />

Д ля добавл<strong>е</strong>ния этого ст а­<br />

тич<strong>е</strong>ского м<strong>е</strong>тода мы использовали<br />

разд<strong>е</strong>ля<strong>е</strong>мый класс.<br />

В этом случа<strong>е</strong> вам прощ<strong>е</strong><br />

понять, что им<strong>е</strong>нно происходит.<br />

Но н<strong>е</strong>обходимости использовать<br />

разд<strong>е</strong>ля<strong>е</strong>мый класс<br />

н<strong>е</strong> было, так м<strong>е</strong>тод можно<br />

добавить в класс Card.<br />

(^К оро З акончим , и<strong>е</strong>р<strong>е</strong>Б<strong>е</strong>рнш ю<strong>е</strong> а х р а н и ц у !<br />

дальш<strong>е</strong> > 383


запиши их<br />

Длинны<strong>е</strong><br />

упраж н<strong>е</strong>ш я<br />

Создани<strong>е</strong> классо б а т <strong>е</strong><br />

Ф орм а со хр а н я <strong>е</strong> т экз<strong>е</strong>м пляр Game, у п р а в л я ю щ и й и гр о й . П о с м о тр и т <strong>е</strong> , как<br />

о н использу<strong>е</strong>тся.<br />

8 классах Player и Game им<strong>е</strong>ются ссылки на<br />

c l a s s Game {<br />

эл<strong>е</strong>м<strong>е</strong>нт формы TextBoxJ в котором появляются<br />

сообщ<strong>е</strong>ния о ход<strong>е</strong> игры. Уб<strong>е</strong>дит<strong>е</strong>сь, что<br />

p r i v a t e L is t < P la y e r > players;<br />

p r i v a t e D ic t io n a r y < V a lu e s , P la y e r > books; в в<strong>е</strong>рхн<strong>е</strong>й части файлов <strong>е</strong>сть строка «using<br />

p r i v a t e D eck stock;<br />

System.VJindows.Forms;».<br />

p r i v a t e T extB ox textBoxOnForm;<br />

p u b l i c Game( s t r i n g p layerN am e, IE n u m e r a b le < str in g > opponentN am es, T extB ox textBoxOnForm )<br />

Random random = new Random{);<br />

^<br />

t h i s . textB oxO nForm = textB oxO nForm ;<br />

p l a y e r s = new L i s t < P l a y e r > () ;<br />

p la y e r s .A d d (n e w P la y e r (p la y e r N a m e , random, textB oxO nForm ))<br />

fo r e a c h ( s t r i n g p la y e r i n opponentN am es)<br />

p la y e r s .A d d (n e w P la y e r ( p l a y e r , random, textB oxO nForm ))<br />

b o o k s = new D ic t io n a r y < V a lu e s , P la y e r > () ;<br />

s t o c k = new Deck О ; _ -у.<br />

D e a l ();<br />

p l a y e r s [0] .S ortH an d O<br />

p r i v a t e v o id D e a lO {<br />

/ / Им<strong>е</strong>нно зд <strong>е</strong> с ь начина<strong>е</strong>тся и гр а .<br />

Это пол<strong>е</strong>зно и для инкапсуляции.<br />

Если использовать 1Епит<strong>е</strong>гаЫ<strong>е</strong><br />

вм<strong>е</strong>сто Listj вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong><br />

случайно отр<strong>е</strong>дактировать код.<br />

/ / Т а су <strong>е</strong>т ся к ол ода, р а з д а <strong>е</strong> т с я по пять карт каждому и гр ок у, за т <strong>е</strong>м с помощью<br />

/ / цикла f o r e a c h вызыва<strong>е</strong>тся м <strong>е</strong>тод P u llO u tB o o k s О для каж дого и гр ок а.<br />

Инт<strong>е</strong>рф<strong>е</strong>йс IEnumerable<br />

д<strong>е</strong>ла<strong>е</strong>т классы бол<strong>е</strong><strong>е</strong> гибкими.<br />

Об этом сл<strong>е</strong>ду<strong>е</strong>т помнить<br />

при дальн<strong>е</strong>йш<strong>е</strong>м р<strong>е</strong>дактировании<br />

кода. В данный мом<strong>е</strong>нт<br />

для получ<strong>е</strong>ния экз<strong>е</strong>мпляра<br />

класса Game можно<br />

написать stringQ.List.<br />

p u b l i c b o o l PlayOneRound(i n t s e le c t e d P la y e r C a r d ) {<br />

}<br />

/ / Сыграйт<strong>е</strong> один р а з . Парам<strong>е</strong>тром я вл я<strong>е</strong>тся выбранная игроком карта и з им<strong>е</strong>ющихся на руках<br />

/ / Вызовит<strong>е</strong> м <strong>е</strong>тод A skForA C ardО для каждого и з игроков, начиная с ч<strong>е</strong>лов<strong>е</strong>ка<br />

/ / с нул<strong>е</strong>вым инд<strong>е</strong>к сом . Зат<strong>е</strong>м вы зовит<strong>е</strong> м <strong>е</strong>тод P u llO u tB o o k sО -<br />

/ / <strong>е</strong>сл и он в<strong>е</strong>рн <strong>е</strong>т зн ач<strong>е</strong>н и <strong>е</strong> t r u e , зн ач и т, у игрока кончились<br />

/ / карты. Закончив со вс<strong>е</strong>ми игроками, о тсор ти р уй т<strong>е</strong> карты<br />

/ / ч <strong>е</strong>л ов<strong>е</strong>ка (чтобы список в форм<strong>е</strong> выгляд<strong>е</strong>л к р а с и в о ). П ров<strong>е</strong>рьт<strong>е</strong>, н<strong>е</strong> закончились<br />

/ / ли карты в з а п а с <strong>е</strong> . В сл уч а<strong>е</strong> полож ит<strong>е</strong>льного р <strong>е</strong> зу л ь т а т а оч исти т<strong>е</strong> пол<strong>е</strong> T extB ox<br />

/ / и вы в<strong>е</strong>дит<strong>е</strong> ф разу "The s t o c k i s o u t o f c a r d s . Game o v e r ! " .<br />

p u b l i c b o o l PullOutBooks(P la y e r p la y e r ) {<br />

}<br />

/ / Игроки выкладывают в зя т к и . М<strong>е</strong>тод возвращ а<strong>е</strong>т зн ач<strong>е</strong>ни <strong>е</strong> t r u e , <strong>е</strong>сл и карты у<br />

/ / игрока за к о н ч и л и сь . Каждая в зя тк а д о б а в л я <strong>е</strong>тся в словарь B o o k s.<br />

p u b l i c s t r i n g DescribeBooksО {<br />

}<br />

/ / Этот м <strong>е</strong>тод возвращ а<strong>е</strong>т длинную стр ок у с описани<strong>е</strong>м в зя т о к каждого игрока,<br />

/ / взяв з а о сн о в у сод<strong>е</strong>рж ани<strong>е</strong> словаря B ooks: "Joe h a s а book o f s i x e s .<br />

/ / (п <strong>е</strong>р<strong>е</strong>н ос строки) Ed h a s a book o f A c e s ."<br />

384 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

А ля написания м<strong>е</strong>тода GetWinneirNameQ нужно создать новый словарь Dictionaru<br />

л я т ь ^ ' Х п ^ Т ' п о м <strong>е</strong> с т и т ь <strong>е</strong>го н« самый в<strong>е</strong>рх. По им<strong>е</strong>ни игрока словарь буд<strong>е</strong>т пр<strong>е</strong>доставко<br />

л и ч <strong>е</strong> с тв <strong>е</strong> сд<strong>е</strong>ланных им за игру взяток. Сначала с помощью цикла foreach<br />

нужно буд<strong>е</strong>т записать в словарь вс<strong>е</strong> сд<strong>е</strong>ланны<strong>е</strong> взятки. Зат<strong>е</strong>м второй цикл foreach долж<strong>е</strong>н<br />

/илксммдльно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. Нужно помнить, что возможна и ничья - ситуация, когда<br />

колм ч<strong>е</strong>стб о взяток присутству<strong>е</strong>т у бол<strong>е</strong><strong>е</strong> ч<strong>е</strong>м одного игрока! Так что вам по-<br />

^ о д и н цикл foreach, ищущии вс<strong>е</strong>х игроков в словар<strong>е</strong> winners, которы<strong>е</strong> им<strong>е</strong>ют м ак-<br />

Л в ы и ^ л " ■ ^ информаци<strong>е</strong>й о Z m кто<br />

public Л г 1 п д GetWinnerName () {<br />

I I Этот м <strong>е</strong>тод вызыва<strong>е</strong>тся в конц<strong>е</strong> игры. Он и сп о л ь зу <strong>е</strong>т собств<strong>е</strong>нны й словарь<br />

/ / ( D i c t i o n a r y < s t r in g , in t > w in n e r s) для отсл<strong>е</strong>ж ивания колич<strong>е</strong>ства в зя ток<br />

/ / каждого и гр ок а. Сначала цикл foreach (Values value in books.Keys)<br />

/ / зап ол н я <strong>е</strong>т словарь winners информаци<strong>е</strong>й о в зя т к а х . Зат<strong>е</strong>м<br />

/ / словарь просм атрива<strong>е</strong>тся на пр<strong>е</strong>дм<strong>е</strong>т поиска максимального<br />

/ / кол ич <strong>е</strong>ства в зя т о к . Н апосл<strong>е</strong>док словарь просм атрива<strong>е</strong>тся <strong>е</strong>щ<strong>е</strong> один р а з , чтобы<br />

/ / сформировать список п о б <strong>е</strong>д и т <strong>е</strong>л <strong>е</strong>й в вид<strong>е</strong> строки {"Joe and Ed") . Если поб<strong>е</strong>дит<strong>е</strong>ль<br />

/ / один, возвращ а<strong>е</strong>тся строка "Ed w it h З b o o k s" . В противном<br />

/ / сл уч а<strong>е</strong> возвращ а<strong>е</strong>тся стр ока "А t i e b e tw e e n J o e and Bob w it h 2 b o o k s."<br />

/ / Пара коротких м <strong>е</strong>тод ов , которы<strong>е</strong> были написаны раньш<strong>е</strong>:<br />

p u b l i c IE n u m e ra b le < strin g > GetPlayerCardNames() {<br />

r e t u r n p l a y e r s [ 0 ] .G etC ardN am es( );<br />

p u b l i c s t r i n g DescribePlayerHands() {<br />

s t r i n g d e s c r i p t i o n = "";<br />

f o r ( i n t i = 0; i < p la y e r s .C o u n t ; i++ ) {<br />

d e s c r i p t i o n += p la y e r s [ i] .N a m e + " h a s " + p l a y e r s [ i] .C a r d C o u n t ;<br />

i f ( p la y e r s [ i ] . CardCount == 1)<br />

d e s c r i p t i o n += " c a r d ." + E n v iro n m en t.N ew L in e;<br />

e l s e<br />

d e s c r i p t i o n += " c a r d s ." + E n v iro n m en t.N ew L in e;<br />

}<br />

d e s c r i p t i o n += "The s t o c k h a s " + s to c k .C o u n t + " c a r d s l e f t . " ;<br />

r e t u r n d e s c r i p t i o n ;<br />

Вв<strong>е</strong>дит<strong>е</strong> 6 окно Watch (inty\r'<br />

чтобы присвоить символ \r '<br />

числу. В р<strong>е</strong>зультат<strong>е</strong> вы поли-<br />

Чит<strong>е</strong> г з . В то вр<strong>е</strong>мя как Лп’<br />

пр<strong>е</strong>враща<strong>е</strong>тся в Ю. Каждый<br />

симоол пр<strong>е</strong>враща<strong>е</strong>тся в сим -<br />

оол гОникод, Аополнит<strong>е</strong>льицю<br />

информацию по этой т<strong>е</strong>м<strong>е</strong> вы<br />

получит<strong>е</strong> в сл<strong>е</strong>дующ<strong>е</strong>й глав<strong>е</strong>.<br />

Она сод<strong>е</strong>ржит символы \r\n. Если ^ o c £ ^ T fm T u T ^ '^ ‘^ ^'^wVonmentWewL/ne.<br />

ванный в Windows, в конц<strong>е</strong> каждой с^воки ^ и “Я<br />

ги<strong>е</strong> оп<strong>е</strong>рационны<strong>е</strong><br />

^*^форматиро~<br />

АРИ~<br />

t-<br />

385


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

длинных<br />

П р З Ж Н <strong>е</strong> Н И Й В о т как п о л н о с т ь ю в ы гл я д я т м <strong>е</strong>тоды д л я кл а сса Game.<br />

p r i v a t e v o id Deal О { М<strong>е</strong>тод PealQ втыва<strong>е</strong>тся в начал<strong>е</strong><br />

s t o c k . S h u f f l e О ;<br />

м асу<strong>е</strong>т колоду и разда<strong>е</strong>т<br />

fo r ( i n t 1 = 0; i < 5; i++)<br />

f o r e a c h (P la y e r p la y e r i n p la y e r s )<br />

каждому игроку no пять карт.<br />

Зат<strong>е</strong>м он собира<strong>е</strong>т взятки, <strong>е</strong>сли<br />

p l a y e r . TakeCard (s t o c k . D e a l () ) ; маковы<strong>е</strong> появляются.<br />

f o r e a c h (P la y e r p la y e r i n p la y e r s )<br />

P u llO u t B o o k s ( p la y e r ) ;<br />

p u b l i c b o o l PlayOneRound( i n t s e le c t e d P la y e r C a r d ) {<br />

Если посл<strong>е</strong> того<br />

как игрок спросил<br />

картц, образовалась<br />

взятка, она<br />

У к<strong>е</strong>-го забира<strong>е</strong>тся.<br />

Ьсли взяток н<strong>е</strong>т<br />

он б<strong>е</strong>р<strong>е</strong>т новы<strong>е</strong> '<br />

карт из за-}<br />

naca.<br />

}<br />

V a lu e s cardT oA skFor = p l a y e r s [ 0 ] . P e e k ( s e le c t e d P la y e r C a r d ) .V a lu e ,•<br />

f o r ( i n t i = 0; i < p l a y e r s . Count; i++ ) {<br />

i f ( i == 0)<br />

p l a y e r s [ 0 ] .A sk F o r A C a r d (p la y er s, 0, s t o c k , ca rd T o A sk F o r );<br />

e l s e<br />

p la y e r s [ i] .A s k F o r A C a r d ( p la y e r s , i , s t o c k ) ;<br />

i f ( P u l lO u t B o o k s ( p la y e r s [ i] )) {<br />

textB oxO n F orm .T ext += p la y e r s [ i] .N a m e<br />

i n t c a rd = 1;<br />

+ " drew a new hand" +<br />

w h ile (c a rd 0)<br />

p l a y e r s [i ] . T ak eC ard (s t o c k . D e a l ()]<br />

c a r d + + ;<br />

}<br />

p l a y e r s [0] .S o rtH a n d O ;<br />

i f (s to c k .C o u n t ==0) {<br />

textB oxO nF orm . T ext =<br />

"The s t o c k i s o u t<br />

r e t u r n t r u e ;<br />

}<br />

r e t u r n f a l s e ;<br />

РУ^тся!^ч^тТб1Типог>яд^‘^'^‘ copmucnucoK.<br />

Зат<strong>е</strong>м n p o 6 eS em !^^ отобража<strong>е</strong>мый<br />

лась ли игра b L u J Z<br />

закончиp<br />

u b l i c b o o l PullOutBooks(P la y e r p la y e r )<br />

E n v ir o n m e n t. N ew L ine;<br />

К<br />

I<br />

Посл<strong>е</strong> щ<strong>е</strong>лчка на кнопк<strong>е</strong> Ask for<br />

a card игра вызыва<strong>е</strong>т м<strong>е</strong>тод<br />

AskForACardQ с выбранной<br />

картой в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра.<br />

Зат<strong>е</strong>м м<strong>е</strong>тод AskForACardQ<br />

вызыва<strong>е</strong>тся для каждого из<br />

игроков.<br />

o f c a r d s . Game o v e r ! E n viron m en t.N ew L in e;<br />

IE n u m erab le< V alu es> b o o k s P u lle d = p l a y e r . P u llO u tB o o k s ()<br />

f o r e a c h (V a lu e s v a lu e i n b o o k sP u lle d )<br />

b o o k s .A d d (v a lu e , p la y e r )<br />

i f (p la y e r.C a r d C o u n t == 0)<br />

r e t u r n t r u e ;<br />

r e t u r n f a l s e ;<br />

М<strong>е</strong>тод PullOutBooksQ пров<strong>е</strong>ря<strong>е</strong>т карты<br />

игрока на наличи<strong>е</strong> б з я т о к . Обнаруж<strong>е</strong>нная<br />

взятка добавля<strong>е</strong>тся в словарь. Если карт<br />

н<strong>е</strong> осталось, возвраща<strong>е</strong>тся знач<strong>е</strong>ни<strong>е</strong> true.<br />

386 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

p u b l i c s t r i n g DescribeBooks()<br />

s t r i n g whoHasW hichBooks =<br />

)<br />

{<br />

Так как в форм<strong>е</strong> долж<strong>е</strong>н отображаться<br />

список взяток, воспользу<strong>е</strong>мся<br />

м<strong>е</strong>тодом Р<strong>е</strong>5спЬ<strong>е</strong>Тк<strong>е</strong>Воок5()<br />

чтобы пр<strong>е</strong>вратить записи словаря<br />

о строки.<br />

^<br />

f o r e a c h (V a lu e s v a lu e i n b o o k s.K e y s)<br />

whoHasW hichBooks += b o o k s [v a lu e ].N a m e + " h a s a book o f<br />

+ C a r d .P lu r a l( v a lu e ) + E n v iro n m en t.N ew L in e;<br />

r e t u r n whoH asW hichBooks;<br />

p u b l i c s t r i n g GetWinnerName() {<br />

D ic t io n a r y < s t r in g , i n t > w in n e r s = new D ic t io n a r y < s t r in g ,<br />

f o r e a c h (V a lu e s v a lu e i n b o o k s.K e y s) {<br />

s t r i n g name = b o o k s[v a lu e ].N a m e ;<br />

i f (w in n e r s.C o n ta in sK e y (n a m e ))<br />

w in n ers[n a m e] ++;<br />

e l s e<br />

w in n ers.A d d (n a m e, 1 );<br />

}<br />

i n t m ostB ook s = 0;<br />

f o r e a c h ( s t r i n g name i n w in n e r s . Keys)<br />

i f (w in n ers[n am e] > m ostB ooks)<br />

m ostB ook s = w in n e r s [name] ; ()<br />

Посл<strong>е</strong> взятия посл<strong>е</strong>дн<strong>е</strong>й карты<br />

тр<strong>е</strong>бу<strong>е</strong>тся опр<strong>е</strong>д<strong>е</strong>лить поб<strong>е</strong>дит<strong>е</strong>ля.<br />

Им<strong>е</strong>нно этим занима<strong>е</strong>тся м<strong>е</strong>тод<br />

GetWinnerNameQ на основ<strong>е</strong> информации<br />

из словаря winners. К л ю ч о м<br />

явля<strong>е</strong>тся имя игрока, а знач<strong>е</strong>ни<strong>е</strong>м -<br />

колич<strong>е</strong>ство взяток.<br />

b o o l t i e = f a l s e ; \ Зат<strong>е</strong>м опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся<br />

максимально<strong>е</strong> колич<strong>е</strong>ство<br />

взяток. Оно пом<strong>е</strong>и^а<strong>е</strong>тся<br />

в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную mostBooks.<br />

{<br />

i f<br />

{<br />

( 'S tr in g .I s N u llO r E m p ty (w in n e r L is t)<br />

w in n e r L is t += " and ";<br />

t i e = t r u e ;<br />

}<br />

w in n e r L is t += name;<br />

}<br />

w in n e r L is t += " w it h " + m ostB ook s + " b o o k s " ;<br />

i f ( t i e )<br />

r e t u r n "A t i e b e tw e e n " + w in n e r L is t ;<br />

e l s e<br />

r e t u r n w in n e r L is t ;<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда мы зна<strong>е</strong>м<br />

игрока с максимальным<br />

колич<strong>е</strong>ством взяток,<br />

можно выв<strong>е</strong>сти строку<br />

с им<strong>е</strong>н<strong>е</strong>м поб<strong>е</strong>дит<strong>е</strong>ля<br />

(или поб<strong>е</strong>дит<strong>е</strong>л<strong>е</strong>й).<br />

Ц <strong>е</strong>р <strong>е</strong>Б <strong>е</strong>р н ш п <strong>е</strong> сш р а н и п у U п р о д о д ж ш !<br />

дальш<strong>е</strong> ► 387


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br />

длинных<br />

П р З Ж Н <strong>е</strong> Н И Й Так вы глядят полностью написанны <strong>е</strong> м<strong>е</strong>тоды класса P la y e r .<br />

p u b lic P la y e r ( S t r i n g name. Random random, TTextBox textBoxOnForm ) {<br />

t h is .n a m e = name;<br />

t h is .r a n d o m = random;<br />

Э т о к о н с т р у к т о р к л а с с а P la y e r . О н<br />

t h i s . textBoxO nForm = textB oxO nForm ;<br />

^ —з а д а <strong>е</strong> т зн<br />

a<br />

а ч <strong>е</strong><br />

...................................<br />

н и я п р и в а т н ы х п о л <strong>е</strong> й и до -<br />

t h i s . c a r d s = new D eck( new C ard[] {} ) ; 5 в т <strong>е</strong> к с т о в о <strong>е</strong> п о л <strong>е</strong> с т р о к у с и н -<br />

te x tB o x O n F o r m . T e x t += name + ф о р м а ц и <strong>е</strong> й о п р и с о <strong>е</strong> д и н и в ш <strong>е</strong> м с я и г р о к <strong>е</strong> .<br />

}<br />

" h a s j u s t j o i n e d t h e game" + E n viron m en t.N ew L in e;<br />

p u b l i c V a lu e s G etR andom V alue() {<br />

Card randomCard = c a r d s . P e e k (random . N e x t (c a r d s . C ou nt)<br />

r e t u r n random C ard. V a lu e ;<br />

}<br />

p u b l i c D eck DoY ouH aveA ny(Values v a lu e ) {<br />

Deck c a rd sIH a v e = c a r d s . P u l lO u t V a lu e s ( v a lu e ) ;<br />

textB oxO n F orm .T ext += Name + " h a s " + c a r d sIH a v e .C o u n t +<br />

М <strong>е</strong> т о д а ^ Я а п с 1 о т \/а 1 и <strong>е</strong> () с пом ош ,ьн><br />

м <strong>е</strong> т о д а Р <strong>е</strong> <strong>е</strong> к О в ы б и р а <strong>е</strong> т с л у ч а й н у ю<br />

к а р т у с р <strong>е</strong> д и и м <strong>е</strong> ю ш ,и х с я у и г р о к а .<br />

+ C a r d .P lu r a l (v a lu e ) + E n v ir o n m e n t.N e w L in e ; М <strong>е</strong> т о д P o Y o u H a v e A n u Q и с п о л ь з ц <strong>е</strong> т<br />

r e t u r n c a rd sIH a v e ; М <strong>е</strong> т о д P u llO u tV a lu e si) д л я и з в л <strong>е</strong> ч <strong>е</strong> -<br />

‘ ^ ------'Ния к а р т , к о т о р ы <strong>е</strong> с о о т в <strong>е</strong> т с т в у ­<br />

ю т з а д а н н ы м п а р а м <strong>е</strong> т р а м<br />

p u b l i c v o i d A sk F o rA C a rd (L ist< P la y er> p l a y e r s , i n t m ylndex. Deck stock)^ ( ^<br />

V a lu e s random V alue = G etR andom V alue() ;<br />

A sk F o rA C a r d (p la y e rs, m yln d ex, s t o c k , random V alue)<br />

Дополнит<strong>е</strong>льно<strong>е</strong> мини-упражн<strong>е</strong>ни<strong>е</strong>: Улучшит<strong>е</strong> инкапсуляцию<br />

класса Player, зам<strong>е</strong>нив в этих двух м<strong>е</strong>тодах List на<br />

IEnumerable, н<strong>е</strong> повлияв на работу программы.<br />

p u b l i c v o i d A sk F o rA C a rd (L ist< P la y er> p l a y e r s , i n t m ylndex.<br />

Deck s t o c k . V a lu e s v a lu e ) {<br />

textB oxO nForm . T e x t += Name + " a s k s i f anyon e h a s a "<br />

+ v a lu e + E n viron m en t.N ew L in e;<br />

i n t t o ta lC a r d s G iv e n = 0;<br />

f o r ( i n t i = 0; i < p la y e r s .C o u n t ; i+ + ) {<br />

i f ( i != m ylndex) {<br />

P la y e r p la y e r = p l a y e r s [ i ] ;<br />

D eck C ardsG iven = p l a y e r . D o Y o u H a v eA n y (v a lu e);<br />

}<br />

i f<br />

}<br />

to ta lC a r d s G iv e n += C a r d sG iv e n . C o u n t;<br />

w h ile (C a rd sG iv en .C o u n t > 0)<br />

c a r d s.A d d (C a r d sG iv e n .D e a l 0 ) ;<br />

( to ta lC a r d s G iv e n == 0) {<br />

textB oxO n F orm .T ext += Name +<br />

" m ust draw from t h e s t o c k ."<br />

c a r d s .A d d ( s t o c k .D e a l () ) ;<br />

^<br />

+ E n v ir o n m e n t. N ew L ine;<br />

В программ<strong>е</strong> два п <strong>е</strong> ­<br />

р<strong>е</strong>груж<strong>е</strong>нных м<strong>е</strong>тода<br />

As.kPorACard{). Эт от<br />

использу<strong>е</strong>т ся соп<strong>е</strong>рникам<br />

и— выбира<strong>е</strong>т<br />

случайную карт у из<br />

им<strong>е</strong>юш,ихся и вызыва<strong>е</strong>т<br />

второй м<strong>е</strong>т од<br />

AskForACardQ.<br />

М <strong>е</strong> т о д A s k F o r A C a r d Q<br />

п р о в <strong>е</strong> р я <strong>е</strong> т в с <strong>е</strong> х и г р о к о в<br />

( з а и с к л ю ч <strong>е</strong> н и <strong>е</strong> м с п р а ш и ­<br />

в а ю щ <strong>е</strong> г о ) , в ы з ы в а <strong>е</strong> т и х<br />

м <strong>е</strong> т о д P o Y o u H a v e A n y Q<br />

и д о б а в л я <strong>е</strong> т н а й д <strong>е</strong> н н ы <strong>е</strong><br />

п о д х о д я щ и <strong>е</strong> к а р т ы .<br />

П ри о т с у т с т в и и у с о п <strong>е</strong> р н и к о в п о д х о д я щ и х<br />

к а р т и г р о к б <strong>е</strong> р <strong>е</strong> т к а р т у и з з а п а с а п р и<br />

п о м о щ и м <strong>е</strong> т о д а P e a lQ .


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Дополнит<strong>е</strong>льны<strong>е</strong> ти пы колл<strong>е</strong>кций...<br />

О б ъ <strong>е</strong> кты L i s t и D i c t i o n a r y о тн о с я тс я к в с т р о <strong>е</strong> н н ы м о б о б щ <strong>е</strong> н н ы м к о л ­<br />

л <strong>е</strong> к ц и я м и являю тся ча стью .N E T F ra m e w o rk. О н и о ч <strong>е</strong> н ь ги б к и , д о ступ к и х<br />

да н н ы м осущ <strong>е</strong>ствля<strong>е</strong>тся в п р о и зволь н о м порядк<strong>е</strong>. Н о и н о гд а р аботу п р о гр а м ­<br />

м ы с д а н н ы м и тр<strong>е</strong>бу<strong>е</strong>тся о гр а н и ч и т ь , та к как явл<strong>е</strong>ни<strong>е</strong>, ко то р о <strong>е</strong> вы м од<strong>е</strong>лиру<strong>е</strong>т<strong>е</strong>,<br />

д о л ж н о работать, как в р <strong>е</strong>альности . В с и туа ц и я х и сп ользую тся о ч <strong>е</strong> р <strong>е</strong> д ь<br />

(Q u e u e ), и л и с т <strong>е</strong> к ( S t a c k ) . О н и о тн о с я тс я к о б о б щ <strong>е</strong> н н ы м ко л л <strong>е</strong> кц и я м , н о<br />

га р а н ти р у ю т о б р а б о тку д а н н ы х в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нном порядк<strong>е</strong>.<br />

И спользуйт<strong>е</strong> оч<strong>е</strong>р<strong>е</strong>дь, когда<br />

п<strong>е</strong>рвы й сохран<strong>е</strong>нны й объ<strong>е</strong>кт буд<strong>е</strong>т<br />

обрабаты ваться п<strong>е</strong>рвы м. Как в случа<strong>е</strong>:<br />

★<br />

★<br />

★<br />

★<br />

а втом о б и л <strong>е</strong> й, д в и ж ущ и хся п о улиц<strong>е</strong><br />

с о д н о с т о р о н н и м дви ж <strong>е</strong> ни<strong>е</strong>м ;<br />

лю д <strong>е</strong> й , сто я щ и х в оч<strong>е</strong>р<strong>е</strong>ди;<br />

кл и <strong>е</strong> н то в , ж д ущ и х о б сл уж и вания п о<br />

т<strong>е</strong>л<strong>е</strong>ф ону;<br />

д р у ги х ситуа ц и й , когда п<strong>е</strong>рвы м обслуж<br />

и ва<strong>е</strong>тся то т, к т о п<strong>е</strong>рвы м приш <strong>е</strong> л .<br />

Оч<strong>е</strong>р<strong>е</strong>дь р


любит<strong>е</strong> ли вы стоять в оч<strong>е</strong>р<strong>е</strong>ди?<br />

Зб<strong>е</strong>нья сл<strong>е</strong>дуют 6 порядк<strong>е</strong> их поступл<strong>е</strong>ния<br />

О ч <strong>е</strong> р <strong>е</strong> д ь отл ича<strong>е</strong>тся о т сп и ска т<strong>е</strong>м , ч т о вы н<strong>е</strong> м ож <strong>е</strong>т<strong>е</strong> добавлять и удал<br />

я ть эл<strong>е</strong>м <strong>е</strong>нты с п р о и зволь н ы м инд<strong>е</strong>ксом . В ы д о б а в л я <strong>е</strong> т <strong>е</strong> о б ъ <strong>е</strong> к т<br />

в о ч <strong>е</strong> р <strong>е</strong> д ь (e n q u e u e ) и у д а л я <strong>е</strong> т <strong>е</strong> и з н <strong>е</strong> <strong>е</strong> (d e q u e u e ). В посл<strong>е</strong>дн<strong>е</strong>м случа<strong>е</strong><br />

оста вш и <strong>е</strong>ся о б ъ <strong>е</strong> кты сд вига ю тся на о д и н эл<strong>е</strong>м<strong>е</strong>нт.<br />

Созда<strong>е</strong>м<br />

оч<strong>е</strong>р<strong>е</strong>дь<br />

строк.<br />

М<strong>е</strong>тод Р<strong>е</strong><strong>е</strong>к()<br />

позволя<strong>е</strong>т выд<strong>е</strong>лить<br />

п<strong>е</strong>рвый<br />

эл<strong>е</strong>м<strong>е</strong>нт<br />

в оч<strong>е</strong>р<strong>е</strong>ди, н<strong>е</strong><br />

удаляя <strong>е</strong>го.<br />

f^emod CleavQ<br />

удаля<strong>е</strong>т из<br />

оч<strong>е</strong>р<strong>е</strong>ди вс<strong>е</strong><br />

объ<strong>е</strong>кты.<br />

Queue myQueue = new Queue();<br />

myQueue.Enqueue("first in line");<br />

myQueue.Enqueue("second in line");<br />

myQueue.Enqueue("third in line");<br />

myQueue.Enqueue("last in line");<br />

string takeALook = myQueue.Peek() ;@<br />

s t r i n g g e t F i r s t = m y Q u e u e . D e q u e u e ()<br />

string getNext = myQueue.Dequeue<br />

int howMany = myQueue.Count<br />

.....................................................................<br />

myQueue.Clear();<br />

В оч<strong>е</strong>р<strong>е</strong>дь добавляются ч<strong>е</strong>тыр<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нта.<br />

П<strong>е</strong>рвый м<strong>е</strong>тод DequeueO<br />

MessageBox.Show("Peek() returned: " + t a k e A L o o k + " \ n "<br />

+<br />

+<br />

"The first Dequeue 0 returned:<br />

"The second Dequeue 0 returned:<br />

‘ -I- g e t F i r s t +<br />

" + g e t N e x t +<br />

+ "Count before Clear 0 was " + h o w M a n y + " \ n "<br />

+ "Count after Clear 0 is now " + myQueue.Count);<br />

<strong>е</strong>го.<br />

' \ n ' ‘<br />

' \ n "<br />

Свойство Count возвраща<strong>е</strong>т<br />

число эл<strong>е</strong>м<strong>е</strong>нтов в оч<strong>е</strong>р<strong>е</strong>ди.<br />

В<br />

уж <strong>е</strong><br />

Объ<strong>е</strong>кты<br />

ждут сво<strong>е</strong>й<br />

оч<strong>е</strong>р<strong>е</strong>ди.<br />

Р<strong>е</strong><strong>е</strong>кО returned; first in tine (I)<br />

The first DequeueO returned; first in lin e (i)<br />

The second DequeueO returned: second in tin e @<br />

C ount before ClearO was 2 ®<br />

C ount after ClearO is now 0 0<br />

390 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

Зб<strong>е</strong>нья сл<strong>е</strong>дуют 6 порядк<strong>е</strong>, обратном порядку их поступл<strong>е</strong>ния<br />

Ст<strong>е</strong>к и м <strong>е</strong><strong>е</strong>т в с<strong>е</strong>го о д н о , н о зн а ч и т<strong>е</strong>л ь н о <strong>е</strong> о т л и ч и <strong>е</strong> о т о ч <strong>е</strong>р <strong>е</strong>д и . В ы пом<strong>е</strong>ща<strong>е</strong>т<strong>е</strong> в н <strong>е</strong>го каж ды й эл <strong>е</strong>м <strong>е</strong>н т<br />

и м о ж <strong>е</strong> т <strong>е</strong> в л ю б о й м о м <strong>е</strong>н т взять п о с л <strong>е</strong> д н и й эл <strong>е</strong>м <strong>е</strong>н т ст<strong>е</strong>ка. С т<strong>е</strong>к н а п о м и н а <strong>е</strong>т бусы. Сначала вы сн и м а<strong>е</strong>т<strong>е</strong><br />

бусину, котор ая бы ла нан и зан а п о сл <strong>е</strong>д н <strong>е</strong>й , п о т о м сл<strong>е</strong>дую щ ую и т. д. Н <strong>е</strong>л ь зя взять ч<strong>е</strong>тв<strong>е</strong>р тую с кон ца<br />

бусину, н <strong>е</strong> сняв т р и пр<strong>е</strong>ды дущ их.<br />

Пом<strong>е</strong>м<br />

а <strong>е</strong> /л ы й<br />

б ст<strong>е</strong>к<br />

эл<strong>е</strong>м <strong>е</strong>н т<br />

С о зд а н и <strong>е</strong> с т <strong>е</strong> к а нич<strong>е</strong>м н<strong>е</strong><br />

отлича<strong>е</strong>тся от о т с^о зд а н и я л ю д о и<br />

д р у г о й о6обиА,<strong>е</strong>ннои колл<strong>е</strong>кции.<br />

6 ce^^npo*^ w e Sta ck< strin g> m y S t a c k = n e w S t a c k < s t r i n g > ( ) ;<br />

э л <strong>е</strong> М ^ <strong>е</strong> н т Е ^ ^ ; ; ^ ^ ^ ^ " f i r s t i n l i n e " ) ;<br />

ницу бныз m y S t a c k . P u s h ( " s e c o n d i n l i n e " ) ;<br />

б а<strong>е</strong>тся m y S t a c k . P u s h ( " t h i r d i n l i n e " ) ;<br />

ИЙ самом l i n e " ) ;<br />

в<strong>е</strong>рху-<br />

© s t r i n g t a k e A L o o k = m y S t a c k . P e e k ( ) ;<br />

O s t r i n g g e t F i r s t = m y S t a c k . P o p ( ) ;<br />

0 s t r i n g g e t N e x t = m y S t a c k . P o p ( ) ;<br />

@ i n t h o w M a n y = m y S t a c k . C o u n t ;<br />

m y S t a c k •C l e a r 0 ;<br />

M e s s a g e B o x . S h o w ( " P e e k ( ) r e t u r n e d ;<br />

+<br />

+<br />

+<br />

+<br />

" T h e f i r s t P o p O r e t u r n e d :<br />

" T h e s e c o n d P o p O r e t u r n e d :<br />

" C o u n t b e f o r e C l e a r O w a s "<br />

" C o u n t a f t e r C l e a r O i s n o w "<br />

М<strong>е</strong>тод PopO удаля<strong>е</strong>т<br />

из ст<strong>е</strong>ка посл<strong>е</strong>дний<br />

добавл<strong>е</strong>нный<br />

туда эл<strong>е</strong>м<strong>е</strong>нт.<br />

Вм<strong>е</strong>сто символов \п можно ^<br />

воспользоваться константой<br />

Environment.NewLinCj но мы<br />

пр<strong>е</strong>дпочли сократить код.<br />

. \<br />

t a k e A L o o k + " \ п " /<br />

+ takeALooJc +<br />

+ g e t F i r s t + " \ n "<br />

" + g e t N e x t + " \ n "<br />

+ h o w M a n y + " \ n "<br />

+ m y S t a c k . C o u n t ) ;<br />

PeekO returned fast: in ltne@<br />

The first PopO returned: last in line @<br />

The secorrd PopO returned; third in fine Q<br />

Count before ClearO was 2 ©<br />

Count after ClearO is now 0 ©<br />

П о сл <strong>е</strong> д н и й о б ъ <strong>е</strong> к т ,<br />

п о м <strong>е</strong> щ <strong>е</strong> н н ы й в с т <strong>е</strong> к ,<br />

с т а н о в и т с я п <strong>е</strong> р в ы м<br />

о б ъ <strong>е</strong> к т о м , к о т о р ы й<br />

б у д <strong>е</strong> т о т т у д а в з я т .<br />

OK<br />

дальш<strong>е</strong> > 391


л<strong>е</strong>п<strong>е</strong>шки и л<strong>е</strong>сорубы<br />

Б<strong>е</strong>ссмыслица какая-то... А что<br />

я могу сд<strong>е</strong>лать со ст<strong>е</strong>ком и оч<strong>е</strong>р<strong>е</strong>дью такого,<br />

ч<strong>е</strong>го н<strong>е</strong> могу сд<strong>е</strong>лать с объ<strong>е</strong>ктами List? Они вс<strong>е</strong>го<br />

лишь позволяют сд<strong>е</strong>лать код на пару строк короч<strong>е</strong>.<br />

При том, что я н<strong>е</strong> им<strong>е</strong>ю доступа к их ср<strong>е</strong>дним<br />

эл<strong>е</strong>м<strong>е</strong>нтам. Ну и зач<strong>е</strong>м таки<strong>е</strong> огранич<strong>е</strong>нны<strong>е</strong><br />

объ<strong>е</strong>кты могут мн<strong>е</strong> понадобиться?<br />

Заполним ст <strong>е</strong>к ч<strong>е</strong>тырьмя<br />

ст роками.<br />

^<br />

Н<strong>е</strong> волнуйт<strong>е</strong>сь, вам н<strong>е</strong> прид<strong>е</strong>тся ни в ч<strong>е</strong>м с<strong>е</strong>бя ограничивать.<br />

С ко п и р о в а ть объ<strong>е</strong>кт Q ueue в о б ъ <strong>е</strong> кт L i s t о ч <strong>е</strong> н ь л <strong>е</strong>гко . Так ж <strong>е</strong> л <strong>е</strong> гко , как ско ­<br />

п и р о в а ть об ъ <strong>е</strong> кт L i s t в объ<strong>е</strong>кт Q ueue, а объ<strong>е</strong>кт Q ueue в объ<strong>е</strong>кт S ta c k ... бол<strong>е</strong><strong>е</strong><br />

т о го , в ы м ож <strong>е</strong>т<strong>е</strong> создать о б ъ <strong>е</strong> кты L i s t , Q ueue и S ta c k из л ю б о го д р уго го<br />

объ<strong>е</strong>кта, р<strong>е</strong>ализую щ и<strong>е</strong> и н т<strong>е</strong> р ф <strong>е</strong> й с lE n u m e r a b le . Д о с та то ч н о воспользоваться<br />

п <strong>е</strong> р <strong>е</strong> гр уж <strong>е</strong> н н ы м ко н с тр у к т о р о м , к о т о р ы й позволя<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>давать к о п и р у <strong>е</strong> ­<br />

м ую ко л л <strong>е</strong> к ц и ю в кач<strong>е</strong>ств<strong>е</strong> парам <strong>е</strong>тра. То <strong>е</strong>сть вы м ож <strong>е</strong>т<strong>е</strong> л <strong>е</strong> гко пр<strong>е</strong>дстави ть<br />

св о и д анны <strong>е</strong> в вид<strong>е</strong> к о л л <strong>е</strong> к ц и и , ко то р а я м аксим ально соотв <strong>е</strong> тству<strong>е</strong> т ваш им<br />

нуждам. (Н о н<strong>е</strong> забы вайт<strong>е</strong>, ч т о п р и к о п и р о в а н и и вы созда<strong>е</strong>т<strong>е</strong> н о в ы й объ<strong>е</strong>кт,<br />

к о т о р ы й буд<strong>е</strong>т заним ать м <strong>е</strong>сто в п ам я ти .)<br />

Stack myStack = new Stack();<br />

myStack. Push ("first in line"); С т <strong>е</strong> к м о ж н о л<strong>е</strong>гко<br />

myStack. Push ("second in line");<br />

зат <strong>е</strong>м<br />

пйлть<br />

т р а н с ф о р м и р о в а т ь<br />

myStack. Push ("third in line"); g , e в о б ъ <strong>е</strong> к т list, в<strong>е</strong>рнут ь<br />

myStack.Push("last in line"),<br />

в с„т»яни<strong>е</strong> ст<strong>е</strong>к». ^<br />

Queue myQueue = new Queue(myStack);<br />

List myList = new List(myQueue);<br />

Stack anotherStack = new Stack(myList);<br />

MessageBox.Show("myQueue has " + myQueue.Count + " items\n"<br />

+ "myList has " + myList.Count + " items\n"<br />

+ "anotherStack has " + anotherStack.Count + " items\n");<br />

B M « « я р <strong>е</strong><br />

Sam cKonupo«»<br />

б новы<strong>е</strong> колд<strong>е</strong>кцим.<br />

m y Q u e u e h a s 4 item s<br />

m yL ist h as 4 item s<br />

a n o th e rS ta c k h a s 4 item s<br />

...Д Л Я д о с т у п а ко в с <strong>е</strong> м<br />

ч л <strong>е</strong> н а м о ч <strong>е</strong> р <strong>е</strong> д и и л и с т <strong>е</strong> к а<br />

д о с т а т о ч н о в о с п о л ь з о в а т ь с я<br />

ц и к л о м ^ г <strong>е</strong> а с И !<br />

392 глава 8


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

_<br />

Напишит<strong>е</strong> программу, которая помога<strong>е</strong>т хозяину каф<strong>е</strong> кормить л<strong>е</strong>сорубов л<strong>е</strong>п<strong>е</strong>шками.<br />

ажн<strong>е</strong>нк<strong>е</strong> Начнит<strong>е</strong> с класса L u m b e r ja c k (Л<strong>е</strong>соруб). Сконструируйт<strong>е</strong> форму и добавьт<strong>е</strong> к кнопкам<br />

обработчики событий.<br />

Л Добавьт<strong>е</strong> в класс Ь гш Ь <strong>е</strong> г j а с к м<strong>е</strong>тод ч т<strong>е</strong> н и я для свойства F la p -<br />

j a c k C o u n t и м<strong>е</strong>тоды T a k e F la p j a c k s и E a tF la p j a c k s .<br />

enum F la p j аск {<br />

C r isp y ,<br />

Soggy,<br />

Browned,<br />

c l a s s L um berjack {<br />

Banana<br />

p r i v a t e s t r i n g name;<br />

p u b l i c s t r i n g Name { g e t { r e t u r n<br />

}<br />

p r i v a t e S ta c k < F la p ja c k > m ea l;-<br />

p u b l i c ЬшпЬ<strong>е</strong>гj a c k ( s t r i n g name) {<br />

t h is .n a m e = name;<br />

m eal = new S t a c k < F la p j a c k > {);<br />

}<br />

p u b l i c i n t FlapjackCount { g e t { / / возвраща<strong>е</strong>т число } }<br />

p u b l i c v o id T a k e F la p ja c k s (F la p ja c k Food, i n t HowMany) {<br />

/ / Д обавля<strong>е</strong>т в с т <strong>е</strong>к M eal у к азан н о<strong>е</strong> кол ич <strong>е</strong>ство л<strong>е</strong>п<strong>е</strong>ш<strong>е</strong>к<br />

}<br />

p u b l i c v o id EatFlapjacks{) {<br />

/ / Выв<strong>е</strong>дит<strong>е</strong> эт и св<strong>е</strong>д<strong>е</strong>н и я на к о н со л ь -------------------------------------<br />

O u tp u t<br />

• -ч-гчвв<br />

Ed’ s e a t i n g f l a p j a c k s<br />

Ed a t e a brow ned f l a p j a c k<br />

Ed a t e a soggy f l a p j a c k<br />

Ed a t e a soggy f l a p j a c k<br />

Ed a t e a soggy f l a p j a c k<br />

Ed a t e a c r i s p y f l a p j a c k<br />

Ed a t e a soggy f l a p j a c k<br />

Ed a t e a b an a n a f l a p j a c k<br />

Ed a t e a bro**ned f l a p j a c k<br />

- Я X<br />

©<br />

Ф орм а п озволя<strong>е</strong>т вв<strong>е</strong>сти им я л<strong>е</strong>соруба в т<strong>е</strong> ксто во <strong>е</strong> пол<strong>е</strong>, ч т о б ы п о м <strong>е</strong> с ти ть <strong>е</strong>го в оч<strong>е</strong>р<strong>е</strong>дь.<br />

В ы дав п<strong>е</strong>рвом у в о ч<strong>е</strong>р<strong>е</strong>ди л<strong>е</strong>сорубу л <strong>е</strong> п <strong>е</strong> ш ки, вы отп р а вля<strong>е</strong>т<strong>е</strong> <strong>е</strong>го <strong>е</strong>сть, щ <strong>е</strong>лкнув на к н о п ­<br />

к<strong>е</strong> N e x t lu m b e rja c k . М ы написа л и о б р а б о т ч и к с о б ы т и й к н о п к и A d d flapjacks. О т с л <strong>е</strong> ж и ­<br />

вайт<strong>е</strong> со сто я н и <strong>е</strong> л<strong>е</strong>сорубов п р и п о м о щ и оч<strong>е</strong>р<strong>е</strong>ди b r e a k f a s t L i n e .<br />

iS BreiiMartfofLumbejacte<br />

ІшЬазаскпаго<strong>е</strong><br />

1.Ed<br />

2.ВЙУ<br />

3. .tones<br />

4. Fred<br />

5.JdiSTsen<br />

6. ВЫ)Ьу, Jr.<br />

Эж.(?ИА<br />

э л <strong>е</strong> м <strong>е</strong> н т<br />

I і S t box<br />

называ<strong>е</strong>т<strong>е</strong><br />

line.<br />

!ЄсіЬаз8ваРІВ£^<br />

Эта кнопка убира<strong>е</strong>т из оч<strong>е</strong>р<strong>е</strong>ди<br />

сл<strong>е</strong>дуюш,<strong>е</strong>го л<strong>е</strong>сорцба, вызыва<strong>е</strong>т <strong>е</strong>го<br />

м<strong>е</strong>тод EatFlapjacks() и п<strong>е</strong>р<strong>е</strong>рисовыба<strong>е</strong>т<br />

сод<strong>е</strong>ржимо<strong>е</strong> т<strong>е</strong>кстового поля.<br />

М<strong>е</strong>тод RedrawListQ выводит в т <strong>е</strong>кстово<strong>е</strong><br />

пол<strong>е</strong> сод<strong>е</strong>ржимо<strong>е</strong> оч<strong>е</strong>р<strong>е</strong>ди. Его<br />

вызывают вс<strong>е</strong> три кнопки. Подсказка:<br />

он использу<strong>е</strong>т цикл foreach.<br />

i<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> Add LuMberjack do-<br />

^ ёавля<strong>е</strong>т имя л<strong>е</strong>сорцба из т<strong>е</strong>кстового<br />

поля пат<strong>е</strong> в оч<strong>е</strong>р<strong>е</strong>дь breakf astLine.<br />

П<strong>е</strong>р<strong>е</strong>таскивая эл<strong>е</strong>м<strong>е</strong>нты RadioBuUon<br />

внутрь эл<strong>е</strong>м<strong>е</strong>нта droupBoXj вы автоматич<strong>е</strong>ски<br />

со<strong>е</strong>диня<strong>е</strong>т<strong>е</strong> их и оставляє-<br />

,т <strong>е</strong> возможность выбрать только один<br />

п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>ль за один раз. Узнать им <strong>е</strong>­<br />

на п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>л<strong>е</strong>й можно в м<strong>е</strong>тод<strong>е</strong><br />

addFfapJacks_Click.<br />

^ p r i v a t e v o id<br />

F la p j a*<br />

i ^ l i c k ( . . . ) {<br />

i f ( ^ i s ^ . C h e c k e 5 ~ ^ tr u e )<br />

^ o d = F la p ja c k T c r is p y ;<br />

Зам<strong>е</strong>тили, что п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

Flapjack использу<strong>е</strong>т строчны<strong>е</strong><br />

буквы (Soggy), но на выход<strong>е</strong><br />

вы получа<strong>е</strong>т<strong>е</strong> прописны<strong>е</strong><br />

(soggy)? Подсказыва<strong>е</strong>м, как<br />

исправить ситуацию. М<strong>е</strong>тод<br />

ToStringO возвраща<strong>е</strong>т строку,<br />

одним из открытых чл<strong>е</strong>нов<br />

которой явля<strong>е</strong>тся м<strong>е</strong>тод<br />

ToLowerO, возвращающий<br />

только прописны<strong>е</strong> буквы.<br />

обрат ит <strong>е</strong> внимани<strong>е</strong> на<br />

. / гииіллаксис: else іГ.<br />

e l s e i f ( ; о ; д у " с Ь <strong>е</strong> с к <strong>е</strong> Г : : tr u e ) ( ОСОБЫЙ с и н т а к с и с :<br />

fo o d = F la p j a c k .S o g g y ; X<br />

e l s e i f (brow n ed .C h eck ed == t r u e ) !<br />

fo o d = F la p j a c k . Browned; P e e k Q в о з в р а щ а <strong>е</strong> т ССЫЛКУ<br />

п<strong>е</strong>рвого л<strong>е</strong>соруба в оч<strong>е</strong>р<strong>е</strong>т-<br />

e ls e<br />

fo o d = F la p ja c k .B a n a n a ;<br />

^ e d r a w L is t O<br />

Lum berjack cu r re n tL u m b e rjа с к = b r e a k f a s t L i n e . P e e k {);<br />

cu rren tL u m b erj a c k . T a k eF la p j a c k s ( f o o d ,<br />

(in t)h o w M a n y .V a lu e );<br />

Эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния NumericUpDown<br />

называ<strong>е</strong>тся howMany, a label называ<strong>е</strong>тся<br />

'nextlnLine.<br />

'


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

н<strong>е</strong>ш<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

p r i v a t e Queue b r e a k f a s t L in e = new Q ueue( );<br />

p r i v a t e v o id a d d L u tn b e r ja c k _ C lic k (o b je c t se n d e r , E ven tA rgs e) {<br />

b r e a k fa s tL in e .E n q u e u e (n e w L u m b er ja c k (n a m e .T e x t) ) ;<br />

nam e. T ex t = "" ; Э п \о<br />

R ed ra w L ist {) ; /,• ^ ^ ^ м <strong>е</strong> н т L k tR n ^<br />

М <strong>е</strong> т о д<br />

Reйf^'йu/L/st(') п р и<br />

m eal;<br />

p u b l i c L u m b e r ja c k (s tr in g name) {<br />

t h is .n a m e = name;<br />

m eal = new S t a c k < F la p j a c k > ( );<br />

p u b l i c i n t F la p ja ck C o u n t { g e t { r e t u r n m e a l.C o u n t; } }<br />

p u b l i c v o id T a k e F la p j a c k s ( F la p j a c k fo o d , i n t howMany) {<br />

f o r ( i n t i = 0; i < howMany; i+ + ) {<br />

m e a l. Push ( f o o d ) ;<br />

Им<strong>е</strong>нно зд<strong>е</strong>сь п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

} } Flapjack вп<strong>е</strong>рвы<strong>е</strong> пиш<strong>е</strong>тся прописными<br />

буквами. Постарайт<strong>е</strong>сь<br />

P iib lic v o id E a tF la p ja c k s О {<br />

понять, как это происходит.<br />

^ к Ц <strong>е</strong> ^ C o n s o le .W r ite L in e (name + " 's e a t i n g f la p j a c k s "<br />

Ф о р м а и и ^ (m ea l.C o u n t > 0) {<br />

^ ^ Ж д о го ^ ‘^ P '^ n e se C o n s o le .W r ite L in e (name + a t e a _ к Г<br />

'^^‘^opySa. + m e a l. Pop () . T o S tr in g () . ToLower () + " f la p j a c k " ) ;<br />

^ ~ —<br />

} М<strong>е</strong>тод meal.PopO возвраща<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong>, м<strong>е</strong>тод<br />

___________ 1___________ ToStringQ которого возвраща<strong>е</strong>т строку, м<strong>е</strong>тод ToLowerO<br />

которой возвраща<strong>е</strong>т другую строку.


п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния и колл<strong>е</strong>кции<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

„ Напишит<strong>е</strong> программу, которая помога<strong>е</strong>т хозяину каф<strong>е</strong> кормить л<strong>е</strong>сорубов л<strong>е</strong>п<strong>е</strong>шками.<br />

Начнит<strong>е</strong> с класса L u m b e rja c k (Л<strong>е</strong>соруб). Сконструируйт<strong>е</strong> форму и добавьт<strong>е</strong> к кнопкам<br />

обработчики событий.<br />

А Добавьт<strong>е</strong> в класс L u m b er j а с к м<strong>е</strong>тод ч т<strong>е</strong> н и я для свойства F la p -<br />

enum F la p ja c k {<br />

C r isp y ,<br />

j a c k C o u n t и м<strong>е</strong>тоды T a k e F la p j a c k s и E a tF la p j a c k s .<br />

S oggy,<br />

Browned,<br />

c l a s s L um berjack {<br />

Banana<br />

p r i v a t e s t r i n g name;<br />

p u b l i c s t r i n g Name { g e t { r e t u r n<br />

p r i v a t e S ta c k < F la p ja c k > m e a l;-<br />

p u b l i c L m n b e r ja c k (s tr in g name) {<br />

th is .n a m e = name;<br />

m eal = new S t a c k < F la p j a c k > () ,<br />

}<br />

p u b l i c i n t Flapj ackCount { g e t { / / возвраща<strong>е</strong>т число } }<br />

p u b l i c v o id T a k e F la p ja c k s (F la p ja c k Food, i n t HowMany) {<br />

/ / Д обавля<strong>е</strong>т в с т <strong>е</strong> к M eal у к азан н о<strong>е</strong> кол ич <strong>е</strong>ство л<strong>е</strong>п<strong>е</strong>ш<strong>е</strong>к<br />

}<br />

p u b l i c v o id EatFlapjacks{) {<br />

/ / Выв<strong>е</strong>дит<strong>е</strong> эт и св <strong>е</strong>д<strong>е</strong>ния на к о н со л ь----------- - '<br />

Oiftput<br />

Ed's €3tif!g flapjacks<br />

Ed ate B brosmeit flapjack<br />

Ed ate a soggy flapjack<br />

Ed ate a soggy flapjack<br />

Ed ate a soggy flapjack<br />

Ed ate a crispy flapjack<br />

Ed ate a soggy flapjack<br />

Ed ate a banana flapjack<br />

Ed ate a browned flapjack<br />

©<br />

Ф орм а позволя<strong>е</strong>т вв<strong>е</strong>сти им я л<strong>е</strong>соруба в т<strong>е</strong> ксто во <strong>е</strong> пол<strong>е</strong>, ч т о б ы п о м <strong>е</strong> с ти ть <strong>е</strong>го в оч<strong>е</strong>р<strong>е</strong>дь.<br />

В ы дав п<strong>е</strong>рвом у в оч<strong>е</strong>р<strong>е</strong>ди л<strong>е</strong>сорубу л <strong>е</strong> п <strong>е</strong> ш ки, вы отп р а вля<strong>е</strong>т<strong>е</strong> <strong>е</strong> го <strong>е</strong>сть, щ <strong>е</strong>лкнув на к н о п ­<br />

к<strong>е</strong> N e x t lu m b e rja c k . М ы н аписа л и о б р а б о т ч и к с о б ы т и й к н о п к и A d d flapjacks. О тсл<strong>е</strong>ж и ­<br />

вайт<strong>е</strong> со сто я н и <strong>е</strong> л<strong>е</strong>сорубов п р и п о м о щ и оч<strong>е</strong>р<strong>е</strong>ди b r e a k f a s t L i n e .<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> Add Lumberjack до-<br />

----------------------- ^ бавля<strong>е</strong>т имя л<strong>е</strong>сорцба из т<strong>е</strong>кстового<br />

1шМаокпат<strong>е</strong> ' 4УШ пят<strong>е</strong> в очср<strong>е</strong>дь breukfastLine.<br />

SredcfaSSne<br />

1.Ed<br />

2.Шу<br />

3. Jones<br />

4 , Fred<br />

5. Jdiisns^<br />

6, ВЫ*у. Jr.<br />

Э т о т<br />

эл<strong>е</strong>м<strong>е</strong>нт<br />

listbox<br />

называ<strong>е</strong>т<strong>е</strong><br />

tine.<br />

ШШстт^ .<br />

]Г<br />

Эта кнопка убира<strong>е</strong>т из оч<strong>е</strong>р<strong>е</strong>ди<br />

сл<strong>е</strong>дуюш,<strong>е</strong>го л<strong>е</strong>сорцба, вызыва<strong>е</strong>т <strong>е</strong>го<br />

м<strong>е</strong>тод EatFlapjacksO и п<strong>е</strong>р<strong>е</strong>рисовыва<strong>е</strong>т<br />

сод<strong>е</strong>ржимо<strong>е</strong> т<strong>е</strong>кстового поля.<br />

М<strong>е</strong>тод RedrawListQ выводит в т <strong>е</strong>кстово<strong>е</strong><br />

пол<strong>е</strong> сод<strong>е</strong>ржимо<strong>е</strong> оч<strong>е</strong>р<strong>е</strong>ди. Его<br />

вызывают вс<strong>е</strong> три кнопки. Подсказка:<br />

он использу<strong>е</strong>т цикл foreach.<br />

I<br />

П<strong>е</strong>р<strong>е</strong>таскивая эл<strong>е</strong>м<strong>е</strong>нты RadioButton<br />

внутрь эл<strong>е</strong>м<strong>е</strong>нта GroupBox, вы автоматич<strong>е</strong>ски<br />

со<strong>е</strong>диня<strong>е</strong>т<strong>е</strong> их и оставля<strong>е</strong>т<strong>е</strong><br />

возможность выбрать только один<br />

п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>ль за один раз. Узнать им <strong>е</strong>­<br />

на п<strong>е</strong>р<strong>е</strong>ключат<strong>е</strong>л<strong>е</strong>й можно в м<strong>е</strong>тод<strong>е</strong><br />

addF!apJacks_Click.<br />

p r i v a t e v o id addFlapjack^Click (. .<br />

F la p j a c k fo o d ;<br />

.) {<br />

Зам<strong>е</strong>тили, что п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

Flapjack использу<strong>е</strong>т строчны<strong>е</strong><br />

буквы (Soggy), но на выход<strong>е</strong><br />

вы получа<strong>е</strong>т<strong>е</strong> прописны<strong>е</strong><br />

исправить ситуацию. М<strong>е</strong>тод<br />

ToStringO возвраща<strong>е</strong>т строку,<br />

одним из открытых чл<strong>е</strong>нов<br />

которой явля<strong>е</strong>тся м<strong>е</strong>тод<br />

ToLowerO, возвращающий<br />

только прописны<strong>е</strong> буквы.<br />

i f t ^ r i s j y . C hecke3~5p tr u e ) „ « u ,,hnnnue Ha<br />

W ? - F l i 5 3 ^ r i 3 p y , ^ l e ;f.<br />

e l s e i f {s o g g y . C hecked == true) CU<br />

fo o d = F la p j a c k .S o g g y ; \<br />

e l s e i f (brow n ed .C h eck ed == t rJ. uU e C ))<br />

I<br />

fo o d = F la p ja ck .B r o w n ed ;<br />

e l s e<br />

fo o d = F la p ja c k .B a n a n a ;<br />

м<strong>е</strong>тод PeekO<br />

ссылку<br />

m п<strong>е</strong>рвого л<strong>е</strong>соруба в оч<strong>е</strong>р<strong>е</strong>с^и.<br />

L um berjack c u r re n tL u m b erja ck = b r e a k f a s t L i n e . P eek О ;<br />

curren tL u m b erj a c k . T ak eF lap j a c k s ( f o o d ,<br />

(in t)h o w M a n y .V a lu e );<br />

.ed ra w L ist () ;<br />

д д ^ д д <strong>е</strong>н т у п р а в л <strong>е</strong> н и я N u m e r ic U p D o w n<br />

называ<strong>е</strong>тся howMany, a label называ<strong>е</strong>тся<br />

-------------------- nextlnLine.


л<br />

9 Ч т <strong>е</strong> н и <strong>е</strong> U З а п и с ь ‘= = * а й л о Б<br />

4 -<br />

^ Сохрани массив байтов и спаси мир 4 -<br />

Иногда настойчивость окупа<strong>е</strong>тся.<br />

Пока что вс<strong>е</strong> ваш и программы жили н<strong>е</strong>долго. Они запускались,<br />

н<strong>е</strong>которо<strong>е</strong> вр<strong>е</strong>мя работали и закрывались. Но этого<br />

н<strong>е</strong>достаточно, когда им<strong>е</strong><strong>е</strong>ш ь д<strong>е</strong>ло с важной информаци<strong>е</strong>й.<br />

Вы долж ны ум<strong>е</strong>ть сохранять свою работу. В этой глав<strong>е</strong> мы<br />

поговорим о том, как записать данны <strong>е</strong> в ф айл, а зат<strong>е</strong>м о<br />

том, как прочитать эту инф орм ацию . В ы познакомит<strong>е</strong>сь с<br />

потоковы м и классам и .N ET и узна<strong>е</strong>т<strong>е</strong> о тайнах ш <strong>е</strong>стнадцат<strong>е</strong>ричной<br />

и двоичной сист<strong>е</strong>м счисл<strong>е</strong>ния.


острова в поток<strong>е</strong><br />

Для чт<strong>е</strong>ния u записи данных 6 .NET используются потоки<br />

Поток (stream) — э то способ, к о то р ы м .N E T F ra m e w o rk о б м <strong>е</strong> н и ­<br />

ва<strong>е</strong>тся д а н н ы м и с п р о гр а м м о й . К а ж д ы й раз, когд а п р о гр ам м а ч и ­<br />

та <strong>е</strong>т и л и записы ва<strong>е</strong>т ф айл, со<strong>е</strong>диня<strong>е</strong>тся с д р уги м к о м п ь ю т<strong>е</strong> р о м<br />

с <strong>е</strong> ти и л и в ы п о л н я <strong>е</strong> т д р уги <strong>е</strong> д <strong>е</strong> й ств и я , связанны <strong>е</strong> с п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong>й<br />

байтов из о д н о го м<strong>е</strong>ста в д руго<strong>е</strong>, р <strong>е</strong> ч ь ид <strong>е</strong>т о п о то к <strong>е</strong> д анны х.<br />

Для чт<strong>е</strong>ния данных<br />

из файла и записи их<br />

в файл использу<strong>е</strong>тся<br />

объ<strong>е</strong>кт Stream.<br />

П р<strong>е</strong>дставьт<strong>е</strong> простую програм м у — ф орм у с о б ­<br />

работчиком собы тий, читаю щ им данны <strong>е</strong> из ф а й ­<br />

ла. Эта оп<strong>е</strong>рация осущ <strong>е</strong>ствля<strong>е</strong>тся с пом ощ ью<br />

объ<strong>е</strong>кта Stream .<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная input сод<strong>е</strong>ржит<br />

данны<strong>е</strong>, прочитанны<strong>е</strong> ^<br />

из объ<strong>е</strong>кта Stream Вы и с п о л ь з у <strong>е</strong> т <strong>е</strong><br />

о б ъ <strong>е</strong> к т S t r e a m ...<br />

■■■U п о и л о к<br />

М оила<strong>е</strong>т<br />

с т в <strong>е</strong> н н о<br />

Д ля записи данны х в ф айл использу<strong>е</strong>тся д р у­<br />

гой объ<strong>е</strong>кт Stream .<br />

stream.Write(...);<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная output<br />

сод<strong>е</strong>ржит данны<strong>е</strong>,<br />

занисьша<strong>е</strong>мы<strong>е</strong><br />

в объ<strong>е</strong>кт stream .<br />

•проц<strong>е</strong>сса н<strong>е</strong> изм<strong>е</strong>нится.<br />

396 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Различны<strong>е</strong> потоки для различных данных<br />

К а ж д ы й п о т о к явля<strong>е</strong>тся п р о и звод н ы м о т а б с тр а к тн о го класса Stream , и сущ<strong>е</strong>ству<strong>е</strong>т<br />

м н о ж <strong>е</strong> ство в с тр о <strong>е</strong> н н ы х классов stream , п р <strong>е</strong> д н а зн а ч <strong>е</strong> н н ы х для р а з л и ч н ы х<br />

о п <strong>е</strong> р а ц и й . В д а н н о й глав<strong>е</strong> будут р а ссм о тр <strong>е</strong> н ы ч т<strong>е</strong> н и <strong>е</strong> и запись в о б ы ч н ы <strong>е</strong> ф айлы ,<br />

н о вс<strong>е</strong> э т и св<strong>е</strong>д<strong>е</strong>ния л <strong>е</strong> гко п р и м <strong>е</strong> н и ть к сж а ты м и заш и ф р о ва н н ы м ф айлам и даж<strong>е</strong><br />

к п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> д а н н ы х п о с<strong>е</strong>ти.<br />

Э т о н <strong>е</strong> к о т о р ы <strong>е</strong><br />

м<strong>е</strong>тода класса<br />

S tre a m .<br />

явля<strong>е</strong>тся<br />

а б с т р а к т н ы м<br />

поэтому вы н<strong>е</strong><br />

мож<strong>е</strong>т<strong>е</strong> создавать<br />

<strong>е</strong>го экз<strong>е</strong>мпляры.<br />

ства и м<strong>е</strong>тоды в со-<br />

FileStream MemorvStream NetworkStream GZIoStream<br />

CloseO CloseO CloseO Closed<br />

ReadO ReadO ReadO ReadO<br />

SeekO SeekO SeekO SeekO<br />

WriteO WriteO WriteO WriteO<br />

О б ъ <strong>е</strong> кт<br />

F ile S t r e a m<br />

позволя<strong>е</strong>т<br />

ч и т а т ь ф айлы<br />

и записы вать<br />

в н и х .<br />

О б ъ <strong>е</strong> кт<br />

M e m o r y S tr ea m<br />

позволя<strong>е</strong>т ч и та ть<br />

данны <strong>е</strong> из пам я ти<br />

и записы вать и х<br />

в пам ять.<br />

О б ъ <strong>е</strong> кт<br />

N e tw o r k S tr e a m<br />

осущ <strong>е</strong>ствля<strong>е</strong>т<br />

ч т<strong>е</strong> н и <strong>е</strong> и запись<br />

д а н н ы х п о с<strong>е</strong>ти.<br />

Вы MO)ketne:<br />

о Записывать в поток.<br />

Э та о п <strong>е</strong> р а ц и я осущ <strong>е</strong>ствля<strong>е</strong>тся п р и п о м о щ и м <strong>е</strong>тода W r i t e О .<br />

О Читать из потока.<br />

М <strong>е</strong> то д R ead {) да<strong>е</strong>т д оступ к ч т <strong>е</strong> н и ю д а н н ы х из ф айла, с<strong>е</strong> ти<br />

и л и из пам яти.<br />

О М<strong>е</strong>нять сво<strong>е</strong> полож<strong>е</strong>ни<strong>е</strong> в поток<strong>е</strong>.<br />

Б о л ь ш и н ств о п о т о к о в п о д д <strong>е</strong> р ж и в а ю т м <strong>е</strong>тод S e e k ( ) , устанавл<br />

и в а ю щ и й ваш у п о з и ц и ю в п о то к<strong>е</strong> .<br />

О б ъ <strong>е</strong> кт G Z ip S tre a m<br />

сж и м а<strong>е</strong>т д анны <strong>е</strong>,<br />

ум <strong>е</strong>ньш ая заним а<strong>е</strong>мо<strong>е</strong><br />

и м и м <strong>е</strong>сто и т<strong>е</strong>м<br />

самым обл<strong>е</strong>гчая и х<br />

ска чивани<strong>е</strong> и хр а н <strong>е</strong> ­<br />

ни<strong>е</strong>.<br />

Потоки позволяют<br />

читать и записывать<br />

данны<strong>е</strong>.<br />

Выбор потока<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

в соотв<strong>е</strong>тствии<br />

с типом данных.<br />

дальш<strong>е</strong> ► 397


намного прощ<strong>е</strong><br />

Объ<strong>е</strong>кт FileStream<br />

В о т ч т о п р о и с х о д и т п р и за п и си в ф айл н<strong>е</strong>с<br />

к о л ь к и х с тр о к т<strong>е</strong>кста:<br />

В в<strong>е</strong>рхн<strong>е</strong>й части любой<br />

программы, ра6отаюш,<strong>е</strong>й<br />

с потоками, должна присутствовать<br />

строчка<br />

u s in g S y s t e m .10;<br />

Созда<strong>е</strong>тся объ<strong>е</strong>кт F ile S t r e a m , п о л уч а ю щ и й<br />

ком анду записы вать в ф айл.<br />

П р и с о <strong>е</strong> д и н и т ь<br />

объ<strong>е</strong>кт •<strong>е</strong>кт FileStream<br />

Л10ЖН0 только<br />

>


Тр<strong>е</strong>хшагоВая проц<strong>е</strong>дура записи т <strong>е</strong> к с та 6 файл<br />

в C # сущ <strong>е</strong>ству<strong>е</strong>т удобны й класс StreamWriter, в ы п о л н я ­<br />

ю щ и й о п и с а н н ы й в пр<strong>е</strong>ды дущ <strong>е</strong>м разд<strong>е</strong>л<strong>е</strong> а л го р и тм за о д и н<br />

шаг. Вам н у ж н о то л ь к о создать о б ъ <strong>е</strong> кт S t r e a m W r i t e r и<br />

п р и с в о и т ь <strong>е</strong>му им я. О н автоматич<strong>е</strong>ски создаст об ъ <strong>е</strong>кт<br />

F i l e S t r e a m и о тк р о <strong>е</strong> т ф айл. П осл <strong>е</strong> ч <strong>е</strong> го оста<strong>е</strong>тся то л ь ко<br />

воспользоваться м <strong>е</strong>тодам и W r it e () и W r i t e L i n e () .<br />

чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Класс StreamWriter автоматич<strong>е</strong>ски<br />

созда<strong>е</strong>т объ<strong>е</strong>кт<br />

FileStream и управля<strong>е</strong>т<br />

им.<br />

Д ля открытия и создания срайлов используйт<strong>е</strong> конструктор класса S tre a m W rite r<br />

И м я файла м о ж н о п<strong>е</strong>р<strong>е</strong>дать к о н с тр у к т о р у S t r e a m W r i t e r { ) . П р и этом ф айл откр ы ва<strong>е</strong>тся<br />

а вто м а ти ч<strong>е</strong>ски . В класс<strong>е</strong> S t r e a m W r i t e r сущ <strong>е</strong>ству<strong>е</strong>т такж <strong>е</strong> п <strong>е</strong> р <strong>е</strong> гр у ж <strong>е</strong> н н ы й к о н с тр у к т о р ,<br />

р а б о та ю щ и й с л о ги ч <strong>е</strong> с к и м и парам <strong>е</strong>трам и: tru e соотв<strong>е</strong>тству<strong>е</strong> т добавл<strong>е</strong>нию т<strong>е</strong>кста в ко н <strong>е</strong> ц<br />

сущ <strong>е</strong>ствую щ <strong>е</strong>го файла, а false — удал<strong>е</strong>нию сущ <strong>е</strong>ствую щ <strong>е</strong>го ф айла и созданию н о в о го с анал<br />

о ги ч н ы м им <strong>е</strong>н<strong>е</strong>м .<br />

StreamWriter writer = new StreamWriter(@"С:\newfiles\toaster oven.txt", true);<br />

■Чнлк & п <strong>е</strong> р <strong>е</strong> д и т н <strong>е</strong> / л ф а й л а<br />

/ а т н а <strong>е</strong> т<br />

кяк т <strong>е</strong> к с т о в а я с т р о к а д <strong>е</strong> з<br />

<strong>е</strong>5С-посл<strong>е</strong>доват<strong>е</strong>лшост<strong>е</strong>и.<br />

Д ля записи в qxlйл используйт<strong>е</strong> м<strong>е</strong>тоды W rite Q и W riteLin eQ<br />

М <strong>е</strong> то д W r it e () записы ва<strong>е</strong>т т<strong>е</strong>кст, а м <strong>е</strong>тод W r i t e L i n e () добавля<strong>е</strong>т к т<strong>е</strong> ксту знак п<strong>е</strong>р<strong>е</strong>носа<br />

с тр о к и . С им волы {0 } , { ! } , { 2 } и т. д. в записы ва<strong>е</strong>м ой стр о к<strong>е</strong> п о зволяю т в к л ю ч и ть в т<strong>е</strong> кст<br />

п арам <strong>е</strong>тры : {0 } зам <strong>е</strong>ня<strong>е</strong>тся п<strong>е</strong>рвы м парам <strong>е</strong>тром посл<strong>е</strong> за п и са н н о й с т р о к и , {1 } - в т о р ы м<br />

ИТ. д.<br />

w r i t e r .W riteL in e (" T h e {0} i s s e t t o { l } d e g r e e s ." , a p p lia n c e , tem p );<br />

0 Д ля освобожд<strong>е</strong>ния от ф айла используйт<strong>е</strong> м <strong>е</strong>тод CloseQ<br />

О ста в и в п о т о к о т к р ы т ы м и с о <strong>е</strong> д и н <strong>е</strong> н н ы м с ф айлом , вы заблокиру<strong>е</strong>т<strong>е</strong> ф айл<br />

для вс<strong>е</strong>х о ста л ьн ы х п рограм м . П о э то м у н<strong>е</strong> забы вайт<strong>е</strong> писать:<br />

w r i t e r .C l o s e о ;<br />

дальш<strong>е</strong> > 399


запишит<strong>е</strong> это<br />

Дьявольский план Жулика<br />

З й п ^ с ь /б а ть файл в корн<strong>е</strong>вой<br />

каталог — н<strong>е</strong> оч<strong>е</strong>нь хорошая<br />

°^^^Р»Нчонная сист<strong>е</strong>ма<br />

Ж и т <strong>е</strong> л и О б ъ <strong>е</strong> ктвиля д олго<strong>е</strong> вр<strong>е</strong>м я б оял ись Ж ул и ка . И в о т о н р<strong>е</strong>-<br />

н<strong>е</strong> позволить это сд<strong>е</strong>ш<br />

и л воспользоваться объ<strong>е</strong>ктом S t r e a m W r it e r для р <strong>е</strong> ализации<br />

Укажит<strong>е</strong> любой<br />

злов<strong>е</strong>щ <strong>е</strong>го плана. П о с м о тр и м на н <strong>е</strong> го поближ <strong>е</strong> . С оздайт<strong>е</strong> консоль- ‘^Р&с по ваш<strong>е</strong>му выбору.<br />

но<strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> и добавьт<strong>е</strong> э т о т к о д в м <strong>е</strong>тод M a in O : - ^<br />

СЭта строчка созда<strong>е</strong>т объ<strong>е</strong>кт<br />

S tre a m W rite r и указыва<strong>е</strong>т <strong>е</strong>го адр<strong>е</strong>с.<br />

esc~1лосл<strong>е</strong>доват<strong>е</strong>льностц^ »»чалом<br />

StreamWriter sw = new StreamWriter(@"С;\secret_plan.txt");<br />

s w t W r i t e L i n e ( " H o w I ' l l d e f e a t C a p t a i n A m a z i n g " ) ;<br />

М<strong>е</strong>тод I-<br />

VJriteLineQ s w . W r i t e L i n e ( " A n o t h e r g e n i u s s e c r e t p l a n b y T h e S w i n d l e r " ) ;<br />

taepeHOCum _ '<br />

строки посл<strong>е</strong> s w . U n i t e ( " I ' 1 1 c r e a t e a n a r m y o f c l o n e s a n d " ) ;<br />

записи, в то<br />

вр<strong>е</strong>мя как s w . W r i t e L i n e ( " u n l e a s h t h e m u p o n t h e c i t i z e n s o f<br />

м<strong>е</strong>тод WriteQ o b j e c t v i l i e . " ) ; ^ ------------ — —<br />

отправля<strong>е</strong>т<br />

обычный for s t r i n(int g l o number c a t i o n = 0; " t h e number m a l l " ;


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

^[аГниш ы ДЛЯ о б ъ <strong>е</strong> к т а ^ <strong>е</strong> аш ^ Г 1 |;<strong>е</strong>Г<br />

у вас <strong>е</strong>сть код для кнопки b u t t o n l_ C lic k (). Расположит<strong>е</strong><br />

магниты таким образом, чтобы создать класс Р1оЬЬо.<br />

При этом обработчик событий долж<strong>е</strong>н прив<strong>е</strong>сти к р<strong>е</strong>зультату,<br />

показанному внизу страницы. Удачи!<br />

private void buttonl_Click(object sender, EventArgs e) {<br />

Flobbo f = new Flobbo("blue yellow");<br />

StreamWriter sw = f.SnobboO;<br />

f .Blobbo(f .Blobbo(f .Blobbo(sw), sw), sw);<br />

}<br />

sw.WriteLine(Zap) Zap);<br />

Zap = orange";<br />

return true;<br />

a<br />

I<br />

sw.WriteLine(Zap);<br />

sw.Close();<br />

return false;<br />

public bool Blobbo '<br />

(bool Already, StreamWriter sw) {<br />

t<br />

■public bool Blobbo(StreamWriter<br />

sw.WriteLine(Zap);<br />

Zap = "green purple";<br />

return false;<br />

public StreamWriter SnobboO {<br />

Р<strong>е</strong>зул ьтат:<br />

с m acaw.txt - Notepaa<br />

Fte Е Л Format View<br />

blue yellow<br />

green purple<br />

red orange<br />

Н ф<br />

дальш<strong>е</strong> > 401


прочитайт<strong>е</strong> это<br />

<strong>е</strong>Ш<strong>е</strong>ни<strong>е</strong> Задачи с МаГнищаМи<br />

Вам тр<strong>е</strong>бовалось сконструировать класс Flobbo, работающ ий опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным образом.<br />

private void buttonl_Click(object sender, EventArgs e) {<br />

Flobbo f = new Flobbo("blue yellow");<br />

StreamWriter sw = f.SnobboO;<br />

f.Blobbo(f .Blobbo(f .Blobbo(sw), sw), sw);<br />

class Flobbo {<br />

private string Zap;<br />

public Flobbo(string Zap) {<br />

this.Zap = Zap;<br />

}<br />

public StreamWriter SnobboO {<br />

f<br />

return new<br />

StreamWriter("macaw.txt");<br />

L iJ<br />

Ещ<strong>е</strong> раз напомина<strong>е</strong>м, что для<br />

р<strong>е</strong>бусов мы нам<strong>е</strong>р<strong>е</strong>нно использу<strong>е</strong>м<br />

произвольны<strong>е</strong> им<strong>е</strong>на<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных и м<strong>е</strong>тодов, пот о­<br />

му что значимы<strong>е</strong> им<strong>е</strong>на д<strong>е</strong>лают<br />

задачу слишком л<strong>е</strong>гкой! Но<br />

пожалуйста, н<strong>е</strong> нужно брать<br />

с нас прим<strong>е</strong>р, когда вы пиш<strong>е</strong>т<strong>е</strong><br />

программы.<br />

r<br />

bool Blobbo (StreamWriter sw) {~j^<br />

sw.WriteLine(Zap);<br />

Zap = "green purple";<br />

return false;<br />

U J<br />

public bool Blobbo<br />

(bool Already, StreamWriter sw) {<br />

if (Already) {<br />

7<br />

sw.WriteLine(Zap); s(Zap); I<br />

sw.Close О<br />

return false;<br />

} else {<br />

I<br />

sw.WriteLine(Zap);<br />

Zap = "red orange";<br />

return true;<br />

Посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния<br />

Т б уд ьт <strong>е</strong> закрыть файлы.<br />

М<strong>е</strong>тод BlobboQ nepeим<strong>е</strong><strong>е</strong>т<br />

два<br />

объявл<strong>е</strong>ния с двумя<br />

различными парам<strong>е</strong>-<br />

І г р а м и . ^<br />

Р<strong>е</strong>зультат:<br />

macaw - Notepad<br />

File Edit Format View Help<br />

M o e y e flo w<br />

g re e n p u rp le<br />

re d o ra n g e<br />

< у ,J. ■<br />

402<br />

глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Чт<strong>е</strong>ни<strong>е</strong> Uзапись при noMoui^u двух объ<strong>е</strong>ктов<br />

С <strong>е</strong> к р <strong>е</strong> тн ы й план Ж у л и к а м ы п р о ч и та <strong>е</strong> м п р и п о м о щ и п о то к а<br />

S t r e a m R e a d e r . И м <strong>е</strong> н н о <strong>е</strong>го к о н с тр у к т о р у п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся им я<br />

ф айла, к о т о р ы й тр<strong>е</strong>бу<strong>е</strong> тся п р о ч и та ть . М <strong>е</strong> то д R e a d L in e () возвращ<br />

а<strong>е</strong>т с тр о ку с т<strong>е</strong> ксто м из ф айла. Д ля п р о ч т <strong>е</strong> н и я вс<strong>е</strong>х с тр о к<br />

и сп о л ьзуй т<strong>е</strong> ц и к л , к о т о р ы й работа<strong>е</strong>т, п о ка пол<strong>е</strong> E ndO f S t r e a m<br />

н<strong>е</strong> п о л у ч и т знач<strong>е</strong>ни<strong>е</strong> tru e , т о <strong>е</strong>сть п о ка н<strong>е</strong> закончатся с тр о к и :<br />

В данном случа<strong>е</strong> мы слишком вольно<br />

использу<strong>е</strong>м слово «поток». Класс<br />

StreamReader (насл<strong>е</strong>дующий ОТ<br />

TextReader) чита<strong>е</strong>т символы из потока,<br />

но это н<strong>е</strong> поток. Поток созда<strong>е</strong>тся,<br />

когда вы п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т<strong>е</strong> имя файла в <strong>е</strong>го<br />

конструктор, и закрыва<strong>е</strong>тся с помощью<br />

м<strong>е</strong>тода Close О . Он им<strong>е</strong><strong>е</strong>т такж<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нный конструктор, которому<br />

можно п<strong>е</strong>р<strong>е</strong>дать объ<strong>е</strong>кт stream.<br />

Т<strong>е</strong>п<strong>е</strong>рь вы поняли, как это работа<strong>е</strong>т?<br />

S t r e a m R e a d e r r e a d e r =<br />

new S t r e a m R e a d e r ( @ " с : \ s e c r e t _ p l a n . t x t " )<br />

S t r e a m W r i t e r w r i t e r =<br />

n ew S t r e a m W r i t e r ( @ " c : \ e m a i l T o C a p t a i n A m a z i n g . t x t<br />

С помощью класса StreamReader программа чита<strong>е</strong>т план r f<br />

Жулика, а ср<strong>е</strong>дства класса StreamWriter позволяют на- )<br />

писать файл, который буд<strong>е</strong>т отправл<strong>е</strong>н по эл<strong>е</strong>ктронной ^<br />

почт<strong>е</strong> суп<strong>е</strong>рг<strong>е</strong>рою Капитану В<strong>е</strong>ликол<strong>е</strong>пному.<br />

w r i t e r . W r i t e L i n e ( " Т о : C a p t a i n A m a z i n g @ o b j e c t v i l l e . n e t " ) ;<br />

w r i t e r . W r i t e L i n e ( " F r o m ; C o m m i s s i o n e r @ o b j e c t i v i l l e . n e t " ) ;<br />

П<strong>е</strong>р<strong>е</strong>дайт<strong>е</strong> файл, который т р<strong>е</strong>бу<strong>е</strong>тся<br />

прочитать конструктору<br />

класса StreamReader.<br />

w r i t e r . W r i t e L i n e ("S T jb j e c t : C a n y o u s a v e t h e d a y . . . a g a i n ? " ) ;<br />

w r i t e r . W r i t e L i n e 0 , ^ W r i t e U ' w O зш .ш в а<strong>е</strong>у. стр окаw<br />

r i t e r . W r i t e L i n e ( " W e 'v e d i s c o v e r e d t h e S w i n d l e r ' s p l a n : " ) ;<br />

' ) !<br />

w h i l e ( ' r e a d e r . E n d O f S t r e a m ) {<br />

s t r i n g l i n e F r o m T h e P la n = r e a d e r . R e a d L i n e 0 ;<br />

w r i t e r . W r i t e L i n e ( " T h e p l a n - > " + l i n e F r o m T h e P l a n ) ;<br />

С б о й ст б а<br />

Ъ<strong>е</strong>лить>^<br />

}<br />

w r i t e r . W r i t e L i n e 0 ;<br />

w r i t e r . W r i t e L i n e ( " C a n y o u h e l p u s?");<br />

^ Цикл чита<strong>е</strong>т строку при по-<br />

\ ^ ^ м о щ и считывающ<strong>е</strong>го уст ройства<br />

и записыва<strong>е</strong>т <strong>е</strong><strong>е</strong> при помощи<br />

устройства записи<br />

w r i t e r . C l o s e О ;<br />

r e a d e r . C l o s e О ;<br />

Вы должны закрыть вс<strong>е</strong> о т ­<br />

крыты<strong>е</strong> потоки, даж<strong>е</strong> <strong>е</strong>сли<br />

вс<strong>е</strong>го лишь чита<strong>е</strong>т<strong>е</strong> файл.<br />

/ |\<br />

О б ъ <strong>е</strong> к т ы S t r e a m R e a d e r<br />

и S t r e a m W r i t e r посл<strong>е</strong> созда<br />

ния их экз<strong>е</strong>мпляров открыли<br />

собств<strong>е</strong>нны<strong>е</strong> потоки. Чтоды<br />

закрыть их, мы два раза оы<br />

зыва<strong>е</strong>м м<strong>е</strong>тод CloseQ.<br />

Hrfp<br />

To: c a p t a 1 r w u n a z in g @ o b je c tv ilie .n e t<br />

From ; coB®»1 s s 1 o n e r @ o b 3 e c t1 v in e .n e t<br />

s u b j e c t : c a n you s a v e t h e d a y . . . a g a in ?<br />

w e’v e d i s c o v e r e d t h e s w i n d l e r ’s p la n :<br />

The p l a n -> HOW I 'l l d e f e a t c a p t a i n /Mnazing ,<br />

The D la n -> AF>oTher g e n iu s s e c r e t p l a n by The s w in d le r _ ^ ^<br />

T he p l a n -> I ’ l l c r e a t e a n arm y o f c lo n e s and u n le a s h th em u pon t h e c i t i z e n s o f o b j e c t v i l l e .<br />

The p l a n -> c lo n e # 0 a t t a c k s t h e m a ll<br />

The p l a n -> C lo n e #1 a t t a c k s downtown<br />

The p l a n -> c lo n e 42 a t t a c k s t h e » a l l<br />

The p l a n -> c lo n e # 3 a t t a c k s d c lo n e #4 a t t a c k s t h e m a ll<br />

The p l a n - > c lo n e #5 a t t a c k s d o w n to w<br />

The p l a n -> c lo n e # 6 a t t a c k s t h e m a ll<br />

c a n y o u h e lp u s?<br />

дальш<strong>е</strong> > 403


н<strong>е</strong> п<strong>е</strong>р<strong>е</strong>с<strong>е</strong>кайт<strong>е</strong> потоки<br />

Данны<strong>е</strong> м о гут проходить ч<strong>е</strong>р<strong>е</strong>з н<strong>е</strong>сколько потоков<br />

Б о л ь ш и м п р <strong>е</strong>им ущ <strong>е</strong>ством р а б о ты с п о то ка м и в .N E T явля<strong>е</strong>тся в о зм о ж н о сть<br />

п у с ти ть д а нны <strong>е</strong> ч<strong>е</strong>р<strong>е</strong>з н <strong>е</strong> ско л ь ко п о то к о в . О д н и м из м н о го ч и с л <strong>е</strong> н н ы х т и ­<br />

п о в д а н н ы х в .N E T явля<strong>е</strong>тся класс C r y p to S tr e a m . О н позволя<strong>е</strong>т заш иф ­<br />

р о вать данны <strong>е</strong>, п<strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м ка к прод<strong>е</strong>лать с н и м и вс<strong>е</strong> оста л ьны <strong>е</strong> о п <strong>е</strong> р а ц и и :<br />

При работ<strong>е</strong> с классом<br />

FileStream данны<strong>е</strong> в вид<strong>е</strong><br />

т<strong>е</strong>кста записываются<br />

н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно в ф д й л .<br />

^ П О Н О В и<br />

O i v e K m C r a p t o S t « « »<br />

со<strong>е</strong>диня<strong>е</strong>тся с oov<br />

<strong>е</strong>ктом FileStream,<br />

и созда<strong>е</strong>т поток замифрованного<br />

т<strong>е</strong>к<br />

ста.<br />

'^'^Фрованньїй<br />

>^<strong>е</strong>кст в файл.<br />

Класс CryptoStream<br />

насл<strong>е</strong>ду<strong>е</strong>т от абстрактного<br />

класса<br />

Stream , как и вс<strong>е</strong> прочи<strong>е</strong><br />

потоковы<strong>е</strong> классы.<br />

р Л <strong>е</strong> ї’'<br />

Потоки можно ПЕРЕДАВАТЬ ПО 1^RTT0ЧKF<br />

Один ноток мож<strong>е</strong>т быть записан в другой, который,<br />

в свою оч<strong>е</strong>р<strong>е</strong>дь, записыва<strong>е</strong>тся в <strong>е</strong>щ<strong>е</strong> один<br />

поток... концом ц<strong>е</strong>почки часто явля<strong>е</strong>тся файл.<br />

404 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

c l a s s P in e a p p le {<br />

Б б а с с <strong>е</strong> й н <strong>е</strong><br />

нужно взять фрагм<strong>е</strong>нты кода<br />

из басс<strong>е</strong>йна и пом<strong>е</strong>стить их на<br />

пусты<strong>е</strong> строчки. Любой фрагм<strong>е</strong>нт<br />

можно использовать н<strong>е</strong>сколько<br />

раз. В басс<strong>е</strong>йн<strong>е</strong> <strong>е</strong>сть<br />

и лишни<strong>е</strong> фрагм<strong>е</strong>нты. В р<strong>е</strong>зультат<strong>е</strong><br />

нужно получить окно<br />

с т<strong>е</strong>кстом, показанно<strong>е</strong> справа.<br />

c o n s t _________ d = " d e l i v e r y .t x t " ;<br />

Fite Edft Format View Help<br />

Infest<br />

a<br />

East<br />

so u th<br />

North<br />

That's all folks'<br />

c l a s s P iz z a {<br />

p r i v a t e ____<br />

p u b l i c P iz z a (_______________<br />

_________.w r i t e r = w r it e r ;<br />

_<br />

J {<br />

p u b l i c _______ _________<br />

{ N o rth , S o u th , E a s t, W est, F la m in g o }<br />

p u b l i c s t a t i c v o i d M ainO {<br />

_______________ o = new __________________( " o r d e r .t x t " ) ;<br />

}<br />

p u b lic v o id<br />

w r i t e r .___<br />

w r i t e r .___<br />

.(f ) ;<br />

_ ( ) ;<br />

..F a r g o f) {<br />

P iz z a pz = new P iz z a (n e w _______________(d, t r u e ) )<br />

p z . ____________(F a rg o .F la m in g o ) ;<br />

f o r (_______ w = 3; W >= 0; w --) {<br />

P iz z a i = new P iz z a<br />

(new ________________ (d, f a l s e ) ) ;<br />

i . I d a h o ( (F a r g o )w );<br />

}<br />

c l a s s P a r ty<br />

p r i v a t e r e a d e r ;<br />

r e a d e r ) {<br />

P a r ty p = new P a rty (n ew<br />

p . ________________ (o) ;<br />

дальш<strong>е</strong> > 405


с<strong>е</strong>рь<strong>е</strong>зный диалог<br />

^ 0 i n p H u e J * e ^ c a Б б а с с <strong>е</strong> й н <strong>е</strong><br />

. ■ s s ; - S * = = -<br />

}<br />

Это точка б хо -<br />

да программы. 3


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Встро<strong>е</strong>нны<strong>е</strong> объ<strong>е</strong>кты для Вызова стандартны х окон диалога<br />

П р и работ<strong>е</strong> с п р о гр а м м о й , ч и та ю щ <strong>е</strong> й и записы ваю щ <strong>е</strong>й<br />

в ф айлы , п <strong>е</strong> р и о д и ч <strong>е</strong> с к и тр <strong>е</strong> б ую тся в сплы ваю щ и <strong>е</strong> о к н а диалога,<br />

н а п р и м <strong>е</strong> р , для вы б о р а и м <strong>е</strong> н и ф айла. И м <strong>е</strong> н н о п о это м у<br />

в .N E T сущ <strong>е</strong>ствую т о б ъ <strong>е</strong> кты , в ы п о л н я ю щ и <strong>е</strong> эту ф ункц и ю .<br />

« Dsslogs<br />

Pointer<br />

I S<br />

CoiofDiatog<br />

^ FoEderBrovwerOiatog<br />

2 3 FontDiaiog<br />

Это окно<br />

F o!der8row seP i«io3'<br />

пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong><br />

Зля работы с пап<br />

KflMWв<br />

.NET им<strong>е</strong><strong>е</strong>тся набор<br />

встро<strong>е</strong>нных окон диалога,<br />

подобных показан<br />

ному на рисунк<strong>е</strong> окну<br />

OpenFilePialog, от кры ­<br />

вающ<strong>е</strong>му файлы.<br />

М<strong>е</strong>тод Shov/DialogO<br />

Д ля вы зова о кна д иалога вам н уж но:<br />

Мы рассмот рим эти<br />

буквально<br />

ч<strong>е</strong>р<strong>е</strong>з минут у.<br />

С оздать экз<strong>е</strong>м пляр о кн а диалога. Э то м о ж н о сд<strong>е</strong>лать п р и п о м о щ и<br />

о п <strong>е</strong> р а то р а new и л и пут<strong>е</strong>м п <strong>е</strong> р <strong>е</strong> та ски вания из T o o lb o x.<br />

© Задайт<strong>е</strong> свойств а окна. Н а п р и м <strong>е</strong> р , T i t l e (т<strong>е</strong> к с т в стр о к<strong>е</strong> заголовка),<br />

I n i t i a l D i r e c t o r y (адр<strong>е</strong>с о ткр ы в а <strong>е</strong> м о й п о ум о л ч а н и ю п а п ки )<br />

и F ile N a m e (для о к о н диалога O p e n и Save).<br />

@ В ы зо в и т<strong>е</strong> м <strong>е</strong>тод S h o w D ia lo g ( ) . О н вы зы ва<strong>е</strong>т о к н о диалога и н<strong>е</strong> возвращ<br />

а<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>, п о ка пользоват<strong>е</strong>ль н<strong>е</strong> щ <strong>е</strong> л кн <strong>е</strong> т на кн о п к <strong>е</strong> О К и л и<br />

C ancel и л и д р уги м способом н<strong>е</strong> закро<strong>е</strong>т о кн о .<br />

О М <strong>е</strong> то д S h o w D ia lo g О возвращ а<strong>е</strong>т п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и <strong>е</strong> D i a l o g R e s u l t . Е го<br />

ч л <strong>е</strong> н ы п р и н и м а ю т знач<strong>е</strong>ния ОК (означа<strong>е</strong>т, ч т о пользоват<strong>е</strong>ль щ <strong>е</strong>лкнул<br />

на к н о п к <strong>е</strong> О К ), C a n c e l, Y e s и No (для о к о н диалога Y e s /N o ).<br />

дальш<strong>е</strong> * 407


окна диалога — это тож<strong>е</strong> объ<strong>е</strong>кты<br />

Окна диалога - э то эл<strong>е</strong>м<strong>е</strong>нты .NET<br />

Ч т о б ы д обав и ть ста н д а р т н о <strong>е</strong> о к н о д и ал ога W ind ow s, д о ст а т о ч н о п <strong>е</strong>р <strong>е</strong>т а ­<br />

щ ить на ф о р м у эл <strong>е</strong>м <strong>е</strong>н т управл<strong>е</strong>ния O p e n F i l e D i a l o g и з окн а T oolbox. О н<br />

поя вля<strong>е</strong>тся в п р о ст р а н ств <strong>е</strong> п о д ф о р м о й , так как э т о компон<strong>е</strong>нт. Так назы ­<br />

ва<strong>е</strong>тся сп <strong>е</strong>ц и ал ьн ы й вид н<strong>е</strong>визуальных эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния. О н и н <strong>е</strong><br />

поя вляю тся на ф о р м <strong>е</strong> , н о и х м о ж н о и спол ьзовать как и л ю б ы <strong>е</strong> други <strong>е</strong> эл <strong>е</strong>­<br />

м <strong>е</strong>нты .<br />

'^^И<strong>е</strong>визуальный»<br />

означа<strong>е</strong>т вс<strong>е</strong>го лишь<br />

1^ 0, что он н<strong>е</strong> появля<strong>е</strong>тся<br />

на форм<strong>е</strong><br />

посл<strong>е</strong> п<strong>е</strong>р<strong>е</strong>таскивания<br />

из окна Toolbox.<br />

л D ialogs<br />

% P o in te r<br />

Щ ] C olorD iatog<br />

О F olderB row serD ialog<br />

1 2 F ontD ialog ^<br />

^ O oenFileD ialog<br />

^ SaveFileD ialog<br />

fnrmi<br />

№<br />

П<strong>е</strong>р<strong>е</strong>тащ<strong>е</strong>нны<strong>е</strong> из окна Toolbox<br />

на форму компон<strong>е</strong>нты от о­<br />

бражаются под р<strong>е</strong>дактором<br />

формы.<br />

\\<br />

Свойство 1п1Ь1а101г<strong>е</strong>Логу опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т'<br />

папку, которая пр<strong>е</strong>длага<strong>е</strong>тся для<br />

Свойство Filter позволя<strong>е</strong>т<br />

м<strong>е</strong>нять<br />

открытия по умолчанию.<br />

фильтры, показыва-<br />

. . Yy - <strong>е</strong>мы<strong>е</strong> в нижн<strong>е</strong>й части<br />

o p e n F i l e D i a l o g l . I n i t i a l D i r e c t o r y = @ " с : \ M y F o l d e r \ D e f a u l t \ " ; окна диалога, напри -<br />

м<strong>е</strong>р, опр<strong>е</strong>д<strong>е</strong>ляющи<strong>е</strong>,<br />

o p e n F i l e D i a l o g l . F i l t e r = " T e x t F i l e s (* . t x t ) | * . t x t | " каки<strong>е</strong> типы файлов<br />

5идцт показываться.<br />

+ " C o m m a -D e lim ite d F i l e s (*.c s v ) |* .csv|a11 F i l e s (*.*)|*.*";<br />

o p e n F i l e D i a l o g l . F i l e N a m e = " d e f a u l t _ f i l e . t x t " ;<br />

Э т и свойства отв<strong>е</strong>тств<strong>е</strong>нны за поo<br />

p e n F i l e D i a l o g l . C h e c k F i l e E x i s t s = t r u e ; (<br />

с о о б щ <strong>е</strong> н и я о б ошибк<strong>е</strong> в случаях,<br />

f когда пользоват<strong>е</strong>ль пыта<strong>е</strong>тся от -<br />

o p e n F i l e D i a l o g l . C h e c k P a t h E x i s t s = f a l s e ; ^ к р ы т ь н<strong>е</strong>сущ<strong>е</strong>ствующий файл.<br />

D i a l o g R e s u l t r e s u l t = o p e n F i l e D i a l o g l . S h o w D i a l o g ( ) ;<br />

i f ( r e s u l t == D i a l o g R e s u l t . O K ) {<br />

}<br />

408 глава 9<br />

O p e n S o m e F i l e ( o p e n F i l e D i a l o g l . F i l e N a m e ) ;<br />

жал ли пользоват<strong>е</strong>ль кнопки<br />

»пров<strong>е</strong>ря<strong>е</strong>т, назнач<strong>е</strong>ни<strong>е</strong><br />

PialogResult.OK. Знач<strong>е</strong>ний п >лоявля<strong>е</strong>тся<br />

ству<strong>е</strong>т кнопк<strong>е</strong> Cancel.<br />

^'^logResult.Cancel соотв<strong>е</strong>т-


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Окна диалога - это объ<strong>е</strong>кты<br />

О б ъ <strong>е</strong> кт O p e n F i l e D i a l o g показы ва<strong>е</strong>т стандартн о <strong>е</strong> о к н о W in d o w s O p e n , а о б ъ <strong>е</strong> кт S a v e F i l e D i a l o g -<br />

стандартн о<strong>е</strong> о к н о Save. И х м о ж н о о то б р а зить и создав п р и п о м о щ и о п <strong>е</strong> р а то р а n ew экз<strong>е</strong>м пляр, задав<br />

<strong>е</strong>го свойства и вы звав <strong>е</strong>го м <strong>е</strong>тод S h o w D ia lo g { ) . Э т о т м <strong>е</strong>тод возвращ а<strong>е</strong>т п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и <strong>е</strong> D i a l o g R e s u l t<br />

(п р о с т о й л о ги ч <strong>е</strong> с к о й п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й в данном случа<strong>е</strong> н<strong>е</strong>доста то ч н о , та к ка к н <strong>е</strong> к о то р ы <strong>е</strong> о кн а диалога им <strong>е</strong>­<br />

ю т бол<strong>е</strong><strong>е</strong> двух к н о п о к ).<br />

s a v e F i l e D i a l o g l = n ew S a v e F i l e D i a l o g {) ;<br />

s a v e F i l e D i a l o g l . I n i t i a l D i r e c t o r y = @ " c: \ M y F o l d e r \ D e f a u l t \ " ;<br />

s a v e F i l e D i a l o g l . F i l t e r = " T e x t F i l e s (*.t x t ) | * .t x t | "<br />

+ " C o m m a -D e lim ite d F i l e s (*.c s v ) [*.csv|A ll F i l e s (*.*)!*.<br />

D i a l o g R e s u l t r e s u l t = s a v e F i l e D i a l o g l . S h o w D i a l o g ( ) ;<br />

i f ( r e s u l t == D i a l o g R e s u l t .OK) {<br />

}<br />

S a v e T h e F i l e ( s a v e F i l e D i a l o g l . F il e N a m e )<br />

Посл<strong>е</strong> мр<strong>е</strong>таскивйния эл<strong>е</strong>м<strong>е</strong>нта<br />

SaveFileDialog из окна Toolbox<br />

^ ----------- нд форму к м<strong>е</strong>тоду формы<br />

InitializeComponentO добавля<strong>е</strong>тся<br />

эта строка.<br />

Понять смысл<br />

■n свойства Filter<br />

I н<strong>е</strong>сложно. Срав-<br />

\ H u m e написанно<strong>е</strong><br />

, ?м<strong>е</strong>жду символами<br />

..... с т<strong>е</strong>м, что<br />

показыва<strong>е</strong>тся в<br />

раскрывающ<strong>е</strong>мся<br />

списк<strong>е</strong> внизу окна.<br />

М<strong>е</strong>тод ShowDialog Q и свойстьо<br />

FileName им<strong>е</strong>ют т<strong>е</strong><br />

ж<strong>е</strong> функции, что и объ<strong>е</strong>кт<br />

OpenFileDialog.<br />

Объ<strong>е</strong>кт SaveFileDialog<br />

соотв<strong>е</strong>тству<strong>е</strong>т<br />

стандартному окну<br />

диалога Save as...<br />

Свойство Title<br />

м<strong>е</strong>ня<strong>е</strong>т т<strong>е</strong>кст<br />

в строк<strong>е</strong> заголовка.<br />

М<strong>е</strong>тод<br />

ShowDialogO вызыва<strong>е</strong>т<br />

окно диа -<br />

лога, открыто<strong>е</strong><br />

на папк<strong>е</strong>, заданной<br />

свойством<br />

Ш 1 а 1 0 1 'г <strong>е</strong> ^ о г у<br />


справочная сист<strong>е</strong>ма<br />

Встро<strong>е</strong>нны<strong>е</strong> классы File и Directory<br />

П о д о б н о классу S t r e a m W r it e r , класс F i l e созда<strong>е</strong>т п о т о к и , п о зволяю щ и <strong>е</strong> р аботать с ф айлам и в ф о­<br />

н о вом р<strong>е</strong>ж им <strong>е</strong>. М <strong>е</strong> то д ы э т о го класса д а ю т во зм о ж н о сть в ы п о л н я ть б о л ь ш и н ств о о п <strong>е</strong> р а ц и й б<strong>е</strong>з пр<strong>е</strong>дв<br />

а р и т<strong>е</strong> л ь н о го создания объ<strong>е</strong>кта F ile S t r e a m . О б ъ <strong>е</strong> кт D i r e c t o r y пр<strong>е</strong>дназнач<strong>е</strong>н для р а б о ты с папкам и.<br />

Клас<strong>е</strong> File позволя<strong>е</strong>т:<br />

О Пров<strong>е</strong>рять, сущ<strong>е</strong>ству<strong>е</strong>т л и дюйл<br />

М <strong>е</strong> то д E x i s t s О возвращ а<strong>е</strong>т зн ач<strong>е</strong>ни<strong>е</strong> tru e<br />

п р и н а л и ч и и указанного вам и ф айла и false —<br />

в п р о ти в н о м случа<strong>е</strong>.<br />

О Читать из ф айла и записывать в н<strong>е</strong>го<br />

М <strong>е</strong> то д O p e n R e a d O да<strong>е</strong>т д оступ к ч т <strong>е</strong> н и ю<br />

ф айла, а м <strong>е</strong>тоды C r e a te () и O p e n W r ite () —<br />

к записи в файл.<br />

О Добавлять в (райл т<strong>е</strong>кст<br />

М <strong>е</strong> то д A p p e n d A llT e x t ()<br />

добавля<strong>е</strong>т т<strong>е</strong> кст<br />

в сущ <strong>е</strong>ствую щ ий ф айл, и созда<strong>е</strong>т ф айл, <strong>е</strong>сли<br />

о н отсутству<strong>е</strong>т на м ом <strong>е</strong>нт запуска м<strong>е</strong>тода.<br />

О П о л уча<strong>е</strong>т инф ормацию о ф айл<strong>е</strong><br />

М <strong>е</strong> то д ы G e tL a s tA c c e s s T im e о и G e t L a s t -<br />

W r ite T im e O возвращ аю т вр<strong>е</strong>м я и дату<br />

посл<strong>е</strong>дн<strong>е</strong>го доступа и посл<strong>е</strong>дн<strong>е</strong>го р<strong>е</strong>дакти ­<br />

р о в а н и я ф айла.<br />

При болшц>< объ<strong>е</strong>мах работы<br />

IiS pT T<br />

создать<br />

экз<strong>е</strong>мпляр класса FUelnfo вм<strong>е</strong>сто<br />

1 °лТ«<br />

Класс РП<strong>е</strong>Ыо отлича<strong>е</strong>тся от клас-<br />

File т<strong>е</strong>м, что для работы вам<br />

•потр<strong>е</strong>бу<strong>е</strong>тся <strong>е</strong>го экз<strong>е</strong>мпляр.<br />

К ^ м <strong>е</strong> того, класс File быстр<strong>е</strong><strong>е</strong> ра~<br />

н<strong>е</strong>большом колич<strong>е</strong>ств<strong>е</strong><br />

оп<strong>е</strong>рации с в то вр<strong>е</strong>мя как<br />

F,telnfo лучш<strong>е</strong><br />

многочисл<strong>е</strong>нных оп<strong>е</strong>раций.<br />

Класс Directory позболя<strong>е</strong>т:<br />

О<br />

о<br />

О<br />

Создать новую п апку<br />

П р и работ<strong>е</strong> с м <strong>е</strong>тодом C r e a t e D i r e c t o r y () вам<br />

тр<strong>е</strong>бу<strong>е</strong>тся указать м арш рут д оступа к папк<strong>е</strong>.<br />

П о лучить список ц)айлов в папк<strong>е</strong><br />

М <strong>е</strong> то д G e t F il e s () созда<strong>е</strong>т массив ф айлов, сод<strong>е</strong>рж ащ ихся<br />

в папк<strong>е</strong>. Вам н у ж н о то л ь ко указать м арш р ут д оступа к н<strong>е</strong>й.<br />

Удалить папку<br />

Э та н <strong>е</strong> сл ож н ая проц<strong>е</strong>дура вы п о л н я <strong>е</strong> тся м <strong>е</strong>тодом D e le t e ()<br />

Класс File явля<strong>е</strong>тся<br />

статич<strong>е</strong>ским, то <strong>е</strong>сть<br />

пр<strong>е</strong>дставля<strong>е</strong>т содой набор<br />

м<strong>е</strong>тодов для радо<br />

т<strong>е</strong>>1 с файлами. Посл<strong>е</strong><br />

создания экз<strong>е</strong>мпляра<br />

Filelnfo вы получа<strong>е</strong>т<strong>е</strong><br />

доступ к тому ж<strong>е</strong> спи<br />

ску м<strong>е</strong>тодов, что и при<br />

работ<strong>е</strong> с классом File.<br />

410 глава 9


4acm°<br />

з а д а в а <strong>е</strong> м ы <strong>е</strong><br />

B o Ilj^ o C b i<br />

чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

И вс<strong>е</strong>-таки зач<strong>е</strong>м нужны символы {0} и {1} в объявл<strong>е</strong>нии<br />

объ<strong>е</strong>кта StreamWriter?<br />

5 При ввод<strong>е</strong> строк в файл иногда возника<strong>е</strong>т н<strong>е</strong>обходимость<br />

вв<strong>е</strong>сти туда и сод<strong>е</strong>ржимо<strong>е</strong> многочисл<strong>е</strong>нных п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных, к прим<strong>е</strong>ру,<br />

можно написать:<br />

w r i t e r .W r it e L i n e ("М<strong>е</strong>ня зо в у т<br />

"мн<strong>е</strong> " + а д <strong>е</strong> + " л<strong>е</strong>т.");<br />

+ name +<br />

Но комбинировать строки таким образом долго, кром<strong>е</strong> того, возраста<strong>е</strong>т<br />

в<strong>е</strong>роятность оп<strong>е</strong>чаток. Намного прощ<strong>е</strong> писать код:<br />

w r i t e r .W r it e L i n e (<br />

"М<strong>е</strong>ня зо в у т {о} мн<strong>е</strong> {1} л <strong>е</strong>т" ,<br />

name, a g e ) ;<br />

Такой вариант л<strong>е</strong>гч<strong>е</strong> чита<strong>е</strong>тся, особ<strong>е</strong>нно, когда в одной строк<strong>е</strong><br />

оказыва<strong>е</strong>тся много п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных.<br />

^ ! Нав<strong>е</strong>рно<strong>е</strong>, вы уж<strong>е</strong> слышали, что файлы на диск<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ны<br />

в вид<strong>е</strong> битов и байтов. Другими словами, при записи файла<br />

на ж<strong>е</strong>сткий диск оп<strong>е</strong>рационная сист<strong>е</strong>ма воспринима<strong>е</strong>т <strong>е</strong>го как<br />

набор байтов. Объ<strong>е</strong>кты Stream R ead er и S trea m W riter<br />

пр<strong>е</strong>образуют эти байты в понятны<strong>е</strong> вам символы, то <strong>е</strong>сть выполняют<br />

кодировани<strong>е</strong> и раскодировани<strong>е</strong>. Помнит<strong>е</strong>, в глав<strong>е</strong> 4<br />

упоминалось, что п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная типа b y t e хранит знач<strong>е</strong>ния от<br />

О до 255? Вс<strong>е</strong> файлы на ж<strong>е</strong>стком диск<strong>е</strong> пр<strong>е</strong>дставляют собой<br />

длинны<strong>е</strong> посл<strong>е</strong>доват<strong>е</strong>льности чис<strong>е</strong>л из этого диапазона. При открытии<br />

файла, скаж<strong>е</strong>м, в прилож<strong>е</strong>нии Блокнот, каждый байт пр<strong>е</strong>образу<strong>е</strong>тся<br />

в символ: наприм<strong>е</strong>р, Е соотв<strong>е</strong>тству<strong>е</strong>т 69, а а — 97<br />

(впроч<strong>е</strong>м, вс<strong>е</strong> зависит от кодировки... но мы поговорим об этом<br />

чуть позж<strong>е</strong>). Соотв<strong>е</strong>тств<strong>е</strong>нно, при сохран<strong>е</strong>нии вв<strong>е</strong>д<strong>е</strong>нного вами<br />

в Блокнот т<strong>е</strong>кста символы пр<strong>е</strong>образуются обратно в байты. Это<br />

пр<strong>е</strong>образовани<strong>е</strong> нужно и для записи п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной типа s t r i n g<br />

в поток.<br />

Разв<strong>е</strong> для записи в файл н<strong>е</strong>достаточно объ<strong>е</strong>кта<br />

treamWriter? Зач<strong>е</strong>м создавать объ<strong>е</strong>кт FileStream?<br />

I Зач<strong>е</strong>м нуж<strong>е</strong>н знак (§ п<strong>е</strong>р<strong>е</strong>д им<strong>е</strong>н<strong>е</strong>м файла?<br />

^ ; При добавл<strong>е</strong>нии в программу строковых констант компилятор<br />

пр<strong>е</strong>образу<strong>е</strong>т <strong>е</strong>зс-посл<strong>е</strong>доват<strong>е</strong>льности (\п или \ г ) в сп<strong>е</strong>циальны<strong>е</strong><br />

символы. Но косая ч<strong>е</strong>рта присутству<strong>е</strong>т и в маршрутах<br />

доступа к файлам. Пом<strong>е</strong>стив в начало строки знак вы говорит<strong>е</strong><br />

С#, что в строк<strong>е</strong> отсутствуют <strong>е</strong>зс-посл<strong>е</strong>доват<strong>е</strong>льности. Кром<strong>е</strong><br />

того, в н<strong>е</strong><strong>е</strong> начинают включаться знаки п<strong>е</strong>р<strong>е</strong>носа (то <strong>е</strong>сть нажатия<br />

клавиши Enter фиксируются автоматич<strong>е</strong>ски):<br />

s t r i n g tw o L in e = @"это стр о к а ,<br />

занимающая дв <strong>е</strong> стр о ч к и .";<br />

Напомнит<strong>е</strong> <strong>е</strong>щ<strong>е</strong> раз, что означают символы \ п и \ t .<br />

I I; Это так называ<strong>е</strong>мы<strong>е</strong> <strong>е</strong>зс-посл<strong>е</strong>доват<strong>е</strong>льности. \ п — п<strong>е</strong>р<strong>е</strong>нос<br />

строки, \ t — табуляция, \ г — символ возврата. В т<strong>е</strong>кстовых<br />

файлах Windows строки должны заканчиваться символами<br />

\ г \ п (об этом мы говорили в глав<strong>е</strong> 8 при знакомств<strong>е</strong> с константой<br />

E n v ir o n m e n t. NewLine). Чтобы использовать в строк<strong>е</strong><br />

обратную косую ч<strong>е</strong>рту, которую компилятор н<strong>е</strong> воспринима<strong>е</strong>т как<br />

<strong>е</strong>зс-посл<strong>е</strong>доват<strong>е</strong>льность, д<strong>е</strong>лайт<strong>е</strong> <strong>е</strong><strong>е</strong> двойной: \\.<br />

А что там говорилось про пр<strong>е</strong>образовани<strong>е</strong> строки в массив<br />

байтов? Как это работа<strong>е</strong>т?<br />

! Для записи строк в т<strong>е</strong>кстовый файл и их дальн<strong>е</strong>йш<strong>е</strong>го<br />

чт<strong>е</strong>ния д<strong>е</strong>йствит<strong>е</strong>льно достаточно объ<strong>е</strong>ктов Stream R eader<br />

и S tream W riter. Но для бол<strong>е</strong><strong>е</strong> сложных оп<strong>е</strong>раций тр<strong>е</strong>бу<strong>е</strong>тся<br />

зад<strong>е</strong>йствовать други<strong>е</strong> потоки. Записывать в файл числа, массивы,<br />

колл<strong>е</strong>кции и объ<strong>е</strong>кты S trea m W riter н<strong>е</strong> ум<strong>е</strong><strong>е</strong>т. Впроч<strong>е</strong>м,<br />

эта т<strong>е</strong>ма буд<strong>е</strong>т подробно рассмотр<strong>е</strong>на чуть позж<strong>е</strong>.<br />

Б<br />

; Как мн<strong>е</strong> создать собств<strong>е</strong>нны<strong>е</strong> диалоговы<strong>е</strong> окна?<br />

5 Вы мож<strong>е</strong>т<strong>е</strong> добавить в про<strong>е</strong>кт форму и придать <strong>е</strong>й нужный<br />

вид. Зат<strong>е</strong>м при помощи оп<strong>е</strong>ратора new созда<strong>е</strong>тся <strong>е</strong><strong>е</strong> экз<strong>е</strong>мпляр<br />

(им<strong>е</strong>нно так вы поступали с объ<strong>е</strong>ктом O p e n F ile D ia lo g ). Посл<strong>е</strong><br />

ч<strong>е</strong>го оста<strong>е</strong>тся вызвать <strong>е</strong><strong>е</strong> м<strong>е</strong>тод S h ow D ialog (), и ново<strong>е</strong><br />

окно диалога готово. Подробно этот проц<strong>е</strong>сс буд<strong>е</strong>т рассмотр<strong>е</strong>н<br />

в глав<strong>е</strong> 13.<br />

Б<br />

; Зач<strong>е</strong>м закрывать потоки посл<strong>е</strong> окончания работы?<br />

! Сообщал ли вам когда-нибудь т<strong>е</strong>кстовый р<strong>е</strong>дактор, что он<br />

н<strong>е</strong> мож<strong>е</strong>т открыть файл, потому что «файл использу<strong>е</strong>тся другим<br />

прилож<strong>е</strong>ни<strong>е</strong>м»? Windows блокиру<strong>е</strong>т открыты<strong>е</strong> файлы и н<strong>е</strong> позволя<strong>е</strong>т<br />

открывать в других прилож<strong>е</strong>ниях. Им<strong>е</strong>нно это происходит<br />

с ваш<strong>е</strong>й программой при открытии файла. Файл оста<strong>е</strong>тся заблокированным,<br />

пока вы н<strong>е</strong> воспользу<strong>е</strong>т<strong>е</strong>сь м<strong>е</strong>тодом C lo s e ().<br />

дальш<strong>е</strong> ► 411


напишит<strong>е</strong> это сам ост оят <strong>е</strong>льно<br />

возьми в руку карандаш<br />

Для работы с файлами и папками в .NET сущ<strong>е</strong>ствуют два встро<strong>е</strong>нных класса с многочисл<strong>е</strong>нными<br />

статич<strong>е</strong>скими м<strong>е</strong>тодами. Класс F i l e сод<strong>е</strong>ржит м<strong>е</strong>тоды работы с файлами, а класс<br />

D i r e c t o r y да<strong>е</strong>т возможность работать с папками. Напишит<strong>е</strong>, как, с ваш<strong>е</strong>й точки зр<strong>е</strong>ния, работают<br />

пр<strong>е</strong>дставл<strong>е</strong>нны<strong>е</strong> сл<strong>е</strong>ва строки кода.<br />

Код<br />

i f ( ! D ir e c t o r y .E x is t s ( @ " c : \S Y P " ) ) {<br />

D i r e c t o r y . C r e a te D ir e c to r y (@ " c : \SY P");<br />

}<br />

i f ( D ir e c t o r y .E x is t s ( @ " c : \S Y P \B o n k " ) ) {<br />

D i r e c t o r y .D e le t e ( @ " c :\S Y P \B o n k " );<br />

}<br />

D i r e c t o r y . C r e a te D ir e c to r y (@ " c :\S Y P \B o n k " );<br />

Его ф ункция<br />

D ir e c to r y .S e tC r e a tio n T im e (@ " c :\SY P \B onk",<br />

new D a te T im e (1 9 7 6 , 09, 2 5 ) ) ;<br />

s t r i n g [] f i l e s = D ir e c t o r y .G e t F ile s ( @ " c : \w in d o w s \" ,<br />

" * .l o g " , S e a r c h O p t i o n .A l l D i r e c t o r i e s ) ;<br />

F i l e . W r ite A llT e x t(@ " c : \S Y P \B o n k \w e ir d o .t x t " ,<br />

@ " Э т о п <strong>е</strong> р в а я с т р о ч к а<br />

a э т о в т о р а я с т р о ч к а<br />

а э т о п о с л <strong>е</strong> д н я я с т р очка");<br />

F i l e . E n c r y p t ( @ " с : \S Y P \B o n k \w e ir d o . t x t " );<br />

к<br />

Это вы <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> проходили...<br />

с м о ж <strong>е</strong> т <strong>е</strong> ли вы угадать<br />

назнач<strong>е</strong>ни<strong>е</strong> этого м<strong>е</strong>тода?<br />

F i l e . С о р у ( @ " с : \S Y P \B o n k \w e ir d o . t x t " ,<br />

© " c : \S Y P \c o p y .t x t " ) ;<br />

D ateT im e myTime =<br />

D ir e c to r y .G e tC r e a tio n T im e (@ " c :\S Y P \B o n k " );<br />

F ile .S e tL a s tW r ite T im e (@ " c :\S Y P \c o p y .t x t " , m yT im e);<br />

F i l e . D e le t e ( @ " c : \S Y P \B o n k \w e ir d o .t x t " ) ;<br />

412 глава 9


О ткры ти<strong>е</strong> и сохран<strong>е</strong>ни<strong>е</strong> файлоб при помощи<br />

окон диалога<br />

П о с т р о и м програм м у, о тк р ы в а ю щ ую т <strong>е</strong> к с т о в ы й файл.<br />

О н а д о л ж н а позволять р<strong>е</strong>дакти р о вать ф айл и со хр а ­<br />

н я ть сд<strong>е</strong>ланны <strong>е</strong> и зм <strong>е</strong> н <strong>е</strong> н и я п р и п о м о щ и с та н д а р тн ы х<br />

эл<strong>е</strong>м <strong>е</strong>нтов у п р а вл<strong>е</strong>ния .NET.<br />

о<br />

о<br />

^ ^ -------У п р а ж н <strong>е</strong> н и <strong>е</strong> !<br />

Создани<strong>е</strong> простои цюрмы.<br />

Вам п о тр<strong>е</strong>бу<strong>е</strong> тся т<strong>е</strong> ксто во <strong>е</strong> нол<strong>е</strong> и дв<strong>е</strong> к н о п<br />

ки. П <strong>е</strong> р <strong>е</strong> та щ и т<strong>е</strong> на ф орм у такж <strong>е</strong> эл<strong>е</strong>м <strong>е</strong>нты<br />

O p e n F i l e D i a l o g и S a v e F i l e D i a l o g . Д в о й н ы м<br />

щ <strong>е</strong>лчком на к н о п к а х создайт<strong>е</strong> о б р а б о т ч и к и собы ­<br />

т и й и д о б а в ь т <strong>е</strong> з а к р ы т о <strong>е</strong> с т р о к о в о <strong>е</strong> п о л <strong>е</strong> n a m e .<br />

Д обавьт<strong>е</strong> о п <strong>е</strong> р а то р u s i n g для S y s t e m . 10.<br />

Привязка кнопки open к эл<strong>е</strong>м<strong>е</strong>нту openFileDialog.<br />

К н о п к а O pen о то б р а ж а <strong>е</strong> т объ<strong>е</strong>кт O p e n F i l e D i a l o g и использу<strong>е</strong>т<br />

м <strong>е</strong>тод F i l e . R e a d A l l T e x t () для ч т <strong>е</strong> н и я ф айла в т<strong>е</strong> ксто во м пол<strong>е</strong>:<br />

p r i v a t e v o i d o p e n _ C lic k ( o b j e c t se n d e r , E ven tA rgs e) {<br />

i f ( o p e n F ile D ia lo g l.S h o w D ia lo g 0 == D i a l o g R e s u l t . OK) {<br />

}<br />

}<br />

name = o p e n F i le D i a l o g l. F ileN am e;<br />

t e x t B o x l . C l e a r ( );<br />

t e x t B o x l.T e x t = F ile .R e a d A llT e x t ( n a m e ) ;<br />

Д<strong>е</strong>йствия для кнопки Save.<br />

1Снопка S a v e использу<strong>е</strong>т для<br />

W r i t e A l l T e x t О :<br />

чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Чтобы разв<strong>е</strong>рнуть т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong><br />

на всю форму, п<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> на н<strong>е</strong><strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нт T ableL ayoutP anel из окна<br />

C on tain ers, присвойт<strong>е</strong> свойству Dock<br />

знач<strong>е</strong>ни<strong>е</strong> F i l l , а при помощи р<strong>е</strong>дактора<br />

свойств Rows и Colunms создайт<strong>е</strong> дв<strong>е</strong><br />

строки и один столб<strong>е</strong>ц, в в<strong>е</strong>рхнюю яч<strong>е</strong>йку<br />

п<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт TextBox, в нижнюю<br />

— эл<strong>е</strong>м<strong>е</strong>нт FlowLayoutPanel.<br />

Свойству Dock присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

F i l l , а свойству F low D ireC tion —<br />

знач<strong>е</strong>ни<strong>е</strong> R ightT oL eft и п<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong><br />

туда дв<strong>е</strong> кнопки. Разм<strong>е</strong>р в<strong>е</strong>рхн<strong>е</strong>го ряда<br />

эл<strong>е</strong>м<strong>е</strong>нта T ableL ayoutP anel задайт<strong>е</strong><br />

равным 100%, а разм<strong>е</strong>р нижн<strong>е</strong>го ряда<br />

пом<strong>е</strong>няйт<strong>е</strong> таким образом, чтобы там<br />

пом<strong>е</strong>стились дв<strong>е</strong> кнопки.<br />

jC Sid^Jle Tent Editor<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> Open<br />

о<strong>е</strong>ла<strong>е</strong>т видимым эл<strong>е</strong>м<strong>е</strong>нт<br />

управл<strong>е</strong>ния OpenFileDialog.<br />

сохр ан<strong>е</strong>ния файла м<strong>е</strong>тод F i l e .<br />

p r i v a t e v o i d s a v e _ C l i c k ( o b j e c t s e n d e r , E ven tA rgs e) {<br />

i f ( s a v e F il e D ia l o g l .S h o w D ia l o g 0 == D ia lo g R e su lt.O K )<br />

}<br />

}<br />

name = s a v e F i l e D i a l o g l . F ileN am e;<br />

F ile .W r it e A llT e x t ( n a m e , t e x t B o x l . T e x t );<br />

Д руги<strong>е</strong> свойства окна д и ал о га.<br />

★ П о м <strong>е</strong> н я й т<strong>е</strong> т<strong>е</strong> к с т в стр о к<strong>е</strong> заголовка с п о м о щ ь ю свойства<br />

★<br />

T i t l e объ<strong>е</strong>кта S a v e F i l e D i a l o g .<br />

У ка ж и т<strong>е</strong> откры ва<strong>е</strong>м ую п о ум о л ч а н и ю папку с п о м о щ ь ю<br />

свойства i n i t i a l F o l d e r .<br />

★ У ка ж и т<strong>е</strong> , ч т о объ<strong>е</strong>кт O p e n F i l e D i a l o g долж <strong>е</strong> н показы вать<br />

то л ь ко т<strong>е</strong> ксто вы <strong>е</strong> ф айлы , с п о м о щ ь ю свойств а F i l t e r .<br />

да<br />

Это т<strong>е</strong>кстово<strong>е</strong> пол<strong>е</strong>,<br />

свойство Multiline которого<br />

им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

true.<br />

(М <strong>е</strong>т оды R e a c tA llT e x tQ<br />

Save.<br />

и WriteAllTextO являются<br />

частью класса File- дол<strong>е</strong><strong>е</strong><br />

подробно мы поговорим<br />

о них ч<strong>е</strong>р<strong>е</strong>з н<strong>е</strong>сколько<br />

. страниц,.<br />

Если н<strong>е</strong> задать это свойство.<br />

раскрывающийся<br />

список в нижн<strong>е</strong>й части окон<br />

диалога Open и Save буд<strong>е</strong>т<br />

пустым. В данном случа<strong>е</strong><br />

используйт<strong>е</strong> фильтр: Text<br />

Files (*.txt)<br />

дальш<strong>е</strong> ^ 413


бросайт<strong>е</strong> мусор в нужную корзину<br />

^ з ь м и в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот каки<strong>е</strong> д<strong>е</strong>йствия производят строки кода.<br />

Код<br />

i f (!D i r e c t o r y . E x i s t s {@"с :\SY P ")) {<br />

D i r e c t o r y . C r e a t e D i r e c t o r y (@"с:\SY P") ;<br />

}<br />

i f ( D ir e c t o r y .E x is t s ( @ " c : \S Y P \B o n k " )) {<br />

D i r e c t o r y . D e l e t e (@"C :\SY P \B onk ");<br />

}<br />

D i r e c t o r y . C r e a te D ir e c to r y (@ " c:\SY P \B onk ");<br />

Функция<br />

пров<strong>е</strong>ря<strong>е</strong>т сущ<strong>е</strong>ствовани<strong>е</strong> папки C:\SYP<br />

и созда<strong>е</strong>т <strong>е</strong><strong>е</strong>, <strong>е</strong>сли она отсутству<strong>е</strong>т.<br />

Пров<strong>е</strong>ря<strong>е</strong>т сущ<strong>е</strong>ствовани<strong>е</strong> папки С:\<br />

SYP\Bonk. Если папка сущ<strong>е</strong>ству<strong>е</strong>т, она<br />

удаля<strong>е</strong>тся.<br />

Созда<strong>е</strong>т папку C:\SYP\Bonk.<br />

D ir e c to r y .S e tC r e a tio n T im e (@ " c:\SY P\B onk",<br />

new D a te T im e (1 9 7 6 , 09, 2 5 ) ) ;<br />

Зада<strong>е</strong>т вр<strong>е</strong>мя создания папки C:\SYP\<br />

Bonk, Z S с<strong>е</strong>нтября 1 9 7 6 .<br />

s t r i n g [] f i l e s = D i r e c t o r y .G e t F il e s ( @ " c :\w in d o w s \" ,<br />

" * .lo g " , S e a r c h O p t i o n .A l l D i r e c t o r i e s );<br />

F i l e . W r it e A llT e x t(@"с :\S Y P \B o n k \w e ir d o .t x t " ,<br />

@"Это п<strong>е</strong>рвая строчка<br />

a э т о вторая строчка<br />

а э т о посл<strong>е</strong>дняя стр оч к а");<br />

F i l e . E n c r y p t(@"с :\S Y P \B o n k \w e ir d o . t x t " );<br />

'<br />

Э т о альт<strong>е</strong>рнативный способ исполь-■<br />

зования обь<strong>е</strong>кта CryptoStream.<br />

F i l e . C op y(@"с: \S Y P \B o n k \w e ir d o .t x t " ,<br />

© " C : \S Y P \c o p y .t x t " ) ;<br />

Получа<strong>е</strong>т список вс<strong>е</strong>х файлов<br />

с расшир<strong>е</strong>ни<strong>е</strong>м *.1од в папк<strong>е</strong> C:\WindowSj<br />

включая файлы в подпапках.<br />

Созда<strong>е</strong>т файл weirdo.txt (<strong>е</strong>сли он<br />

<strong>е</strong>щ<strong>е</strong> н<strong>е</strong> создан) в папк<strong>е</strong> C:\SYP\Bonk<br />

и записыва<strong>е</strong>т в н<strong>е</strong>го три строки<br />

т<strong>е</strong>кста.<br />

Зашифровыва<strong>е</strong>т файл weirdo.txt<br />

при помощи встро<strong>е</strong>нной сист<strong>е</strong>мы<br />

шифрования Windows.<br />

Копиру<strong>е</strong>т сод<strong>е</strong>ржимо<strong>е</strong> файла C:\SYP\<br />

Bonk\weirdo.txt в файл C:\SYP\Copy.txt.<br />

D ateT im e myTime =<br />

D ir e c to r y .G e tC r e a tio n T im e (@ " c : \SY P \B onk ") ;<br />

F ile .S e t L a s t W r it e T im e ( © " c :\S Y P \c o p y .tx t" , m yT im e);<br />

F i l e .D e l e t e ( @ " c : \S Y P \B o n k \w e ir d o .t x t " ) ;<br />

Объявля<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную myTime и присваива<strong>е</strong>т<br />

<strong>е</strong>й вр<strong>е</strong>мя создания п а п к и С:\<br />

SYP\Bonk.<br />

М<strong>е</strong>ня<strong>е</strong>т посл<strong>е</strong>дн<strong>е</strong><strong>е</strong> вр<strong>е</strong>мя записи файла<br />

copy.txt в папк<strong>е</strong> C:\SYP\, присваивая<br />

<strong>е</strong>му знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной myTime.<br />

Удаля<strong>е</strong>т файл C:\SYP\Bonk\weirdo.txt.<br />

414 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

инт<strong>е</strong>рф<strong>е</strong>йс IDisposable<br />

М н о ж <strong>е</strong> с тв о классов .N E T р<strong>е</strong>ализу<strong>е</strong>т к р а й н <strong>е</strong> п о л <strong>е</strong> зн ы й и н т <strong>е</strong> р ­<br />

ф <strong>е</strong>йс I D i s p o s a b l e . О н с о д <strong>е</strong> р ж и т в с <strong>е</strong> г о о д и н м <strong>е</strong>тод Dispose О .<br />

Э то т инт<strong>е</strong> р ф <strong>е</strong> й с о б ъ я сн я<strong>е</strong>т п р ограм м <strong>е</strong>, ч т о <strong>е</strong>сть ва ж н ы <strong>е</strong> в<strong>е</strong>щ и,<br />

к о то р ы <strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся сд<strong>е</strong>лать для зав<strong>е</strong>рш <strong>е</strong>ния работы . В<strong>е</strong>дь р а с ­<br />

п р <strong>е</strong> д <strong>е</strong> л <strong>е</strong> н н ы <strong>е</strong> р <strong>е</strong> с у р с ы н<strong>е</strong> освобож д аю тся сам остоят<strong>е</strong>льно.<br />

Для э т о го и м тр<strong>е</strong>бу<strong>е</strong>тся м <strong>е</strong>тод D i s p o s e ( ) .<br />

В оспользу<strong>е</strong>м ся ф ун кц и <strong>е</strong> й И С Р G o То D e fin itio n для п р о см о тр а<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ния и н т<strong>е</strong>рф <strong>е</strong> й са I D i s p o s a b l e . В в<strong>е</strong>дит<strong>е</strong> «ID isposable»<br />

в п р о и зволь н о м м<strong>е</strong>ст<strong>е</strong> в н у тр и класса, щ <strong>е</strong> л кн и т<strong>е</strong> на э т о й с т р о ч ­<br />

к<strong>е</strong> п р а в о й к н о п к о й м ы ш и и в ы б р и т<strong>е</strong> в м <strong>е</strong> ню ком анду G o То<br />

D e fin itio n . О т к р о <strong>е</strong> тс я вкладка с кодом . В о т ч т о в ы увид ит<strong>е</strong>:<br />

При объявл<strong>е</strong>нии<br />

о^<strong>е</strong>ктов в разд<strong>е</strong>л<strong>е</strong><br />

using вызов м<strong>е</strong>тода<br />

Dispose ( ) таких объ<strong>е</strong>ктов<br />

буд<strong>е</strong>т осущ<strong>е</strong>ствляться<br />

автоматич<strong>е</strong>ски.<br />

namespace System<br />

{<br />

// Кратко<strong>е</strong> описани<strong>е</strong>:<br />

Многи<strong>е</strong> классы распр<strong>е</strong>д<strong>е</strong>ляют м<strong>е</strong>жду собой<br />

таки<strong>е</strong> важны<strong>е</strong> р<strong>е</strong>сурсы как память,<br />

файлы и други<strong>е</strong> объ<strong>е</strong>кты. Они со<strong>е</strong>диня- ^<br />

ются с этими р<strong>е</strong>сурсами и н<strong>е</strong> разрывают<br />

связь, пока н<strong>е</strong> получат сигнал, что<br />

работа законч<strong>е</strong>на.<br />

II Да<strong>е</strong>т м<strong>е</strong>тод освобожд<strong>е</strong>ния распр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных р <strong>е</strong> с у р с о в .<br />

public interface IDisposable<br />

{<br />

// Кратко<strong>е</strong> описани<strong>е</strong>:<br />

// Выполня<strong>е</strong>т опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>мы<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong>м задачи,<br />

// связанны<strong>е</strong> с освобожд<strong>е</strong>ни<strong>е</strong>м или сбросом<br />

/ / н<strong>е</strong>управля<strong>е</strong>мых р<strong>е</strong>сурсов<br />

void Dispose О;<br />

/\юбой класс, р<strong>е</strong>ализуюш,ий инт<strong>е</strong>рф<strong>е</strong>йс<br />

IDisposable, н<strong>е</strong>м<strong>е</strong>дл<strong>е</strong>нно освобожда<strong>е</strong>т любы<strong>е</strong><br />

зад<strong>е</strong>йствованны<strong>е</strong> р<strong>е</strong>сурсы посл<strong>е</strong> вызова <strong>е</strong>го м <strong>е</strong>­<br />

тода DisposeQ. Это посл<strong>е</strong>дн<strong>е</strong><strong>е</strong>, что д<strong>е</strong>ла<strong>е</strong>тся<br />

п<strong>е</strong>р<strong>е</strong>д зав<strong>е</strong>рил<strong>е</strong>ни<strong>е</strong>м работы с объ<strong>е</strong>ктом.<br />

рас-пр<strong>е</strong>-д<strong>е</strong>-лять, гл.<br />

раздавать р<strong>е</strong>сурсы или<br />

обязанности для опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных<br />

ц<strong>е</strong>л<strong>е</strong>й. Управляющий<br />

р аспр<strong>е</strong>д <strong>е</strong>л и л вс<strong>е</strong><br />

конф<strong>е</strong>р<strong>е</strong>нц-залы под б<strong>е</strong>спол<strong>е</strong>зный<br />

с<strong>е</strong>минар по м<strong>е</strong>н<strong>е</strong>джм<strong>е</strong>нту.<br />

дальш<strong>е</strong> > 415


мн<strong>е</strong> снова нужно к в<strong>е</strong>т <strong>е</strong>ринару<br />

Оп<strong>е</strong>раторы using Ьк ср<strong>е</strong>дство изб<strong>е</strong>)кать сист<strong>е</strong>мных ошибок<br />

Н а п р о т я ж <strong>е</strong> н и и главы вам тв <strong>е</strong> р д и л и о н <strong>е</strong> о б хо д и м о сти за к р ы в а т ь п о ­<br />

т о к и . В<strong>е</strong>дь и м <strong>е</strong> н н о с эти м связана одна из сам ы х р а с п р о с тр а н <strong>е</strong> н н ы х<br />

о ш и б о к . К счастью , в C # им <strong>е</strong><strong>е</strong>тся зам <strong>е</strong>чат<strong>е</strong>льны й и н стр ум <strong>е</strong> н т, позвол<br />

я ю щ и й изб <strong>е</strong>ж ать п о д о б н о й с и туации — это и н т <strong>е</strong> р ф <strong>е</strong> й с I D is p o s a b le<br />

с <strong>е</strong> го м <strong>е</strong>тодом D is p o s e ( ) . Е сли п о м <strong>е</strong> с т и т ь к о д п о т о к а в о п <strong>е</strong> р а т о р<br />

u s i n g , п о т о к н а ч н <strong>е</strong> т закры ваться а в то м а ти ч<strong>е</strong>ски . Вам н у ж н о то л ько<br />

о б ъ я в и т ь п о т о к о в у ю с с ы л к у с эти м о п <strong>е</strong> р а то р о м , п о м <strong>е</strong> сти в сл<strong>е</strong>дом в<br />

ф и гу р н ы х ско б ка х и сп о л ь зую щ и й эту ссы лку код. О п <strong>е</strong> р а то р u s in g п о ­<br />

сл<strong>е</strong> зав<strong>е</strong>рш <strong>е</strong>ния р а б о ты с э ти м кодом буд<strong>е</strong>т а в т о м а т и ч <strong>е</strong> с к и в ы зы в а т ь<br />

м <strong>е</strong> т о д D i s p o s e () п о т о к а . В о т как э то работа<strong>е</strong>т;<br />

о п <strong>е</strong> р а т о р о м using вс<strong>е</strong>гда<br />

о б <strong>е</strong> л <strong>е</strong> н и <strong>е</strong> объ<strong>е</strong>кта ■<br />

В данном случа<strong>е</strong> р<strong>е</strong>чь ид<strong>е</strong>т<br />

Ш <strong>е</strong><strong>е</strong> н<strong>е</strong> о т<strong>е</strong>х оп<strong>е</strong>раторах<br />

using, которы<strong>е</strong> распола ­<br />

гаются в в<strong>е</strong>рхн<strong>е</strong>й части<br />

кот.<br />

■М блок кода в ф и­<br />

гурных скобках.<br />

using (StreamWriter sw = new StreamWriter("secret_plan.txt")) {<br />

}<br />

sw.WriteLine("Как поб<strong>е</strong>дить Капитана В<strong>е</strong>ликол<strong>е</strong>пного");<br />

Эти оп<strong>е</strong>ратоsw.WriteLine<br />

("Ещ<strong>е</strong> один г<strong>е</strong>ниальный с<strong>е</strong>кр<strong>е</strong>тный план"); Р^'(используют<br />

sw.WriteLine("от Жулика")<br />

Посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния работы<br />

оп<strong>е</strong>ратора using, в зы в а <strong>е</strong> т ­<br />

ся м<strong>е</strong>тод '^од DisposeQ Disao'ip.n использи<strong>е</strong>мого<br />

в данном случа<strong>е</strong> на п.<br />

« к т указыва<strong>е</strong>т объ~<br />

о Л <strong>е</strong> к т , с о зд а н ^<br />

usinfi Как и лю~<br />

бой ругой.<br />

Вс<strong>е</strong> потоки им<strong>е</strong>ют закрывающий м<strong>е</strong>тод Dispose ().<br />

При этом поток, объявл<strong>е</strong>нный внутри оп<strong>е</strong>ратора<br />

using, вс<strong>е</strong>гда закрыва<strong>е</strong>т с<strong>е</strong>бя сам!<br />

По одному оп<strong>е</strong>ратору using на объ<strong>е</strong>кт<br />

О п <strong>е</strong> р а т о р ы u s in g м о ж н о пом <strong>е</strong>щ ать д р у г за д руго м , п р и этом<br />

вам н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся д о п о л н и т<strong>е</strong> л ь н ы й н а б о р ф и гу р н ы х скобок.<br />

u s in g (Stream R eader r e a d e r = new S tr e a m R ea d er {" s e c r e t _ p l a n . t x t " ))<br />

u s in g (S trea m W riter w r i t e r = new S tr e a m R ea d er ( " e m a il. t x t " ))<br />

{<br />

// оп<strong>е</strong>раторы, использующи<strong>е</strong> устройства чт<strong>е</strong>ния и записи<br />

u sin g закро<strong>е</strong>т <strong>е</strong>го автоматич<strong>е</strong>ски.<br />

Потоки ВСЕГДА<br />

сл<strong>е</strong>ду<strong>е</strong>т т я в -<br />

лять внутри оп<strong>е</strong>ратора<br />

using. Это<br />

гарантиру<strong>е</strong>т, что<br />

посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния<br />

работы они<br />

будут закрыты!<br />

416 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Пробл<strong>е</strong>мы на работ<strong>е</strong><br />

П <strong>е</strong>р<strong>е</strong>д вам и Б райан. О н р а зр а б о тч и к п р о гр а м м на С# и л ю б и т свою работу, н о обожа<strong>е</strong>т устраивать н<strong>е</strong>запланированны<br />

<strong>е</strong> вы хо д н ы <strong>е</strong> . Е го н а ч а л ь н и к н <strong>е</strong> н а в и д и т та ки <strong>е</strong> си туа ц и и , п о это м у Б р а й а н у п р и х о д и тс я<br />

п р ид ум ы вать в<strong>е</strong>ски<strong>е</strong> п р и ч и н ы . ^ —<br />

О<br />

Сынок, с марта ты<br />

отпрашива<strong>е</strong>шься к<br />

в<strong>е</strong>т<strong>е</strong>ринару уж<strong>е</strong> д<strong>е</strong>вятый раз.<br />

Н<strong>е</strong> поискать ли т<strong>е</strong>б<strong>е</strong> новую<br />

работу?<br />

Создадим программу уч<strong>е</strong>та оправданий Брайана<br />

И спользуйт<strong>е</strong> свои з н а н и я о ч т <strong>е</strong> н и и ф айлов и записи в н и х для создания<br />

п р о гр а м м ы п о п о и с к у п о д хо д ящ <strong>е</strong> го оправдания. Б райану н у ж н о отсл<strong>е</strong>ж<br />

и в а ть , каки<strong>е</strong> п р и ч и н ы ухода с р а б о ты о н использовал в посл<strong>е</strong>дн<strong>е</strong><strong>е</strong><br />

вр<strong>е</strong>м я, и ка к на н и х о тр <strong>е</strong> а ги р о в а л <strong>е</strong>го н ачальник.<br />

V<br />

рАО<strong>е</strong>М<br />

со<br />

<strong>е</strong>о6 > -<br />

Б р а й а н х о ч <strong>е</strong> т<br />

хранить п<strong>е</strong>р<strong>е</strong>ч<strong>е</strong>нь<br />

причин ухода<br />

с работы в одном<br />

м<strong>е</strong>ст<strong>е</strong>, поэтому<br />

выд<strong>е</strong>лим для н<strong>е</strong>го<br />

Ы кпку-<br />

Excuse Manager<br />

Bccuse My dog has a headachae<br />

FtemAs Didnt woik. Boss knows I dwit have a dog<br />

Last Wednesday, Mardi 04. Ж Ш Q -»<br />

Wedaie<br />

3 ^ 1 /2)1 0 12;®:51 PM<br />

f^ n k m<br />

Иногда Брайану л<strong>е</strong>нь<br />

выдумывать. Поэтому<br />

добавим кнопку<br />

Random, которая<br />

буд<strong>е</strong>т случайным<br />

образом выбирать<br />

причину прогула.<br />

А<br />

Папка сод<strong>е</strong>ржит т<strong>е</strong>кстовы<strong>е</strong><br />

файлы, в каждом из кот о­<br />

рых записано одно оправдани<strong>е</strong>.<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> Save<br />

сохраня<strong>е</strong>т т<strong>е</strong>кущ<strong>е</strong><strong>е</strong> объясн<strong>е</strong>ни<strong>е</strong><br />

Брайана в такой файл.<br />

Чтобы <strong>е</strong>го открыть, используйт<strong>е</strong><br />

кнопку Open.<br />

ID:- 3<br />

дальш<strong>е</strong> * 417


уваж ит<strong>е</strong>льны<strong>е</strong> причины для брайана<br />

e<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

★<br />

★<br />

Помнит<strong>е</strong>, что<br />

символ ! означа<strong>е</strong>т<br />

Н Е Т — то<br />

<strong>е</strong>ст ь зд<strong>е</strong>сь п р о ­<br />

в<strong>е</strong>ря<strong>е</strong>тся, н<strong>е</strong> явля<strong>е</strong>тся<br />

ли марил<br />

Создани<strong>е</strong> срормы<br />

Постройт<strong>е</strong> для Брайана программу, выбирающую оправдани<strong>е</strong>.<br />

Вам тр<strong>е</strong>бу<strong>е</strong>тся ф орм а со сл<strong>е</strong>дую щ им и о тл и ч и т<strong>е</strong> л ь н ы м и п р и знакам и:<br />

★ П р и п <strong>е</strong> р в о й загрузк<strong>е</strong> д о л ж н а б ы ть д о ступ на т о л ь к о к н о п к а F o ld e r .<br />

★<br />

★<br />

★<br />

П р и о тк р ы ти и и сохр а н <strong>е</strong> н и и п р и ч и н ы п р и пом о щ и эл<strong>е</strong>м<strong>е</strong>нта L a b e l<br />

отобража<strong>е</strong>тся т<strong>е</strong>кущ ая дата. С войство A u t o S i z e это го .эл<strong>е</strong>м<strong>е</strong>нта им <strong>е</strong><strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> F a l s e , а свойство B o r d e r S t y l e — знач<strong>е</strong>ни<strong>е</strong> F ix e d 3 D .<br />

П осл <strong>е</strong> со х р а н <strong>е</strong> н и я оправдания появля<strong>е</strong>тся о к н о Excuse W ritte n .<br />

К н о п к а F o ld e r о тк р ы в а <strong>е</strong> т о к н о диалога для п р о с м о тр а п а пок. П осл <strong>е</strong><br />

вы б о р а п а п к и п о я в л я ю тся к н о п к и Save, O p e n и R a n d o m Excuse.<br />

Е сли пользоват<strong>е</strong>ль изм <strong>е</strong>нил л ю б о <strong>е</strong> из т р <strong>е</strong> х п о л <strong>е</strong> й , в с тр о к у заголовка<br />

рядом с н а д п и сью «Excuse M anager» добавля<strong>е</strong>тся зв<strong>е</strong>здочка (* ). О н а<br />

исч<strong>е</strong>за<strong>е</strong>т посл<strong>е</strong> со х р а н <strong>е</strong> н и я д а н н ы х и л и о т к р ы т и я н о в о го ф айла.<br />

Ф орм а сл<strong>е</strong>дит за т<strong>е</strong>кущ <strong>е</strong>й п а п к о й и за т<strong>е</strong>м , б ы л о л и со хр а н <strong>е</strong> н о т<strong>е</strong>кущ<strong>е</strong><strong>е</strong><br />

оправдани<strong>е</strong>. Ч т о б ы сл<strong>е</strong>дить за п р о ц <strong>е</strong> ссо м со хр а н <strong>е</strong> н и я , используйт<strong>е</strong><br />

обработчики событий Changed для т р <strong>е</strong> х эл<strong>е</strong>м <strong>е</strong>нтов ввода.<br />

Создани<strong>е</strong> класса Excuse и хран<strong>е</strong>ни<strong>е</strong> <strong>е</strong>го экз<strong>е</strong>мпляра в qjopMe<br />

E x c u s e<br />

Description: string<br />

Results: string<br />

LastUsed: DateTime<br />

ExcusePath: string<br />

OpenFile(string)<br />

Save(string)<br />

Дважды щ<strong>е</strong>лкнув<br />

на п<strong>е</strong>р<strong>е</strong>-<br />

>тащ<strong>е</strong>нном на<br />

форму т <strong>е</strong>кстовом<br />

пол<strong>е</strong>,<br />

вы создадит<strong>е</strong><br />

для н<strong>е</strong>го обработчик<br />

соды-<br />

_тий Changed.<br />

Д обавим в ф орм у пол<strong>е</strong> C u r r e n t E x c u s e для о то б р а ж <strong>е</strong> н и я в ы б р а н н о го о правдания. Вам п о ­<br />

тр <strong>е</strong> б ую тся т р и п <strong>е</strong> р <strong>е</strong> г р у ж <strong>е</strong> н н ы х к о н с т р у к т о р а : для загрузки ф о рм ы , для о т к р ы т и я ф айла и<br />

для сл уч а й н о го оправдания. Д обавьт<strong>е</strong> м <strong>е</strong>тоды O p e n F i l e () и S a v e () для о т к р ы т и я и сохран<br />

<strong>е</strong> н и я оправдания. А зат<strong>е</strong>м <strong>е</strong>щ <strong>е</strong> и м <strong>е</strong>тод U p d a te F o r m ( ) , о б н о в л я ю щ и й эл<strong>е</strong>м <strong>е</strong>нты управл<strong>е</strong>н<br />

и я (а во т п о л <strong>е</strong>зн ы <strong>е</strong> п о д с к а з к и ) :<br />

Этот парам<strong>е</strong>тр опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т,<br />

вносились ли изм<strong>е</strong>н<strong>е</strong>ния в форму.<br />

Вам потр<strong>е</strong>бу<strong>е</strong>тся пол<strong>е</strong><br />

для <strong>е</strong>го хран<strong>е</strong>ния.<br />

p r i v a t e v o id U p d a teF o rm (b o o l changed)<br />

i f (! ! changed) { '' ^<br />

t h i s . d e s c r i p t i o n . T e x t = c u r r e n t E x c u s e .D e s c r ip t io n ;<br />

t h i s . r e s u l t s . T ex t = c u r r e n t E x c u s e .R e s u lt s ,•<br />

t h i s j l a s t u s e d . V a l u e = c u r r e n t E x c u s e . L a s tU s e d ;<br />

i f ^ ig t r i n g .I s N u l lO r E m p t y ( c u r r e n t E x c u s e .E x c u s e P a t h ) )<br />

_ y T ir e D a te .T e x t = F il e .G e t L a s t W r it e T im e ( c u r r e n t E x c u s e .E x c u s e P a t h ) .T o S t r in g O ;<br />

у- , t h i s . T e x t = "E xcuse M anager";


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Q Кнопка Save сохраня<strong>е</strong>т выбранно<strong>е</strong> оправдани<strong>е</strong> в qэaйл<br />

Щ <strong>е</strong> л ч о к на кн о п к <strong>е</strong> Save долж <strong>е</strong>н вы зы вать о к н о диалога Save As.<br />

★<br />

Каждая запись сохраня<strong>е</strong>тся в отд<strong>е</strong>льны й т<strong>е</strong> ксто вы й файл. В п<strong>е</strong>рвой с тр о ч к<strong>е</strong> ф игуриру<strong>е</strong>т<br />

оправдани<strong>е</strong>, во в то р о й — р<strong>е</strong>зультат, а в тр <strong>е</strong> ть<strong>е</strong> й — дата п осл<strong>е</strong>дн<strong>е</strong>го исп о л ьзо в а н и я (опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся<br />

м<strong>е</strong>тодом T o S t r i n g () об ъ <strong>е</strong> кта D a t e T i m e P ic k e r ) . Класс E x c u s e долж <strong>е</strong>н им <strong>е</strong>ть<br />

м<strong>е</strong>тод S a v e ( ) для сохран<strong>е</strong>ния оправданий в файл.<br />

★ О к н о диалога Save As д о л ж н о о тк р ы в а ть папку, вы б р а н н ую пользоват<strong>е</strong>л<strong>е</strong>м п р и п о м о ­<br />

щ и к н о п к и F older. В кач<strong>е</strong>ств<strong>е</strong> и м <strong>е</strong> н и ф айла ф и гур и р у<strong>е</strong> т названи<strong>е</strong> оправдания с расш<br />

и р <strong>е</strong> н и <strong>е</strong> м .txt.<br />

★ В о кн <strong>е</strong> диалога д о л ж н ы б ы т ь ф ил ьтры : т<strong>е</strong> ксто в ы <strong>е</strong> ф айлы (* .tx t) и вс<strong>е</strong> ф айлы (* .* ).<br />

★<br />

П о п ы т к и со х р а н <strong>е</strong> н и я п р и н <strong>е</strong> за п о л н <strong>е</strong> н н ы х п о л я х д о л ж н ы п р и в о д и ть к п о я в л <strong>е</strong> н и ю во т<br />

та к о го окн а диалога:<br />

Unable to save<br />

Please specify an eccuse arvd a resutt<br />

парам<strong>е</strong>тр MessageBoxlcon.<br />

О<br />

Кнопка Open открыва<strong>е</strong>т сохран<strong>е</strong>нны <strong>е</strong> оправдания<br />

Щ <strong>е</strong> л ч о к на кн о п к <strong>е</strong> O p e n долж <strong>е</strong>н вы зы вать о д н о и м <strong>е</strong> н н о <strong>е</strong> о к н о диалога.<br />

★<br />

В о кн <strong>е</strong> диалога O p e n п о ум о л ч а н и ю д о л ж н а б ы ть о т к р ы т а папка, вы бранная пользоват<strong>е</strong>л<strong>е</strong>м<br />

п р и п о м о щ и к н о п к и F older.<br />

★ Д обавьт<strong>е</strong> м <strong>е</strong>тод O pen () в класс E x c u s e .<br />

★<br />

М <strong>е</strong> то д C o n v e r t . T o D a te T im e О загруж а<strong>е</strong>т со хр а н <strong>е</strong> н н ы <strong>е</strong> д а н н ы <strong>е</strong> в эл<strong>е</strong>м <strong>е</strong>нт управл<strong>е</strong>н<br />

и я D a t e T i m e P ic k e r , в ы б и р а ю щ и й вр<strong>е</strong>мя.<br />

О<br />

★<br />

П о п ы т к а о т к р ы т ь н о в о <strong>е</strong> оправдани<strong>е</strong>, н<strong>е</strong> со х р а н и в пр<strong>е</strong>ды дущ <strong>е</strong><strong>е</strong>, д о л ж н а п р и в о д и ть<br />

к п о я в л <strong>е</strong> н и ю в о т та к о го о к н а диалога:<br />

Д ля вызова подобных окон диалога<br />

используйт<strong>е</strong> п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нный м<strong>е</strong>тод<br />

MessageBox.ShowO, позволяющий зааават<strong>е</strong>><br />

парам<strong>е</strong>тр MessageBoxButtons.<br />

YesA/c?. При щ<strong>е</strong>лчк<strong>е</strong> пользоват<strong>е</strong>ля на<br />

1^рпк<strong>е</strong> No м<strong>е</strong>тод ShowO возвраща<strong>е</strong>т<br />

PialogResult.No.<br />

^<br />

Н у , и , након<strong>е</strong>ц, пусть кнопка Random Excuse загружа<strong>е</strong>т случайно<strong>е</strong> оправдани<strong>е</strong><br />

П р и щ <strong>е</strong>лчк<strong>е</strong> на кн о п к <strong>е</strong> R a n d o m Excuse долж <strong>е</strong>н случайны м образом о ткр ы в а ть ся ф айл из п а п ­<br />

к и с оправданиям и.<br />

★<br />

О б ъ <strong>е</strong> кт R andom н у ж н о буд<strong>е</strong>т с о х р а н и т ь в пол<strong>е</strong> и п<strong>е</strong>р<strong>е</strong>дать одном у из п <strong>е</strong> р <strong>е</strong> гр у ж <strong>е</strong> н н ы х<br />

к о н с тр у к т о р о в объ<strong>е</strong>кта E x c u s e .<br />

★ Е сли о т к р ы т о <strong>е</strong> в д а н н ы й м о м <strong>е</strong>нт оправдани<strong>е</strong> н<strong>е</strong> сохр а н <strong>е</strong> н о , д о л ж н о появляться п о ­<br />

казанно<strong>е</strong> вы ш <strong>е</strong> о к н о ди алога с пр<strong>е</strong>дупр<strong>е</strong>ж д <strong>е</strong>ни<strong>е</strong>м .<br />

дальш<strong>е</strong> ► 419


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

н<strong>е</strong>нк<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как выглядит код для поиска оправданий отсутствия на работ<strong>е</strong>, который мы написали<br />

для Брайана.<br />

форма использу<strong>е</strong>т поля для сохран<strong>е</strong>ния<br />

p r i v a t e E x cu se c u r r e n tE x c u s e = new E x cu se () т<strong>е</strong>кущ<strong>е</strong>го объ<strong>е</strong>кта Excuse о о ы д р а н н у ю<br />

p r i v a t e s t r i n g s e l e c t e d F o l d e r = i / папку, a такж<strong>е</strong>, запомина<strong>е</strong>т, оыл ли из<br />

p r i v a t e b o o l form C hanged = f a l s e ;<br />

м<strong>е</strong>н<strong>е</strong>н этот объ<strong>е</strong>кт. К-ром<strong>е</strong> того, она<br />

Random random = new Random();<br />

( сохраня<strong>е</strong>т объ<strong>е</strong>кт Random для кнопки<br />

Random Excuse.<br />

p r i v a t e v o i d folder_Click( o b j e c t s e n d e r , E v en tA rg s e) {<br />

f o l d e r B r o w s e r D i a lo g l .S e le c t e d P a t h = s e l e c t e d F o l d e r ;<br />

выбора ПОАЬЗО-<br />

D ia lo g R e s u lt r e s u l t = f o l d e r B r o w s e r D i a lo g l . Sh o w D ia lo g ( ) ; "Л ПоСЛ<strong>е</strong> OWOop«<br />

i f ( r e s u l t == D ia lo g R e s u lt .OK) { / бйИл<strong>е</strong>л<strong>е</strong>М ^<br />

s e l e c t e d F o l d e r = f o l d e r B r o w s e r D ia lo g l.S e le c t e d P a t h ; сохр^ня<strong>е</strong><br />

s a v e . E n a b led = t r u e ; ( %кл\ОЧа<strong>е</strong>т v<br />

o p e n .E n a b le d = tr u e ;<br />

___ ) m e КН01А.КИ.<br />

ran d om E xcu se. E n a b led = t r u e ;<br />

}<br />

Это символ оп<strong>е</strong>ратора ИЛИ, выраж<strong>е</strong>ни<strong>е</strong> им <strong>е</strong>­<br />

<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true (<strong>е</strong>сли н<strong>е</strong> указано оправдани<strong>е</strong>)<br />

ИЛИ р<strong>е</strong>зультат.<br />

p r i v a t e v o id s a v e _ C l i c k ( o b j e c t se n d e r , E v e n t A r g s e j / {<br />

i f ( S t r in g .I s N u llO r E m p t y ( d e s c r ip t io n .T e x t ) m i t r i n g . IsN ullO rE m p ty ( r e s u l t s . T e x t ) ) {<br />

M essa g eB o x .S h o w (" P lea se s p e c i f y an e x c u g ^ a n d a r e s u l t " ,<br />

"U nable t o sa v e " , M essa g e B o x B u tto n s. OK, M e s s a g e B o x I c o n .E x c la m a tio n );<br />

r e tu r n ;<br />

}<br />

Зд<strong>е</strong>сь задаются ф и л ь -<br />


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

p r i v a t e b o o l CheckChanged() {<br />

i f (form Changed) {<br />

D ia lo g R e s u lt r e s u l t = M essa g eB o x .S h o w (<br />

"The c u r r e n t e x c u s e h a s n o t b e e n s a v e d . C o n tin u e ? " ,<br />

"W arning", M essa g eB o x B u tto n s.Y esN o , M essa g eB o x Ico n .W a rn in g )<br />

i f ( r e s u l t == Ц1 a 1 ogRe s u l t ^ I ^ ,<br />

}<br />

r e t u r n f a l s e , M e s s a g e B o x S h o w C ) в о з в р а щ а <strong>е</strong> т<br />

}<br />

r e t u r n tr u e ;<br />

п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> DialogResult, которо<strong>е</strong> мы<br />

мож<strong>е</strong>м пров<strong>е</strong>рить.<br />

p r i v a t e v o i d description_TextChanged(object se n d e r ,<br />

c u r r e n t E x c u s e .D e s c r ip t io n = d e s c r i p t i o n .T e x t ;<br />

U p d a te F o r m (tr u e );<br />

}<br />

p r i v a t e v o id results_TextChanged( o b j e c t s e n d e r , E v en tA rg s e) {<br />

c u r r e n t E x c u s e .R e s u lt s = r e s u l t s . T e x t ;<br />

U p d a te F o r m (tr u e );<br />

}<br />

p r i v a t e v o i d la s t U s e d _ V a lu e C h a n g e d ( o b j e c t s e n d e r , E ven tA rgs e) {<br />

c u r r e n tE x c u s e . L a stU se d = la s t U s e d .V a lu e ;<br />

J<br />

U p d ateF orm (tru eT ^ — ./Т<strong>е</strong>/з<strong>е</strong>Эдча знач<strong>е</strong>ния true м<strong>е</strong>тоду UpdateFormO J<br />

заставля<strong>е</strong>т <strong>е</strong>го пом<strong>е</strong>тить форму как из-<br />

, м<strong>е</strong>н<strong>е</strong>нную, но н<strong>е</strong> обновлять состояни<strong>е</strong> пол<strong>е</strong>й<br />

ввода.<br />

c l a s s E x cu se {<br />

p u b l i c s t r i n g D e s c r i p t i o n { g e t ; s e t ; }<br />

p u b l i c s t r i n g R e s u lt s { g e t ; s e t ; }<br />

p u b l i c D ateT im e L a stU se d g e t ; s e t ;<br />

p u b l i c s t r i n g E x cu se P a th g e t ; s e t ;<br />

p u b l i c E x cu se 0 {<br />

E x c u se P a th =<br />

}<br />

p u b l i c E x c u s e ( s t r i n g e x c u se P a th )<br />

O p e n F ile ( e x c u s e P a t h ) ;<br />

}<br />

p u b l i c E xcuse(R andom random, s t r i n g f o l d e r )<br />

s t r i n g [] file N a m e s = D i r e c t o r y . G e t F i l e s ( f o l d e r . * .t x t " )<br />

O p e n F ile ( f ile N a m e s [ r a n d o m .N e x t ( f ile N a m e s . L e n g t h ) ])<br />

{<br />

Это три обработчика<br />

событшА СЫпд<strong>е</strong>с1 рля<br />

EventArgs <strong>е</strong>) { ) л<strong>е</strong>й ввода ^°рМЫ. ШМ<strong>е</strong>-<br />

/ н<strong>е</strong>ни<strong>е</strong> состояния<br />

‘ из них говорит о >^оМ,<br />

ч т о оправдани<strong>е</strong> было от<br />

р<strong>е</strong>дактировано, поэтому<br />

Сначала сл<strong>е</strong>ду<strong>е</strong>т обно-<br />

\ вить экз<strong>е</strong>мпляр Excuse<br />

> Г ^ т <strong>е</strong> м<br />

UpdateFormO,<br />

e ^ e<br />

добавить<br />

^ Z Z b<br />

зв<strong>е</strong>здочку в строку заголовка<br />

и<br />

свойству Changed знач<strong>е</strong><br />

ни<strong>е</strong> true.<br />

Кнопка Random Exru


блок вы бора<br />

Запись файлоб сопровожда<strong>е</strong>тся приняти<strong>е</strong>м р<strong>е</strong>ш<strong>е</strong>ний<br />

В ам п р <strong>е</strong>д ст о и т написать м н о ж <strong>е</strong>ств о п рограм м , к о т о р ы <strong>е</strong> б<strong>е</strong>р ут входную и н ф о р м а ц и ю ,<br />

н а п р и м <strong>е</strong>р , и з ф айла, и р<strong>е</strong>ш аю т, ч то с н <strong>е</strong> й п о т о м д<strong>е</strong>лать. В о т к р ай н <strong>е</strong> ти п и ч н ы й код с<br />

о д н и м дл и н н ы м о п <strong>е</strong> р а т о р о м i f . О н п р о в <strong>е</strong>р я <strong>е</strong> т п <strong>е</strong>р <strong>е</strong>м <strong>е</strong>н н у ю p a r t и в ы водит в ф ай л<br />

р азл и ч н ы <strong>е</strong> стр о ч к и в за в и си м о сти о т и сп ол ьзу<strong>е</strong>м ого п <strong>е</strong>р <strong>е</strong>ч и сл <strong>е</strong>н и я . М н о ж <strong>е</strong>ст в о вариантов<br />

п р и в о д и т к м н о ж <strong>е</strong>ств <strong>е</strong>н н ы м к ом би н ац и я м о п <strong>е</strong> р а т о р о в e l s e i f :<br />

enum B o d y P a r t {<br />

H ea d ,<br />

S h o u l d e r s ,<br />

K n e e s ,<br />

T o e s<br />

П<strong>е</strong>ргд нами п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> част<strong>е</strong>й<br />

т<strong>е</strong>ла — голова, пл<strong>е</strong>чи, кол<strong>е</strong>ни<br />

и пальцы ног. Мы собира<strong>е</strong>мся сравнивать<br />

п<strong>е</strong>о<strong>е</strong>м<strong>е</strong>нную с каждым из<br />

эл<strong>е</strong>м<strong>е</strong>нтов и выводить строку в за ­<br />

висимости от р<strong>е</strong>зультата.<br />

}<br />

p r i v a t e v o i d W r i t e P a r t l n f o ( B o d y P a r t p a r t , S t r e a m W r i t e r w r i t e r ) {<br />

i f ( p a r t == B o d y P a r t .H e a d )<br />

w r i t e r . W r i t e L i n e ( "на г о л о в <strong>е</strong> в о л о с ы " ) ;<br />

e l s e i f ( p a r t == B o d y P a r t . S h o u l d e r s )<br />

w r i t e r . W r i t e L i n e ( " п л <strong>е</strong>ч и ш и р о к и <strong>е</strong> " ) ;<br />

e l s e i f ( p a r t == B o d y P a r t . K n e e s )<br />

w r i t e r . W r i t e L i n e ( " к о л <strong>е</strong> н и у з л о в а т ы <strong>е</strong> " ) ;<br />

e l s e i f ( p a r t == B o d y P a r t . T o e s )<br />

e l s e<br />

w r i t e r . W r i t e L i n e ( "пальцы н о г м а л <strong>е</strong> н ь к и <strong>е</strong> " ) ;<br />

Используя оп<strong>е</strong>раторы if/else,<br />

мы вынужд<strong>е</strong>ны снова и сно<br />

ва писать строчку it (part<br />

==[option]).<br />

Посл<strong>е</strong>дний оп<strong>е</strong>ратор else понадобится,<br />

<strong>е</strong>сли ни одного соотв<strong>е</strong>тствия н<strong>е</strong> буд<strong>е</strong>т<br />

■найд<strong>е</strong>но.<br />

w r i t e r . W r i t e L i n e ( "а п р о э т у ч а с т ь т <strong>е</strong> л а мы н и ч <strong>е</strong> г о н <strong>е</strong> з н а <strong>е</strong> м " ) ;<br />

WTVPM<br />

Каки<strong>е</strong> пробл<strong>е</strong>мы могут возникнуть при написании кода<br />

с многочисл<strong>е</strong>нными оп<strong>е</strong>раторами if/else? Подумайт<strong>е</strong> об<br />

оп<strong>е</strong>чатках, н<strong>е</strong>совпадающих скобках и т. п.<br />

422 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Оп<strong>е</strong>ратор switch<br />

С р авн<strong>е</strong>ни<strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й с набором р а з л и ч н ы х знач<strong>е</strong>н<br />

и й — ча сто встр<strong>е</strong>чаю щ аяся ситуация, о со б <strong>е</strong> н н о п р и<br />

ч т <strong>е</strong> н и и и за п иси ф айлов. О н а насто л ько р а сп р о стр а ­<br />

н<strong>е</strong>на, ч т о в C # им <strong>е</strong><strong>е</strong>тся о с о б ы й о п <strong>е</strong> р а то р .<br />

Э то о п <strong>е</strong> р а то р switch. В о т ка к с <strong>е</strong>го п о м о щ ь ю буд<strong>е</strong>т вы ­<br />

гляд<strong>е</strong>ть код с пр<strong>е</strong>ды дущ <strong>е</strong>й с тр а н и ц ы , п о с т р о <strong>е</strong> н н ы й на<br />

м н о го ч и с л <strong>е</strong> н н ы х к о м б и н а ц и я х о п <strong>е</strong> а то р о в i f / e l s e :<br />

enum B o d y P a r t<br />

H ea d ,<br />

S h o u l d e r s ,<br />

Ключ<strong>е</strong>во<strong>е</strong> слово break; по-<br />

-казыва<strong>е</strong>т, гд<strong>е</strong> заканчива<strong>е</strong>мся<br />

один оп<strong>е</strong>ратор case и начина<strong>е</strong>тся<br />

сл<strong>е</strong>дующий. Ч<br />

нНачнит<strong>е</strong> а ч н и т <strong>е</strong> с<br />

ключ<strong>е</strong>вого слова<br />

switch, за которым сл<strong>е</strong>ду<strong>е</strong>т<br />

сравнива<strong>е</strong>мая п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная.<br />

T o e s , ■ ■ --------<br />

Оп<strong>е</strong>ратор switch н<strong>е</strong> им<strong>е</strong><strong>е</strong>т никаких<br />

особ<strong>е</strong>нност<strong>е</strong>й, пр<strong>е</strong>дназнач<strong>е</strong>нных<br />

для работы с файлами. Это вс<strong>е</strong>го<br />

лишь пол<strong>е</strong>зный инструм<strong>е</strong>нт,<br />

который мы мож<strong>е</strong>м использовать<br />

в т<strong>е</strong>кущ<strong>е</strong>й ситуации.<br />

Оп<strong>е</strong>ратор switch<br />

сравнива<strong>е</strong>т ОДНУ<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

с МНОЖЕСТВОМ<br />

знач<strong>е</strong>ний.<br />

Зав<strong>е</strong>ршить оп<strong>е</strong>ратор case можно<br />

знаком п<strong>е</strong>р<strong>е</strong>носа строки. Программа<br />

вс<strong>е</strong> равно буд<strong>е</strong>т компилироваться,<br />

так как один оп<strong>е</strong>ратор<br />

case заканчива<strong>е</strong>тся maMj гд<strong>е</strong><br />

начина<strong>е</strong>тся сл<strong>е</strong>дующий.<br />

W r i t e P a r t l n f o ( B o d y P a r t p a r t , S t r e a m W r i t e r w r i t e r )<br />

s w i t c h ^ { p a r ^ {<br />

e B o d y P a r t . H e a d :<br />

w r i t e r . W r i t e L i n e (" н а г о л о в <strong>е</strong> в о л о с ы " ) ;<br />

b r e a k ;<br />

e B o d y P a r t . S h o u l d e r s :<br />

w r i t e r . W r i t e L i n e (" п л <strong>е</strong> ч и ш и р о к и <strong>е</strong> " ) ;<br />

• b r e a k ;<br />

c a s e B o d y P a r t . K n e e s :<br />

w r i t e r . W r i t e L i n e ( " к о л <strong>е</strong> н и у з л о в а т ы <strong>е</strong> " ) ;<br />

b r e a k ;<br />

c a s e B o d y P a r t . T o e s :<br />

w r i t e r . W r i t e L i n e ( "пальцы н о г м а л <strong>е</strong> н ь к и <strong>е</strong> " )(;<br />

b r e a k ;<br />

d e f a u l t :<br />

w r i t e r . W r i t e L i n e { "a п р о э т у ч а с т ь т <strong>е</strong> л а мы<br />

b r e a k ;<br />

Т<strong>е</strong>ло оп<strong>е</strong>ратора switch<br />

пр<strong>е</strong>дставля<strong>е</strong>т собой набор<br />

оп<strong>е</strong>раторов case, сравнивающих<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную,<br />

сл<strong>е</strong>дующую за ключ<strong>е</strong>вым<br />

словом switch, с пр<strong>е</strong>длага<strong>е</strong>мыми<br />

знач<strong>е</strong>ниями.<br />

За ключ<strong>е</strong>вым словом<br />

case сл<strong>е</strong>ду<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

для сравн<strong>е</strong>ния, дво<strong>е</strong>точи<strong>е</strong><br />

и набор оп<strong>е</strong>раторов,<br />

зав<strong>е</strong>ршающийся словом<br />

break;. Им<strong>е</strong>нно эти<br />

оп<strong>е</strong>раторы выполняются<br />

при совпад<strong>е</strong>нии знач<strong>е</strong>ний.<br />

н и ч <strong>е</strong> г о н <strong>е</strong> з н а <strong>е</strong> м " ) ;<br />

default-., кот о-<br />

дальш<strong>е</strong> > 423


застигнутый врасплох<br />

Чт<strong>е</strong>ни<strong>е</strong> U запись информации о картах В файл<br />

Зап и сь кол оды в ф ай л осущ <strong>е</strong>ствить л<strong>е</strong>гко — д о ст а т о ч н о цикла, зап исы ваю<br />

щ <strong>е</strong>го им я к аж дой карты. В о т м <strong>е</strong>тод, к о т о р ы й м о ж н о д обав и ть к объ <strong>е</strong>к ту<br />

D e ck;<br />

p u b l i c v o id W r it e C a r d s ( s t r in g file n a m e ) {<br />

u s in g (S trea m W riter w r i t e r = new S t r e a m W r it e r ( f ile n a m e ) ) {<br />

}<br />

f o r ( i n t i = 0 ; i < c a r d s . C o u n t; i++ ) {<br />

}<br />

w r i t e r .W r it e L i n e ( c a r d s [ i] .N am e);<br />

A как осущ <strong>е</strong>ствить ч т <strong>е</strong> н и <strong>е</strong> и з файла? И м <strong>е</strong> н н о зд <strong>е</strong>сь вам на п ом ощ ь п р и д <strong>е</strong>т<br />

о п <strong>е</strong> р а т о р switch.<br />

switch начина<strong>е</strong>т<br />

работу с указания знач<strong>е</strong>ния<br />

--------с которым буд<strong>е</strong>т осущТст:<br />

Suits suit; ,/ Дйннмы<br />

^ оп<strong>е</strong>ратор switch вт ь7а<br />

swxtch (suitstring) (<br />

м<strong>е</strong>тода, поэтами<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная suit сохран<strong>е</strong>на<br />

case "Spades'<br />

о строк<strong>е</strong>. ^<br />

suit = Suits.Spades;<br />

break;<br />

case "Clubs":<br />

suit = Suits .Clxibs;<br />

break;<br />

case "Hearts" ; —<br />

suit = Suits.Hearts;<br />

break;<br />

case "Diamonds";<br />

suit = Suits.Diamonds;<br />

break;<br />

default:<br />

Оп<strong>е</strong>ратор switch<br />

позволя<strong>е</strong>т сравнивать<br />

одно<br />

знач<strong>е</strong>ни<strong>е</strong> с набором<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных.<br />

. Каждая из строч<strong>е</strong>к case сравнива<strong>е</strong>т<br />

н<strong>е</strong>которо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

с п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, указанной в<br />

строчк<strong>е</strong> switch. В случа<strong>е</strong> совпад<strong>е</strong>ния<br />

вьтолнян?тся вс<strong>е</strong><br />

оп<strong>е</strong>раторы, располож<strong>е</strong>нны<strong>е</strong> до<br />

ключ<strong>е</strong>вого слова break.<br />

Строчка default стоит<br />

в самом конц<strong>е</strong>. Если знач<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной н<strong>е</strong> совпало<br />

ни с одним из пр<strong>е</strong>длож<strong>е</strong>нных<br />

вариантов, будут выполн<strong>е</strong>ны<br />

оп<strong>е</strong>раторы, стоящи<strong>е</strong> посл<strong>е</strong><br />

ключ<strong>е</strong>вого слова default.<br />

MessageBox.Show(suitstring + " н<strong>е</strong> подходит!");<br />

424 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Чт<strong>е</strong>ни<strong>е</strong> карт из файла<br />

О п <strong>е</strong> р а т о р sw itch позволя<strong>е</strong>т п о с т р о и т ь н о в ы й к о н с т р у к т о р для<br />

класса D e c k из пр<strong>е</strong>ды дущ <strong>е</strong>й главы . О н ч и та <strong>е</strong> т из ф айла и п р о в <strong>е</strong> р я ­<br />

<strong>е</strong> т каж дую с тр о ч к у на пр<strong>е</strong>дм <strong>е</strong>т сравн<strong>е</strong>ния с картам и. П р и удачном<br />

р<strong>е</strong>зультат<strong>е</strong> ср а в н <strong>е</strong> н и я карта попада<strong>е</strong>т в колоду.<br />

В о т к р а й н <strong>е</strong> п о л <strong>е</strong> зн ы й м <strong>е</strong>тод S p l i t О . О н разбива<strong>е</strong>т каж дую с тр о ­<br />

ку на массив бол<strong>е</strong><strong>е</strong> м <strong>е</strong>лких с тр о к , п<strong>е</strong>р<strong>е</strong>давая <strong>е</strong>й м ассив c h a r [ ]<br />

разд <strong>е</strong>лит<strong>е</strong>льн ы х знаков.<br />

p u b l i c D e c k ( s t r in g file n a m e ) {<br />

c a r d s = new L is t< C a r d > ();<br />

S tream R ead er r e a d e r = new S tr e a m R e a d e r ( f ile n a m e ) ;<br />

w h ile ( ! r e a d e r . EndOfStream ) {<br />

b o o l in v a lid C a r d = f a l s e ;<br />

s t r i n g n ex tC a r d = r e a d e r . R e a d L in e () ; U :<br />

s t r i n g [ ] c a r d P a r ts = n e x t C a r d .S p lit ( n e w c h a r [] { '<br />

V a lu e s v a lu e = V a lu e s .A c e ;<br />

s w it c h ( c a r d P a r t s [0 ]) {<br />

c a s e "Ace": v a lu e = V a lu e s .A c e ; b rea k ;<br />

}<br />

c a s e "Two": v a lu e = V a lu e s.T w o ; b rea k ;<br />

v a lu e = V a lu e s .T h r e e ; b r e a k ;<br />

c a s e "Three"<br />

c a s e "F our";<br />

v a lu e = V a lu e s .F o u r ; b rea k ;<br />

v a lu e = V a l u e s .F iv e ; b rea k ;<br />

c a s e " F iv e " :<br />

c a s e " S ix " : v a lu e = V a l u e s .S i x ; b rea k ;<br />

c a s e "Seven": v a lu e = V a l u e s . S ev en ; b r e a k ;<br />

c a s e " E ig h t" : v a lu e = V a l u e s . E i g h t ; b rea k ;<br />

c a s e "N ine": v a lu e = V a lu e s .N in e ; b rea k ;<br />

c a s e "Ten": v a lu e = V a lu e s .T e n ; b rea k ;<br />

c a s e Jack " : v a lu e = V a lu e s .J a c k ; b rea k ;<br />

c a s e Queen": v a lu e = V a l u e s . Queen; b rea k ;<br />

c a s e "King": v a lu e = V a lu e s .K in g ; b rea k ;<br />

d e f a u l t : in v a lid C a r d = t r u e ; b rea k ;<br />

S u i t s s u i t = S u i t s .C lu b s ;<br />

s w it c h ( c a r d P a r t s [2 ]) {<br />

c a s e "Spades": s u i t = S u i t s .S p a d e s ; b rea k ;<br />

c a s e "C lubs": s u i t = S u i t s .C lu b s ; b rea k ;<br />

c a s e " H ea rts" : s u i t = S u i t s .H e a r t s ; b rea k ;<br />

c a s e "Diamonds": s u i t = S u its .D ia m o n d s ; b reak ;<br />

d e f a u l t : in v a lid C a r d = t r u e ; b rea k ;<br />

}<br />

i f ( ! in v a lid C a r d ) {<br />

c a rd s.A d d (n e w C a r d ( s u it , v a l u e ) ) ;<br />

}<br />

Зд<strong>е</strong>сь строку nextCard<br />

разбивают при помощи проб<strong>е</strong>лов.<br />

В р<strong>е</strong>зультат<strong>е</strong> строковая<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная Six of Diamonds<br />

пр<strong>е</strong>враща<strong>е</strong>тся в массив {"Six”,<br />

"of’\ "Diamonds”}.<br />

J<br />

} ) ;<br />

Onejoamop switch<br />

сравнива<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

с п<strong>е</strong>рвым<br />

словом строки.<br />

В случа<strong>е</strong> совпад<strong>е</strong>ния<br />

знач<strong>е</strong>ни<strong>е</strong> при -<br />

сваива<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

value.<br />

с 6<br />

дальш<strong>е</strong> > 425


p.s. я наш<strong>е</strong>л свою лягуш ку<br />

Столько кода для чт<strong>е</strong>ния вс<strong>е</strong>го одной карты? Н<strong>е</strong><br />

многовато л и ? А что д<strong>е</strong>лать с объ<strong>е</strong>ктами с большим<br />

колич<strong>е</strong>ством знач<strong>е</strong>ний и пол<strong>е</strong>й? Н<strong>е</strong>уж<strong>е</strong>ли мн<strong>е</strong><br />

потр<strong>е</strong>бу<strong>е</strong>тся оп<strong>е</strong>ратор switch для каждого?<br />

У ~<br />

Е сть бол<strong>е</strong><strong>е</strong> простой спо со б сохран<strong>е</strong>ния объ<strong>е</strong>ктов<br />

в ф айл — с<strong>е</strong>риализация (serialization).<br />

В м <strong>е</strong>ст о скруп ул<strong>е</strong>зной за п и си в ф а й л каж дого п ол я и<br />

зн а ч <strong>е</strong>н и я м о ж н о со х р а н и т ь о б ъ <strong>е</strong>к т с<strong>е</strong>р и а л и за ц и <strong>е</strong>й <strong>е</strong>го<br />

в п оток . О б ъ <strong>е</strong>к т п р и эт о м пр <strong>е</strong>в р ащ а<strong>е</strong>тся в н а б о р бай ­<br />

тов. О б р а т н ы й п р о ц <strong>е</strong> сс назы ва<strong>е</strong>тся д<strong>е</strong>с<strong>е</strong>р и а л и за ц и <strong>е</strong> й , то<br />

<strong>е</strong>сть вы в о ссо зд а <strong>е</strong>т <strong>е</strong> о б ъ <strong>е</strong>к т и з п оток а байтов.<br />

З а т т и т на будущ<strong>е</strong><strong>е</strong>, ч т о сущ<strong>е</strong>ству<strong>е</strong>т<br />

м<strong>е</strong>тод Bnum.ParseQ (с ним вы познакомит<strong>е</strong>сь<br />

в глав<strong>е</strong> 1 4 ). который пр<strong>е</strong>образу<strong>е</strong>т<br />

строку Spades 8 эл<strong>е</strong>м<strong>е</strong>нт п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния<br />

Suits.Spades. Впроч<strong>е</strong>м, в рассматрива<strong>е</strong>мом<br />

случа<strong>е</strong> лучил<strong>е</strong> вс<strong>е</strong>го использовать с<strong>е</strong>риализацию,<br />

в ч<strong>е</strong>м вы скоро уб<strong>е</strong>дит<strong>е</strong>сь...<br />

426 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Ч то происходит с объ<strong>е</strong>ктом при с<strong>е</strong>риализации?<br />

П р о ц <strong>е</strong> с с к о п и р о в а н и я объ<strong>е</strong>кта из кучи и п о м <strong>е</strong> щ <strong>е</strong> н и я в ф айл каж <strong>е</strong>тся та и н с тв <strong>е</strong> н ­<br />

ны м , на самом д<strong>е</strong>л<strong>е</strong> там вс<strong>е</strong> о ч <strong>е</strong> н ь п р о сто .<br />

О бъ <strong>е</strong>кт в куч<strong>е</strong> © С <strong>е</strong>риализованны й объ<strong>е</strong>кт<br />

Э кз<strong>е</strong>м пляр объ<strong>е</strong>кта им <strong>е</strong><strong>е</strong>т н<strong>е</strong>ко<strong>е</strong><br />

состояни<strong>е</strong>. О б ъ <strong>е</strong> кт п р и этом<br />

«зна<strong>е</strong>т» то л ько , ч т о д<strong>е</strong>ла<strong>е</strong>т экз<strong>е</strong>мпляр<br />

о д н о го класса о тл и ч н ы м<br />

о т д р у го го экз<strong>е</strong>м пляра э т о го ж <strong>е</strong><br />

класса.<br />

П р и с<strong>е</strong>риализа ц и и полностью<br />

сохраня<strong>е</strong>тся состояни<strong>е</strong> объ<strong>е</strong>кта,<br />

п о это м у ка ж д ы й экз<strong>е</strong>м пляр<br />

м о ж <strong>е</strong> т б ы ть возвращ <strong>е</strong>н в кучу.<br />

00100101 ^ ^с о х р а н <strong>е</strong> н ы в ^<br />

01000110<br />

_ I в м <strong>е</strong> с т <strong>е</strong> с а о п о л н и т <strong>е</strong> л Й о й<br />

д а л ь н <strong>е</strong> й ш <strong>е</strong> г о в о с с т а ­<br />

н о в л <strong>е</strong> н и я о б ъ <strong>е</strong> к т а ( н а п ш -<br />

file.dat<br />

О бъ <strong>е</strong>кт снова в куч<strong>е</strong><br />

И зат<strong>е</strong>м ...<br />

Зат<strong>е</strong>м, м о ж <strong>е</strong> т бы ть, ч<strong>е</strong>р<strong>е</strong>з м н о го д н <strong>е</strong> й и<br />

в д р у го й п р о гр ам м <strong>е</strong>, вы м ож <strong>е</strong>т<strong>е</strong> п р о в <strong>е</strong> ­<br />

с т и д<strong>е</strong>с<strong>е</strong>риализацию объ<strong>е</strong>кта. И с х о д ­<br />

н ы й класс буд<strong>е</strong>т восста новл<strong>е</strong>н из файла<br />

ровно в то ж <strong>е</strong> состояни<strong>е</strong>, в к о то р о м он<br />

бы л, со вс<strong>е</strong>м и <strong>е</strong>го п о л я м и и знач<strong>е</strong>ниям и.<br />

дальш<strong>е</strong> > 427


сохраняйт<strong>е</strong> основной объ<strong>е</strong>кт<br />

Ч то им<strong>е</strong>нно мы сохраня<strong>е</strong>м<br />

В ы уж <strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, ч т о объ<strong>е</strong>кт хранит и н ф о р м а ц и ю в полях. С о о тв <strong>е</strong> т­<br />

с тв <strong>е</strong> н н о п р и с<strong>е</strong> р и а л и за ц и и н у ж н о с о х р а н и т ь каж до<strong>е</strong> из пол<strong>е</strong>й.<br />

Ч <strong>е</strong> м сл о ж н <strong>е</strong> й , объ<strong>е</strong>кт, т<strong>е</strong>м слож н<strong>е</strong><strong>е</strong> <strong>е</strong>го с<strong>е</strong> риализация. К а к 37, та к и 70,<br />

вс<strong>е</strong>го л и ш ь б а й ты , зн ачи м ы <strong>е</strong> т и п ы , к о то р ы <strong>е</strong> м о ж н о записать в ф айл<br />

б<strong>е</strong>з и зм <strong>е</strong> н <strong>е</strong> н и й . А как б ы ть, <strong>е</strong>сли в состав<strong>е</strong> о б ъ <strong>е</strong>кта п р и сутств у<strong>е</strong>т ссылка^<br />

А п я ть ссы лок? А ч т о <strong>е</strong>сли э т и ссы л ки , в свою оч<strong>е</strong>р<strong>е</strong>дь, ссы лаю тся на<br />

д р уги <strong>е</strong> объ<strong>е</strong>кты ?<br />

П одум айт<strong>е</strong> об этом . К акая часть объ<strong>е</strong>кта явля<strong>е</strong>тся п о т<strong>е</strong> н ц и а л ь н о у н и ­<br />

кальной? П р<strong>е</strong>дставьт<strong>е</strong>, ч т о и м <strong>е</strong> н н о н у ж н о в о сста н о в и ть, ч т о б ы получ<br />

и т ь объ<strong>е</strong>кт, к о т о р ы й бы л со хран<strong>е</strong>н. Т ак и л и и н а ч <strong>е</strong> , н о вс<strong>е</strong> сод<strong>е</strong>рж им о<strong>е</strong><br />

к у ч и н у ж н о записы вать в файл.<br />

ИЛПРЯГИ<br />

м о з г и<br />

Каким образом сл<strong>е</strong>ду<strong>е</strong>т сохранить объ<strong>е</strong>кт Car, чтобы потом <strong>е</strong>го<br />

можно было восстановить в исходно<strong>е</strong> состояни<strong>е</strong>? Пр<strong>е</strong>дположим,<br />

что в автомобил<strong>е</strong> <strong>е</strong>дут три пассажира, он им<strong>е</strong><strong>е</strong>т тр<strong>е</strong>хлитровый<br />

двигат<strong>е</strong>ль и вс<strong>е</strong>с<strong>е</strong>зонны<strong>е</strong> шины... разв<strong>е</strong> вся эта информация —<br />

н<strong>е</strong> часть состояния объ<strong>е</strong>кта Car? И что с н<strong>е</strong>й д<strong>е</strong>лать?<br />

(UJuna)<br />

Объ<strong>е</strong>кт Engine<br />

явля<strong>е</strong>тся закрытым.<br />

Нужно ли<br />

<strong>е</strong>го сохранять?<br />

p assenger С6^ , g масілл«<br />

Э1ЛЛ.0<br />

a Ціл^о<br />

« о н » « “<br />

^<br />

К а ж д ы й и з о б ъ <strong>е</strong> к ­<br />

т о в п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и я<br />

P a s s e n g e r и м <strong>е</strong> <strong>е</strong> т<br />

с с ы л к и н а д р у г и <strong>е</strong><br />

о б ъ <strong>е</strong> к т ы . С л <strong>е</strong> д у <strong>е</strong> т<br />

л и и х с о х р а н я т ь ?<br />

■ ^ L is \*<br />

428 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

С<strong>е</strong>риализации подв<strong>е</strong>рга<strong>е</strong>тся н<strong>е</strong> только сам объ<strong>е</strong>кт...<br />

...но и объ <strong>е</strong>кты , н а к о т о р ы <strong>е</strong> о н ссы ла<strong>е</strong>тся, и даж <strong>е</strong> вс<strong>е</strong> объ <strong>е</strong>кты , н а к о т о р ы <strong>е</strong> ссы ­<br />

л а ю т с я эт и объ<strong>е</strong>кт ы и т. д. Н <strong>е</strong> волнуйт<strong>е</strong>сь, э т о звучит сл о ж н о , н о вся проц<strong>е</strong>ду- П о добны <strong>е</strong> г р и п п ы<br />

ра п р о и зв о д и т ся автом атич<strong>е</strong>ски. С # н ач и н а<strong>е</strong>т с объ<strong>е</strong>кта, к о т о р ы й вы х о т и т <strong>е</strong> с в я за н н ы х о б ъ <strong>е</strong> к т о в<br />

с<strong>е</strong>риали зовать, и см о тр и т н а <strong>е</strong>го пол я в пои ск ах связанн ы х объ<strong>е</strong>ктов. Н ай д я и н о гд а н а з ы в а ю т<br />

такой объ<strong>е</strong>кт, о н п о в т о р я <strong>е</strong>т ан ал огичную о п <strong>е</strong>р а ц и ю . Э т о п о зв о л я <strong>е</strong>т со х р а н и т ь « г р а ф а м и »<br />

всю нуж ную и н ф о р м а ц и ю .<br />

Пр» *“<br />

о б ъ <strong>е</strong> к т ы .<br />

Одним из пол<strong>е</strong>й<br />

объ<strong>е</strong>кта К<strong>е</strong>пп<strong>е</strong>!<br />

явля<strong>е</strong>тся колл<strong>е</strong>кция<br />

Ust, в которой<br />

сод<strong>е</strong>ржатся Ш<br />

объ<strong>е</strong>кта Vog (Собака).<br />

Ш такж<strong>е</strong><br />

тр<strong>е</strong>бу<strong>е</strong>тся с<strong>е</strong>риализовать.<br />

к<br />

q<br />

^<br />

оба объ<strong>е</strong>кта Dog им <strong>е</strong>­<br />

ют ссылки на объ<strong>е</strong>кт<br />

DoggylD (Ид<strong>е</strong>нтификатор<br />

собаки) и объ<strong>е</strong>кт<br />

Collar (Ош<strong>е</strong>йник).<br />

Они тож<strong>е</strong> будут<br />

подв<strong>е</strong>ргнуты с<strong>е</strong>риализации.<br />

^ ъ <strong>е</strong> к т О О ' ^<br />

II<br />

дальш<strong>е</strong> > 429


с<strong>е</strong>риализован для ваш<strong>е</strong>й защиты<br />

С<strong>е</strong>риализация позволя<strong>е</strong>т чи тать и записывать<br />

объ<strong>е</strong>кт ц<strong>е</strong>ликом<br />

в ф айлы м о ж н о записы вать н<strong>е</strong> то л ь к о с т р о ч к и т<strong>е</strong>кста. П роц<strong>е</strong>дур а с<strong>е</strong>р<br />

и а л и з а ц и и позволя<strong>е</strong>т ко п и р о в а т ь в ф айл ц<strong>е</strong>лы <strong>е</strong> о б ъ <strong>е</strong> кты и ч и та ть<br />

и х оттуда... а в<strong>е</strong>дь это вс<strong>е</strong>го н <strong>е</strong> ско л ь ко с тр о ч <strong>е</strong> к кода! Вам потр <strong>е</strong> б у<strong>е</strong> т­<br />

ся п р о в <strong>е</strong> с ти н<strong>е</strong>больш ую п о д го то в и т<strong>е</strong> л ь н у ю р аботу — доб авить стр о ч к у<br />

[ S e r i a l i z a b l e ] в в <strong>е</strong> р х н ю ю часть с<strong>е</strong>риализу<strong>е</strong>м ого класса. П осл <strong>е</strong> это ­<br />

го вс<strong>е</strong> буд<strong>е</strong>т го т о в о к записи.<br />

Объ<strong>е</strong>кт BinaryFormatter<br />

С <strong>е</strong>риализация любого объ<strong>е</strong>кта н а чи н а <strong>е</strong> тся с создания экз<strong>е</strong>м пляра объ<strong>е</strong>кта<br />

B in a r y F o r m a t t e r . Э то о ч <strong>е</strong> н ь п р о с то . Д о с та то ч н о добавить <strong>е</strong>щ<strong>е</strong><br />

о дну с тр о ку u s in g в в <strong>е</strong> р х н ю ю часть класса:<br />

Чт<strong>е</strong>ни<strong>е</strong> и запись<br />

объ<strong>е</strong>ктов в файл<br />

осущ<strong>е</strong>ствляются<br />

быстро. Просто<br />

с<strong>е</strong>риализуйт<strong>е</strong><br />

или дис<strong>е</strong>риализуйт<strong>е</strong><br />

обь<strong>е</strong>кт.<br />

using System.Runtime.Serialization.Formatters.Binary;<br />

• • •<br />

BinaryFormatter formatter = new BinaryFormatter();<br />

Осталось создать поток u приступить к чт<strong>е</strong>нию и записи объ<strong>е</strong>ктов М<strong>е</strong>тоЭ<br />

новы<strong>е</strong> ^ f созда<strong>е</strong>т<br />

М <strong>е</strong>тод S e r i a l i z e () объ<strong>е</strong>кта B in a r y F o r m a t t e r записы ва<strong>е</strong>т объ<strong>е</strong>кты мия откры-<br />

В поток.<br />

ЛЙ<br />

using (Stream output = File.Create(filenameString)) {<br />

formatter.Serialize(output, objectToSerialize);<br />

^ ^ М<strong>е</strong>тод SerializeQ 5epem<br />

' объ<strong>е</strong>кт и записыва<strong>е</strong>т <strong>е</strong>го<br />

Ч т о б ы п р о ч и т а т ь с<strong>е</strong> р и а л и зованны й объ<strong>е</strong>кт, и спользуй т<strong>е</strong> м <strong>е</strong>тод в поток. Вы избавл<strong>е</strong>ны от<br />

D e s e r i a l i z e {) объ<strong>е</strong>кта B in a r y F o r m a t t e r . О н возвращ а<strong>е</strong>т ссылку, т и п н<strong>е</strong>обходимости д<strong>е</strong>лать это<br />

к о т о р о й м о ж <strong>е</strong> т н<strong>е</strong> совпадать с п<strong>е</strong>р<strong>е</strong>м <strong>е</strong> н н о й , п р <strong>е</strong> д н а зн а ч <strong>е</strong> н н о й для к о п и - вручную!<br />

р о вания. В это м случа<strong>е</strong> и сп ользуй т<strong>е</strong> п р ив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>.<br />

using (Stream input = File.OpenRead(filenameString)) {<br />

SomeObj obj = (SomeObj)formatter.Deserialize(input);<br />

} ^<br />

( Используй м<strong>е</strong>тод PeserializeQ для чт<strong>е</strong>ния обь<strong>е</strong>к-<br />

V _ та из потока, н<strong>е</strong> забывайт<strong>е</strong> осущ<strong>е</strong>ствить прив<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

возвраща<strong>е</strong>мого знач<strong>е</strong>ния к типу чита<strong>е</strong>мого<br />

объ<strong>е</strong>кта.<br />

430 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

А трибут [Serializable]<br />

А т р и б у т о м назы ва<strong>е</strong>тся сп<strong>е</strong>циальны й т<strong>е</strong>г, добавля<strong>е</strong>м ы й в в<strong>е</strong>рхню ю часть классов. С помощ ью атрибутов<br />

в <strong>C#</strong> сохраняю тся м <strong>е</strong> т а д а н н ы <strong>е</strong> , то <strong>е</strong>сть и н ф о р м ац и я о том , как нужно исп ользовать код. Д о б а в и в атр и ­<br />

бут [ S e r i a l i z a b l e ] н а д о б ъ я в л <strong>е</strong> н и <strong>е</strong> м к л а с с а , вы п оказы ва<strong>е</strong>т<strong>е</strong>, что это т класс м ож но с<strong>е</strong>риализовать.<br />

П одобно<strong>е</strong> допустимо, скаж <strong>е</strong>м, для классов с полям и значим ы х ти п ов (напри м <strong>е</strong>р, i n t , d e c im a l или<br />

<strong>е</strong>питп). О тсутстви<strong>е</strong> этого атрибута, как и наличи<strong>е</strong> в класс<strong>е</strong> пол<strong>е</strong>й, с<strong>е</strong>риализац и я которы х н<strong>е</strong>возм ож на,<br />

п ри водят к сообщ <strong>е</strong>нию об ощ ибк<strong>е</strong>. Уб<strong>е</strong>дит<strong>е</strong>сь в этом сами...<br />

Создани<strong>е</strong> и с<strong>е</strong>риализация класса<br />

П ом н и т<strong>е</strong> класс Guy из главы 3? С <strong>е</strong>риализу<strong>е</strong>м <strong>Дж</strong>о, чтобы и н ф о р м ац и я о коли ч<strong>е</strong>ств<strong>е</strong> <strong>е</strong>го<br />

наличности осталась в ф айл<strong>е</strong>.<br />

[ S e r i a l i z a b l e ]<br />

c l a s s Guy<br />

в в<strong>е</strong>рхн<strong>е</strong>й части л ю ­<br />

бого файла класса, кот орый Вы собира<strong>е</strong>т <strong>е</strong>сь с<strong>е</strong>риализовать.<br />

Э тот код с<strong>е</strong>риализу<strong>е</strong>т класс в ф ай л G uy_f i l e . d a t, а такж <strong>е</strong> добавля<strong>е</strong>т кн опки Save Jo e<br />

(С охранить <strong>Дж</strong>о) и L oad Jo e (Загрузить Д ж о):<br />

u s in g S y ste m .lO ;<br />

u s in g S y s te m .R u n tim e . S e r i a l i z a t i o n . F o r m a t t e r s . B in a r y ;<br />

p r i v a t e v o id s a v e J o e _ C l ic k ( o b j e c t s e n d e r , E v en tA rg s e)<br />

u s in g (Stream o u tp u t = F i l e . C r e a t e ( " G u y _ F ile . d a t " )) {<br />

}<br />

B in a r y F o r m a tte r f o r m a t t e r = new B in a r y F o r m a tte r ( );<br />

f o r m a t t e r .S e r i a l i z e ( o u t p u t , j o e ) ;<br />

}<br />

p r i v a t e v o i d l o a d J o e _ C l ic k ( o b j e c t se n d e r , E ven tA rgs e)<br />

{<br />

u s in g (Stream in p u t = F ile .O p e n R e a d (" G u y _ F ile .d a t" ))<br />

B in a r y F o r m a tte r f o r m a t t e r = new B in a r y F o r m a tte r ( );<br />

j o e = ( G u y ) f o r m a t t e r .D e s e r i a l i z e ( i n p u t ) ;<br />

Эти дв<strong>е</strong> строки using<br />

обязат<strong>е</strong>льно должны<br />

быть. П<strong>е</strong>рвая указыва<strong>е</strong>т<br />

пространство им<strong>е</strong>н,<br />

в котором происходят<br />

оп<strong>е</strong>рации ввода и вывода,<br />

вторая д<strong>е</strong>ла<strong>е</strong>т<br />

допустимой проц<strong>е</strong>дуру<br />

с<strong>е</strong>риализации.<br />

Fun w ith Jo e a n d 8 o b<br />

Joe has S »<br />

B ebhasSlffl}<br />

îh e b a r* has $100<br />

(3»в$№<br />

to Jae<br />

Receive<br />

}<br />

U pdateForm O ;<br />

Joetfïes<br />

$10 to В*<br />

Bob gives<br />

$5!o Jo e<br />

О<br />

}<br />

Запуск и т<strong>е</strong>стировани<strong>е</strong> програллмы<br />

Если Д ж о в р<strong>е</strong>зультат<strong>е</strong> обм <strong>е</strong>нны х о п <strong>е</strong>р ац и и с Бобом получил<br />

2 0 0 долларов, вряд ли он захоч<strong>е</strong>т п о т<strong>е</strong>р ять их п ри вы ход<strong>е</strong> из<br />

програм м ы . Т<strong>е</strong>п<strong>е</strong>рь Д ж о м ож <strong>е</strong>т сохран и ть свои кап италы в ф айл<br />

и восстан овить их в лю бой мом<strong>е</strong>нт.<br />

load Joe<br />

дальш<strong>е</strong> ► 431


с<strong>е</strong>риализация колоды карт<br />

С<strong>е</strong>риализу<strong>е</strong>м и д<strong>е</strong>с<strong>е</strong>риализу<strong>е</strong>м колоду карт<br />

Д авайт<strong>е</strong> <strong>е</strong>щ <strong>е</strong> р аз запиш <strong>е</strong>м в ф айл колоду карт. Б лагодаря с<strong>е</strong>р<br />

и ализац и и эта задача зн ачит<strong>е</strong>льн о упростилась. Вам нужно<br />

вс<strong>е</strong>го лиш ь создать п оток и записать в н<strong>е</strong>го объ<strong>е</strong>кты .<br />

О Создани<strong>е</strong> нового про<strong>е</strong>кта<br />

Щ <strong>е</strong>лкнит<strong>е</strong> п равой кн опкой мыш и на им <strong>е</strong>н и нового п р о <strong>е</strong>кта в окн<strong>е</strong> S olution Explorer, вы б<strong>е</strong>рит<strong>е</strong><br />

команду A d d /E x istin g Item и добавьт<strong>е</strong> классы C a rd и D eck (а такж <strong>е</strong> п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>н и я S u i t s<br />

и V a lu e s и и н т<strong>е</strong>рф <strong>е</strong>й сы C a rd C o m p a re r_ b y S u it и C a rd C o m p a re r_ b y V a lu e ), ко то р ы <strong>е</strong> вы<br />

использовали в глав<strong>е</strong> 8. Вам такж <strong>е</strong> потр<strong>е</strong>бую тся два класса, сравниваю щ их карты . Н <strong>е</strong> забудьт<strong>е</strong><br />

отр<strong>е</strong>дакти ровать строку n a m e s p a c e , посл<strong>е</strong> того как вс<strong>е</strong> ф ай лы будут скоп ированы в новы й<br />

про<strong>е</strong>кт.<br />

© Добавл<strong>е</strong>ни<strong>е</strong> атрибута<br />

Д обавьт<strong>е</strong> атрибут [ S e r i a l i z a b l e ] к обоим классам, скопированы<br />

м в про<strong>е</strong>кт. , э т о г о с<strong>е</strong>риализация<br />

^ ___ У н<strong>е</strong>возможна.<br />

О Добавл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тодов к дюрм<strong>е</strong><br />

М <strong>е</strong>тод R andom D eck случайны м образом созда<strong>е</strong>т колоду карт, а<br />

м<strong>е</strong>тод D e a lC a r d s разда<strong>е</strong>т их и вы водит р<strong>е</strong>зультат на консоль.<br />

Random random = new Random( );<br />

p r i v a t e D eck Random Deck(i n t number) {<br />

С о з д а <strong>е</strong> т с я п у с т а я к о м -<br />

д а , в к о т о р у ю с л у ч а й н ы м<br />

о б р а з о м д о Ш л я ь о т с я<br />

D eck myDeck = new D eck (new C ard[] { })<br />

к а р т ы и з к л а с с а С а г а , ^<br />

f o r ( i n t i = 0 ; i < number; i++ )<br />

с о з д а н н о го в п р <strong>е</strong> д ы д у щ <strong>е</strong> й<br />

{ глав<strong>е</strong>.<br />

m yDeck.A dd(new Card(<br />

}<br />

}<br />

r e t u r n myDeck;<br />

( S u it s ) r a n d o m .N e x t (4 ) ,<br />

(V a lu e s )r a n d o m .N e x t(1 , 1 4 ) ) ) ;<br />

p r i v a t e v o i d D ea lC a rd s(D ec k d eck T o D ea l, s t r i n g t i t l e ) {<br />

C o n s o l e . W r i t e L i n e ( t i t l e ) ;<br />

w h ile (d eck T o D ea l.C o u n t > 0 )<br />

{<br />

Card n ex tC a rd = d e c k T o D e a l.D e a l(0)<br />

C o n s o le .W r ite L in e (n e x tC a r d .N a m e );<br />

}<br />

C o n s o le .W r it e L in e (<br />

')<br />

^^^^одыи e^TdZ<br />

^У льт ат на консоль.<br />

432 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Пр<strong>е</strong>дварит<strong>е</strong>льная подготовка зако н ч<strong>е</strong>на... с<strong>е</strong>риализу<strong>е</strong>м колоду<br />

Д обавьт<strong>е</strong> к н о п к и , уп р а вляю щ и <strong>е</strong> записью и ч т<strong>е</strong> н и <strong>е</strong> м колод ы . С в<strong>е</strong> ряйт<strong>е</strong> сь<br />

3 один поток<br />

можно с<strong>е</strong>риализовать<br />

н<strong>е</strong>сколь<br />

ко объ<strong>е</strong>ктоо.<br />

с р<strong>е</strong>зультатам и на к о н с о л и . К олода, к о то р у ю вы записы ва<strong>е</strong>т<strong>е</strong> в ф айл,<br />

д о л ж н а совпадать с ко л о д о й , к о то р у ю вы чи та<strong>е</strong>т<strong>е</strong> .<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t sender, E v e n t A r g s a) {<br />

}<br />

D e c k d e c k T o W r i t e = R a n d o m D e c k (5);<br />

u s i n g (Stream o u t p u t = F i l e .C r e a t e (" D e c k l .<br />

B i n a r y F o r m a t t e r bf = n e w B i n a r y F o r m a t t e r ();<br />

b f . S e r i a l i z e ( o u t p u t , d e c k T o W r i t e ) ;<br />

}<br />

D e a l C a r d s ( d e c k T o W r i t e , "Что б ы л о з а п и с а н о в ф а й л " );<br />

p r i v a t e v o i d b u t t o n 2 _ C l i c k ( o b j e c t sender, E v e n t A r g s e) ■<br />

}<br />

u s i n g (Stream input = F i l e . O p e n R e a d ( " D e c k l . d a t " )) {<br />

B i n a r y F o r m a t t e r bf = n e w B i n a r y F o r m a t t e r ();<br />

D e c k d e c k F r o m F i l e = (D e c k ) b f . D e s e r i a l i z e ( i n p u t ) ;<br />

D e a l C a r d s ( d e c k F r o m F i l e T T ^ T O бьіло п р о ч и т а н о и з файла");<br />

}<br />

С<strong>е</strong>риализация набора колод<br />

П осл <strong>е</strong> о т к р ы т и я п о то к а в н <strong>е</strong> го м о ж н о записы вать п р о и звольн о <strong>е</strong> ко л и ч <strong>е</strong> ­<br />

ство и н ф о р м а ц и и . П о э то м у добавим дв<strong>е</strong> к н о п к и , п о зволяю щ и <strong>е</strong> со хр а ­<br />

н я ть в ф айл п р о и звольн о <strong>е</strong> колич<strong>е</strong>ств о колод.<br />

p r i v a t e v o i d b u t t o n 3 _ C l i c k ( o b j e c t sender, E v e n t A r g s e) {<br />

}<br />

u s i n g (Stream o u t p u t = F i l e .C r e a t e (" D e c k 2 .d a t " )) {<br />

}<br />

B i n a r y F o r m a t t e r bf = n e w B i n a r y F o r m a t t e r ();<br />

for (int i = 1; i


вн<strong>е</strong>шний вид символов<br />

Мн<strong>е</strong> н<strong>е</strong> нравится, что когда я открываю срайл, в который<br />

был записан объ<strong>е</strong>кт, я вижу какой-то мусор. Посл<strong>е</strong> записи<br />

колоды в вид<strong>е</strong> набора строк я открывала файл в прилож<strong>е</strong>нии<br />

Блокнот и спокойно <strong>е</strong>го читала. Мн<strong>е</strong> казалось, что в С # я должна<br />

— I б<strong>е</strong>з пробл<strong>е</strong>м понимать вс<strong>е</strong>, что д<strong>е</strong>лаю.<br />

С <strong>е</strong>риализованны <strong>е</strong> объ<strong>е</strong>кты записы ваю тся в двоичном<br />

ф ормат<strong>е</strong>.<br />

О н и к о м п а к тн ы . П о э то м у вы м ож <strong>е</strong>т<strong>е</strong> расп ознать с тр о к и , о тк р ы в<br />

ф айл с с<strong>е</strong> р и а л изованны м объ<strong>е</strong>ктом : в<strong>е</strong>дь наибол<strong>е</strong><strong>е</strong> к о м п а к тн ы й<br />

сп о со б и х записи в ф айл — и м <strong>е</strong> н н о в вид<strong>е</strong> стр о к. Н о писа ть в таком<br />

вид<strong>е</strong> чи сл а н<strong>е</strong> им <strong>е</strong><strong>е</strong>т смысла. Л ю б о <strong>е</strong> ч и сл о т и п а i n t м о ж н о<br />

с о х р а н и т ь в ч <strong>е</strong> т ы р <strong>е</strong> х байтах. П о э то м у б ы л о бы стр а н н о хр а н и т ь ,<br />

к прим <strong>е</strong>ру, ч и сло 49 369 144 ка к 8-сим вольную строку, удобную<br />

для ч т <strong>е</strong> н и я . Э то бы ла бы пустая тр а та м<strong>е</strong>ста!<br />

с Д <strong>е</strong> н о й<br />

Для пр<strong>е</strong>дставл<strong>е</strong>ния символов или строк в вид<strong>е</strong> байтов в .NET использу<strong>е</strong>тся Юникод.<br />

К счастью, в Windows им<strong>е</strong><strong>е</strong>тся инструм<strong>е</strong>нт, позволяющий понять принцип работы Юникода. Откройт<strong>е</strong><br />

прилож<strong>е</strong>ни<strong>е</strong> Character Мар (выб<strong>е</strong>рит<strong>е</strong> в м<strong>е</strong>ню Start команду Run. вв<strong>е</strong>дит<strong>е</strong> «charmap.exe» и щ<strong>е</strong>лкнит<strong>е</strong> на<br />

кнопк<strong>е</strong> ОК).<br />

П р и взгляд<strong>е</strong> на сим волы из р а зн ы х я зы ков ста н о в и тся п о н я т н о , ско л ь ко и н ф о р м а ц и и тр<strong>е</strong>бу<strong>е</strong>тся<br />

записать в ф айл для со х р а н <strong>е</strong> н и я т<strong>е</strong>кста. П о э то м у .N E T п р <strong>е</strong> о б р а з у <strong>е</strong> т вс<strong>е</strong> с т р о к и и сим волы в ф орм<br />

ат Ю н и к о д . Б <strong>е</strong>рутся д а н н ы <strong>е</strong> (н а п р и м <strong>е</strong> р , буква Н ) и п р <strong>е</strong>образую тся в б а й ты (ч и с л о 72). В<strong>е</strong>дь буквы ,<br />

ц и ф р ы , п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и я и д р уги <strong>е</strong> д а н н ы <strong>е</strong> х р а н я тс я в п а м я ти и м <strong>е</strong> н н о в вид<strong>е</strong> б айтов. У знать ж <strong>е</strong> соотв<strong>е</strong>т^<br />

ств и <strong>е</strong> м<strong>е</strong>жду числ а м и и сим волам и м о ж н о в Т аблиц<strong>е</strong> сим волов (C h a ra c te r М а р ).<br />

Выд<strong>е</strong>рит<strong>е</strong> в с п и ­<br />

ск<strong>е</strong> шрифтов Anal и<br />

прокрутит<strong>е</strong> вниз до<br />

<strong>е</strong>вр<strong>е</strong>йского алфавита.<br />

Щ<strong>е</strong>лчком выб<strong>е</strong>рит<strong>е</strong><br />

символ Shin.<br />

Посл<strong>е</strong> выбора символа в<br />

строк<strong>е</strong> состояния появится<br />

<strong>е</strong>го код. Д ля буквы<br />

Shin ~ это число OSE4<br />

о ш<strong>е</strong>стнадцат<strong>е</strong>ричной<br />

сист<strong>е</strong>м<strong>е</strong> счисл<strong>е</strong>ния.<br />

Д ля пр<strong>е</strong>образования<br />

получ<strong>е</strong>нного знач<strong>е</strong>ния<br />

в д<strong>е</strong>сятичную сист<strong>е</strong>му<br />

воспользуйт<strong>е</strong>сь калькулятором<br />

Windows в р<strong>е</strong>жим<strong>е</strong><br />

Scientific.<br />

в Chaiacttr Мар<br />

Pont!<br />

О feW<br />

ЙФ<br />

(h 4 j J b fb H j H j G G Ъ Ъ G e Ц Q q w<br />

д<br />

W V<br />

Л<br />

A<br />

Ч--<br />

V A. 6<br />

w Л, V 0<br />

0<br />

A Л A Л<br />

у V ' V •w'<br />

д 0 У w W 0 0<br />

■ Л, 1 0 t 9 H 3. я T<br />

IN Ü t 1 Э ■? □ n i Л о M n Э Y<br />

« '<br />

><br />

)i_ i .<br />

Л.<br />

ё w Л<br />

i p f S’ 1 i j ] iS i г Cl ih<br />

п<br />

т r £ a 1 у A % z , ♦<br />

J<br />

Hehiewletar<br />

р -<br />

____ ^<br />

Юникод — это<br />

индустриальный<br />

стандарт. Вы<br />

мож<strong>е</strong>т<strong>е</strong> пос<strong>е</strong>т<br />

ит ь сайт h ttp ://<br />

unicode.org/<br />

434 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

.NET использу<strong>е</strong>т Unicode для хран<strong>е</strong>ния симВолоб и т<strong>е</strong>кста<br />

Т и п ы , хр а н я щ и <strong>е</strong> т<strong>е</strong> к с т и сим волы , — s t r i n g и c h a r — в пам я ти х р а н я т<br />

и н ф о р м а ц и ю в Ю н и к о д <strong>е</strong> . П р и записи д а н н ы х в ф айл с о х р а н я ю тся сим-<br />

волы Ю н и к о д . С оздайт<strong>е</strong> н о в ы й п р о <strong>е</strong> кт, п о с тр о й т<strong>е</strong> ф орм у с тр <strong>е</strong> м я кноп-<br />

кам и, ч т о б ы п о см о тр <strong>е</strong> ть н а р аботу м <strong>е</strong>тодов F i l e . W r i t e A l l B y t e s {) и<br />

R e a d A l I B y t e s () и понять, как и м <strong>е</strong>н н о осущ <strong>е</strong>ствля<strong>е</strong>тся зап ись в ф айл. _ ^ ^ у Т ) . Р а Ж Н 0 Н и 0<br />

/ ^ ^ Ф<br />

^ Запиш <strong>е</strong>м в ф айл обычную строку и прочита<strong>е</strong>м <strong>е</strong><strong>е</strong>.<br />

В оспользуйт<strong>е</strong>сь м <strong>е</strong>тодом W r i t e A l l T e x t { ) , ч т о б ы заставить п <strong>е</strong> рвую к н о п к у записы вать<br />

с тр о к у «Eureka!» в ф айл «eureka.txt». Зат<strong>е</strong>м создайт<strong>е</strong> массив байто в e u r e k a B y t e s , п р о ч и ­<br />

та й т<strong>е</strong> в н <strong>е</strong> го из ф айла и вы в<strong>е</strong>дит<strong>е</strong> п о л у ч <strong>е</strong> н н ы й р<strong>е</strong>зультат:<br />

F i l e . W r it e A llT e x t ( " e u r e k a . t x t " , "E u reka!" );<br />

b y t e [ ] e u r e k a B y te s = F i l e .R e a d A l l B y t e s ( " e u r e k a .t x t " ) ;<br />

f o r e a c h (b y te b i n e u r e k a B y te s) ^ М<strong>е</strong>тод R e a d A llB y te s Q возвраща<strong>е</strong>т ^<br />

c o n s o l e w r i t e (" f 0 ) " b) ■ V сш лку на новш массив, с^<strong>е</strong>ржащии<br />

C o n s o l e . w r i t e ( 10} , ) , Saumbi, п р о ч и т а н н ы <strong>е</strong> и з ф а й л а .<br />

C o n s o le .W r ite L in e O ;<br />

Н а КО Н С О Л Ь буд<strong>е</strong>т вы в<strong>е</strong>д<strong>е</strong>но: 6 9 117 114 lO i 107 97 3 3 . Н о <strong>е</strong>сл и открыть файл в прилож<strong>е</strong>нии<br />

Simple Text Editor, вы уви ди т<strong>е</strong> строку «Eureka!»<br />

О П усть вторая кнопка отобража<strong>е</strong>т байты в ш <strong>е</strong>стнадцат<strong>е</strong>ричной сист<strong>е</strong>м <strong>е</strong>.<br />

Ч и сла в это й сист<strong>е</strong>м<strong>е</strong> показы ваю тся н<strong>е</strong> то л ько в п р и л о ж <strong>е</strong> н и и C haracter М ар, поэтом у им <strong>е</strong><strong>е</strong>т<br />

смысл научиться с н и м и работать. К од обработчика со б ы ти й для в то р о й к н о п к и долж <strong>е</strong>н о т­<br />

личаться м<strong>е</strong>тодом C o n s o l e . W r it e ( ) , для к о то р о го напиш ит<strong>е</strong>:<br />

гопчпТр W r it e ( " f 0 -x 2 ) " Ь) ■ с и с т <strong>е</strong> м <strong>е</strong> ы т о л ь з у к )т с я числа<br />

C o n s o le .w r it e ( I 0 .X 2 ) ' от о до я и буквы от А до F. Так 6 8 рябно 1 0 7 . ^<br />

В и т о г<strong>е</strong> м <strong>е</strong>то д W r i t e O буд<strong>е</strong>т вы водить п ар ам <strong>е</strong>тр О (п <strong>е</strong>рв ы й п о сл <strong>е</strong> в ы в оди м ой с т р о к и )Л<br />

в ви д<strong>е</strong> кода. П о эт о м у вы у в и ди т<strong>е</strong> с<strong>е</strong>м ь байтов: 45 75 72 65__6Ь 61 21^1—-------------------- ---------<br />

о А тр<strong>е</strong>тья кнопка должна выводить буквы <strong>е</strong>вр<strong>е</strong>йского алдювита<br />

В <strong>е</strong> р н и т<strong>е</strong> сь в Таблицу сим волов (C h a ra cte r М а р ) и дважды щ <strong>е</strong>лкнит<strong>е</strong> на сим вол<strong>е</strong> S hin, ч т о ­<br />

б ы добавить <strong>е</strong>го в пол<strong>е</strong>. П род<strong>е</strong>лайт<strong>е</strong> это для оста л ьн ы х сим волов в слов<strong>е</strong> «Shalom»: L am ed<br />

(U + 0 5 D C ), Vav (U +05D 5) и M e m (U-t-05DD). В код об р а б о тчика с о б ы ти й для тр <strong>е</strong> ть<strong>е</strong>й к н о п к и<br />

добавьт<strong>е</strong> ско п и р о в а н н ы <strong>е</strong> буквы и добавьт<strong>е</strong> парам <strong>е</strong>тр E n c o d i n g . U n ic o d e :<br />

F i l e .W r it e A l l T e x t ( " e u r e k a .tx t" , "Ш *?Ш" , E n c o d in g .U n ic o d e ) ;<br />

О б р а ти л и вним а н и <strong>е</strong> на обратный порядок букв посл<strong>е</strong> вставки? Д <strong>е</strong>ло в то м , ч т о <strong>е</strong> вр<strong>е</strong>йски <strong>е</strong><br />

слова ч и та ю тс я справа нал<strong>е</strong>во. З апустит<strong>е</strong> код и п о с м о тр и т<strong>е</strong> на п о л у ч <strong>е</strong> н н ы й р<strong>е</strong>зультат: f f<br />

f e <strong>е</strong>9 05 dc 05 d5 05 dd 0 5 . П <strong>е</strong> р в ы <strong>е</strong> два сим вола — «FF ЕЕ», Ч Т О означа<strong>е</strong>т с тр о ку из двухб<br />

а й то в ы х сим волов. О ста л ьны <strong>е</strong> б а й ты пр<strong>е</strong>дста вл яю т со б о й буквы <strong>е</strong> в р <strong>е</strong> й ского алф авита, -<br />

н о п <strong>е</strong> р <strong>е</strong> в<strong>е</strong>рнуты <strong>е</strong>, та к U +05E 9 буд<strong>е</strong>т показано как <strong>е</strong>9 05. Н о <strong>е</strong>сли о т к р ы т ь ф айл в ваш<strong>е</strong>м<br />

п р и л о ж <strong>е</strong> н и и S im p le T ext E d ito r, вс<strong>е</strong> буд<strong>е</strong>т вы гляд<strong>е</strong>ть п р а в и л ьн о !<br />

дальш<strong>е</strong> ► 435


изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> порядка байтов<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong> данных Внутри массиВа байтоВ<br />

Так как вс<strong>е</strong> д а н н ы <strong>е</strong> в и т о г<strong>е</strong> п <strong>е</strong>р <strong>е</strong>к о д и р у ю тся в б а й т ы ,<br />

ф ай л и м <strong>е</strong><strong>е</strong>т см ы сл п р <strong>е</strong>дставить в ви д<strong>е</strong> б о л ь ш о г о м а с с и ­<br />

в а б а й т о в . С п о со б ы ч т<strong>е</strong>н и я таких м асси вов и за п и си в<br />

н и х вы уж <strong>е</strong> зн а<strong>е</strong>т<strong>е</strong>.<br />

Этот код созда<strong>е</strong>т массив<br />

байтов с названи<strong>е</strong>м<br />

П рив<strong>е</strong>т ст ви<strong>е</strong>», открыва<strong>е</strong>т<br />

входящий поток и<br />

данны<strong>е</strong> в байты массива о<br />

нул<strong>е</strong>вого до ш<strong>е</strong>стого.<br />

Ы<strong>е</strong>\\о\и<br />

byte[] greeting;<br />

greeting = File.ReadAllBytes(filename<br />

Это статич<strong>е</strong>ский<br />

м<strong>е</strong>тод для объ<strong>е</strong>кта<br />

Arraцs, м<strong>е</strong>няюищи<br />

порядок байтов н й<br />

обратный. Зд<strong>е</strong>сь он<br />

использу<strong>е</strong>тся, чтобы<br />

показать, как вн<strong>е</strong>с<strong>е</strong>нны<strong>е</strong><br />

в массив байтоб<br />

изм<strong>е</strong>н<strong>е</strong>ния б л м я ю т Нй<br />

вид чита<strong>е</strong>мой из


Класс BinaryVi/riter<br />

Д а н н ы <strong>е</strong> р а з л и ч н ы х т и п о в п<strong>е</strong>р<strong>е</strong>д за п и сью в ф айл можно п р <strong>е</strong> о б р а зо вы вать в массивы<br />

б а й то в , н о э то кр а й н <strong>е</strong> р у ти н н а я работа. П о э то м у в .N E T п о я в и л ся класс<br />

BinaryWriter, автоматич<strong>е</strong>ски пр<strong>е</strong>образующий данны<strong>е</strong> и за п и сы в а ю щ и й и х<br />

чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Одь<strong>е</strong>кт Stream W riter<br />

' так ж<strong>е</strong> зашифровыва<strong>е</strong>т<br />

оанны<strong>е</strong>,, но он работа<strong>е</strong>т<br />

только с т<strong>е</strong>кстом.<br />

в ф айл. Вам н у ж н о то л ь к о создать о б ъ <strong>е</strong> кт F i l e S t r e a m и п<strong>е</strong>р<strong>е</strong>дать <strong>е</strong> го к о н стр ук- ф ^ .<br />

то р у класса B i n a r y W r i t e r . П осл <strong>е</strong> ч <strong>е</strong> го вы зы ва<strong>е</strong>тся м <strong>е</strong>тод за п и си д а н н ы х. Добавим<br />

в прогрп р о а м м у<br />

<strong>е</strong>щ<strong>е</strong> одну кнопку, ч т о б ы п о с м о тр <strong>е</strong> ть на спосо б р а б о ты с классом X<br />

B i n a r y W r i t e r ( ) .<br />

О С оздайт<strong>е</strong> ко н сольно<strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> и у ка ж и т<strong>е</strong> д а н н ы <strong>е</strong> для за п и си в ф айл.<br />

J<br />

int i n t V a l u e = 48769414;<br />

S t r i n g s t r i n g V a l u e = "Hello!";<br />

byte[] b y t e A r r a y = { 47, 129, 0, 116 };<br />

f l o a t f l o a t V a l u e = 491.695F;<br />

c h a r c h a r V a l u e = 'E ';<br />

д а ^ ^ ^ с о з а ^ <strong>е</strong> т новый файл,<br />

даж<strong>е</strong> при наличии уж<strong>е</strong> суш,<strong>е</strong>ст6ующ<strong>е</strong>го.<br />

открыва<strong>е</strong>т<br />

им<strong>е</strong>ющийся файл и записыва<strong>е</strong>т новию<br />

информацию пов<strong>е</strong>рх старой.<br />

© П р и п о м ощ и м<strong>е</strong>тода F i l e . C r e a te () о ткр о <strong>е</strong> м н о в ы й п о то к: ^<br />

u s i n g ( F i l e S t r e a m o u t p u t = F i l e .C r e a t e (" b i n a r y d a t a . d a t " ))<br />

О<br />

u s i n g ( B i n a r y W r i t e r w r i t e r = n e w B i n a r y W r i t e r ( o u t p u t ) ) {<br />

П р и каж дом вы зов<strong>е</strong> м <strong>е</strong>тода W r i t e О в к о н <strong>е</strong> ц ф айла, в к о т о р ы й осущ <strong>е</strong>ствля<strong>е</strong>тся<br />

запись д а н н ы х, буд<strong>е</strong>т добавляться байт.<br />

w r i t e r .Write (intvalue) ;<br />

1


см<strong>е</strong>сь байтов<br />

Знач<strong>е</strong>ния типов float и int занимают<br />

по 4 бита, в то вр<strong>е</strong>мя как типы long<br />

и double три<strong>е</strong>буют по 8 байт.<br />

^ ^ q z о& ± 8 ^ в с в с Z 1 Z f 8 1 0 0 7 4 fe d s f s 4 3 4 -s - ZO b y t e s<br />

-J I____ ______ _ — »I--------- j n - Z<br />

in tV a lu e ~ Ш ш д \/ а (и <strong>е</strong> b y t e A r r a y<br />

V<br />

c k a r V a iu e<br />

V<br />

^озьми в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

П<strong>е</strong>рвый байт это длина строки.<br />

riocMompemt? соотв<strong>е</strong>тстви<strong>е</strong> ш<br />

мож<strong>е</strong>т<strong>е</strong> в Таблии,<strong>е</strong> символов. Слово<br />

«Hello!» начина<strong>е</strong>тся с U+0048<br />

и заканчива<strong>е</strong>тся U+OOZ1.<br />

Воспользовавшись Воспользовйвшиа:> кл кальку л ь кулля-<br />

я<br />

тором Windows для пр<strong>е</strong>ооразования<br />

знач<strong>е</strong>ний из ш <strong>е</strong>ст ­<br />

надцат<strong>е</strong>ричной сист<strong>е</strong>мы в<br />

д<strong>е</strong>сятичную, вы обнаружит<strong>е</strong><br />

числа, составляющи<strong>е</strong> массив.<br />

I I . 11 I >. ^ ^ ^ ^ ...ß л . , .,^4 I I и н и и -2 t л ^ Z' 1ЛЛ —<br />

Класс BinaryReader<br />

^П <strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная типа char<br />

'Е’ занима<strong>е</strong>т вс<strong>е</strong>го<br />

один байт, он соотв<strong>е</strong>тству<strong>е</strong>т<br />

символа<br />

U+004S.<br />

К ласс B in a r y R e a d e r р а б ота<strong>е</strong>т а н а л о ги ч н о классу B i n a r y W r i t e r .<br />

И<strong>е</strong> в<strong>е</strong>рьт<strong>е</strong> нам на слово. Зам<strong>е</strong>нит<strong>е</strong><br />

строку для чт<strong>е</strong>ния<br />

В ы созда<strong>е</strong>т<strong>е</strong> п о т о к , п р и со <strong>е</strong> д и н я <strong>е</strong> т<strong>е</strong> к н<strong>е</strong>м у о б ъ <strong>е</strong> кт B in a r y R e a d e r и<br />

вы зы ва<strong>е</strong>т<strong>е</strong> <strong>е</strong> го м <strong>е</strong>тоды . Н о п р о гр а м м а для ч т <strong>е</strong> н и я н <strong>е</strong> з н а <strong>е</strong> т , ч т о з а типа float вызовом м <strong>е</strong>т о­<br />

д а н н ы <strong>е</strong> с о д <strong>е</strong> р ж а т с я в ф а й л <strong>е</strong> ! И н <strong>е</strong> м о ж <strong>е</strong> т узнать. З н а ч <strong>е</strong> н и <strong>е</strong> т и п а да Readlnt3Z(). (Вам потр<strong>е</strong>бу<strong>е</strong>тся<br />

зам<strong>е</strong>нить тип<br />

flo a t 4 9 1 . 695F пр<strong>е</strong>образовалось в d8 f 5 43 4 5. Н о э т и ж <strong>е</strong> б а й ты под- ,,FlnnVpZT"<br />

х о д я т к зн а ч <strong>е</strong> н и ю т и п а i n t - 1 140 185 334. П о э то м у сл<strong>е</strong>ду<strong>е</strong>т в яв-увидит<strong>е</strong>, чт Т чит а<strong>е</strong>^^я<br />

из<br />

но м вид<strong>е</strong> указы вать т и п ч и та <strong>е</strong> м о го з н а ч<strong>е</strong>ния. Д обавьт<strong>е</strong> к ф орм <strong>е</strong> <strong>е</strong>щ<strong>е</strong> файла.<br />

одну к н о п к у и займ <strong>е</strong>мся ч т<strong>е</strong> н и <strong>е</strong> м то л ь к о ч т о за п и с а н н ы х д а н н ы х:<br />

О Н а ч н <strong>е</strong> м с задания о б ъ <strong>е</strong> кто в F ile S t r e a m и B in a r y R e a d e r :<br />

u s in g (F ile S t r e a m in p u t = F i l e . O penR ead( " b in a r y d a t a . d a t'<br />

u s in g (B in a ry R ea d er r e a d e r = new B in a r y R e a d e r ( in p u t ) ) {<br />

) )<br />

© У ка ж и т<strong>е</strong> т и п д а н н ы х , к о т о р ы й буд<strong>е</strong>т возвращ ать ка ж д ы й из м <strong>е</strong>тодов объ<strong>е</strong>кта<br />

B in a r y R e a d e r .<br />

©<br />

i n t in tR e a d = r e a d e r .Readlnt32();<br />

s t r i n g s t r in g R e a d = reader.ReadStringO;<br />

b y t e [ ] b y teA rra y R ea d = r e a d e r .R e a d B y te s (4) ;<br />

) ЙЗ которых возвраща<strong>е</strong>т данны<strong>е</strong><br />

f l o a t f lo a t R e a d = r e a d e r .ReadSingle () ; ^ ^ a d B y te sQ ^ M ^ t)/^ '^ ’’<br />

c h a r charR ead = r e a d e r .ReadChar();<br />

Щ<strong>е</strong>т парам<strong>е</strong>тр, сообщающий<br />

В ыв<strong>е</strong>д<strong>е</strong>м р<strong>е</strong>зультат ч т <strong>е</strong> н и я д а н н ы х на консоль:<br />

C o n s o l e .W r i t e ( " i n t : {о} s t r i n g : { l }<br />

f o r e a c h (b y te b i n byteA rra y R ea d )<br />

C o n s o le .W r it e ( " { o } ", b ) ;<br />

C o n s o le .W r it e ( " f l o a t : { 0 } c h a r : { l }<br />

}<br />

C o n so le.R e a d K ey O ;<br />

байтов тр<strong>е</strong>бу<strong>е</strong>тся прочитать.<br />

b y t e s : ", in tR e a d , S tr in g R e a d )<br />

f lo a t R e a d ,<br />

charR ead)<br />

В о т ка к о н буд<strong>е</strong>т вы гляд<strong>е</strong>ть:<br />

i n t : 48 7 6 9 4 1 4 s t r i n g : H e llo ! b y t e s : 47 129 0 116 f l o a t : 4 9 1 .6 9 5 c h a r: E<br />

438 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Чт<strong>е</strong>ни<strong>е</strong> U запись с<strong>е</strong>риализованных файлов Вручную<br />

О т к р ы т ы <strong>е</strong> в п р и л о ж <strong>е</strong> н и и Б л о к н о т с<strong>е</strong>риализо ванны <strong>е</strong> ф айлы вы глядят н<strong>е</strong> о ч <strong>е</strong> н ь т I<br />

красиво. В с<strong>е</strong> записанны <strong>е</strong> вам и ф айлы нахо д я тся в папк<strong>е</strong> Ы п \О <strong>е</strong> Ь и д . Д авайт<strong>е</strong> у 1 1 Р а Ж Н Р Н и 0 1<br />

п о см о то и м на д о п о л н и т<strong>е</strong> л ь н ы <strong>е</strong> п р и <strong>е</strong> м ы р а б о ты с н и м и . 1<br />

Г<br />

С<strong>е</strong>риализу<strong>е</strong>м два объ<strong>е</strong>кта C ard в различны<strong>е</strong> ф айлы<br />

И спользуйт<strong>е</strong> н а п и с а н н ы й ран<strong>е</strong><strong>е</strong> код, ч т о б ы с<strong>е</strong>риализовать тройку кр<strong>е</strong>ст<strong>е</strong>й в ф айл t h r e e - с .<br />

d a t , а ш<strong>е</strong>ст<strong>е</strong>рку ч<strong>е</strong>рв<strong>е</strong>й — в ф айл s i x - h . d a t. У б<strong>е</strong>дит<strong>е</strong>сь, ч т о оба ф айла находятся в о д н о й<br />

папк<strong>е</strong>, и м <strong>е</strong> ю т о д и н а к о в ы й разм <strong>е</strong>р и о т к р о й т <strong>е</strong> и х в Б л о кн о т<strong>е</strong> :<br />

ß ф а й л <strong>е</strong><br />

в с т р <strong>е</strong> ч а ю т с я<br />

З Н Й К О М Ь іЄ СЛОбЙ,<br />

но по больш<strong>е</strong>-и<br />

т ст и он н<strong>е</strong>чіхтй<strong>е</strong>М-<br />

^<br />

1 three-C - Notepad<br />

File Edit F o rm at View H elp<br />

W yy ~ ^ PSerialize a deck of cards, version=l.0.0.0.<br />

Cu1ture=neutral, PubTicKeyToken=nu11 serialize_a_deck_of_cards.Cardi<br />

i < S u i t > k _ B a c k i n g F i e l d r < v a l u e > k _ B a c k i n g F i e 1 d - 5 e r i a l 1 z e _ a _ d e c k _ o f _ c a r d s . S u i t S T<br />

s e r i a T i z e _ a _ d e c k _ o f _ c a r d s . v a l u e s ,<br />

| y y y y t 5 e r ia l - i z e _ a _ d e c k _ o f _ c a r d s . s u i t s<br />

. v a l u e __ s- ‘u y^ iy s e r i a l l z e _ a _ d e c k _ o f _ c a r d s . v a l u e s . v a l u e — a, >• /<br />

О<br />

Ц и кл , сравниваюи^^й два двоичных ф айла<br />

П р и ч т <strong>е</strong> н и и б айтов из п о то ка м<strong>е</strong>тод R e a d B y t e () возвращ а<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> ти п а i n t . П ол<strong>е</strong><br />

L e n g t h п о то ка позволя<strong>е</strong>т уб<strong>е</strong>диться, ч то ф айл п р о ч и та н полностью .<br />

b y t e [ ] f i r s t F i l e = F i l e .R e a d A l l B y t e s ( " t h r e e - с . d a t " );<br />

b y t e [ ] s e c o n d F ile = F i l e .R e a d A l l B y t e s ( " s i x - h .d a t " ) ;<br />

f o r ( i n t 1 = 0 ; i < f i r s t F i l e . L e n g t h ; i++)<br />

i f ( f i r s t F i l e [ i ] != s e c o n d F i l e [ i ] )<br />

C o n s o le .W r ite L in e (" B y te # { 0 } : { l } v e r s u s {2 }" ,<br />

i , f i r s t F i l e [ i ] , s e c o n d F i l e [ i ] );<br />

Т ак кй к эти файлы были проч<br />

м т й н и в разны<strong>е</strong> массивы, мы<br />

им<strong>е</strong><strong>е</strong>м возможность сравнить<br />

мХ побайтно. В данном случа<strong>е</strong><br />

в два разных файла были с<strong>е</strong>риализованы<br />

объ<strong>е</strong>кты одного<br />

класса, поэтому они должны<br />

быть практич<strong>е</strong>ски ид<strong>е</strong>нтичны.,<br />

но давайт<strong>е</strong> сйМи п 0СМ01^ и М ,<br />

НАСКОЛЬКО они совпадают.<br />

f<br />

i<br />

])уДын<strong>е</strong><br />

д к ш <strong>е</strong><br />

о с щ о р > о Ж Н ь 1 1<br />

Этот цикл сравнива<strong>е</strong>т п<strong>е</strong>рвы<strong>е</strong> байты из обоих<br />

файлов, потом вторы<strong>е</strong>, потом тр<strong>е</strong>тьи и т. д.<br />

Информация об обнаруж<strong>е</strong>нных различиях выводится<br />

на консоль.<br />

Запись в ф айл н<strong>е</strong> вс<strong>е</strong>гда осущ <strong>е</strong>ствля<strong>е</strong>тся<br />

с чистого листа!<br />

осторожны с м<strong>е</strong>тодом File.<br />

OpenWriteQ. Он н<strong>е</strong> удаля<strong>е</strong>т им<strong>е</strong>ющийся файл, а начина<strong>е</strong>т<br />

запись пов<strong>е</strong>рх уж<strong>е</strong> записанной информации. Поэтому мы<br />

пр<strong>е</strong>дпочли м<strong>е</strong>тод File.CreateQ, создаюи^ий новый файл.<br />

IJeJ^e^ej^H uixie с ш р а н и Щ ) U И ^ ^ о д о л ж и м !<br />

439


отпраздну<strong>е</strong>м наши различия<br />

Найдит<strong>е</strong> отличия и отр<strong>е</strong>дактируйт<strong>е</strong> файлы<br />

Н а п и с а н н ы й нам и ц и к л ч <strong>е</strong> т к о указы ва<strong>е</strong>т на р а зл и чи я м<strong>е</strong>жду<br />

двумя с<strong>е</strong> р и а л и зо ванны м и ф айлам и C ard. З а п и са н н ы <strong>е</strong> объ<strong>е</strong><br />

к ты р азл и чаю тся п о л я м и S u i t и V a lu e , со о тв <strong>е</strong> тств<strong>е</strong>нно,<br />

и м <strong>е</strong> н н о в этом будут различаться ф айлы . Н а й д я б а й ты , сод<strong>е</strong>рж<br />

ащ и<strong>е</strong> и н ф о р м а ц и ю о м асти и с та р ш и н ств <strong>е</strong> ка р ты , м ы<br />

см ож <strong>е</strong>м о т р <strong>е</strong> д а к т и р о в а т ь и х , п о л учив в и т о г<strong>е</strong> сов<strong>е</strong>рш <strong>е</strong> н н о<br />

н о в ую карту с н у ж н ы м и нам парам <strong>е</strong>трам и!<br />

Возможна с<strong>е</strong>риализация объ<strong>е</strong>к-<br />

^О в в формат XML<br />

О Рассмотрим выв<strong>е</strong>д<strong>е</strong>нны<strong>е</strong> на консоль р<strong>е</strong>зультаты<br />

О н и показы ваю т, ч<strong>е</strong>м р а зличаю тся ф айлы :<br />

B y te #322 : 1 v e r s u s 3<br />

B y te # 3 8 2 : 3 v e r s u s 6<br />

В <strong>е</strong> р н и т<strong>е</strong> сь к п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и ю S u i t s в пр<strong>е</strong>ды дущ <strong>е</strong>й глав<strong>е</strong>, и вы увид и т<strong>е</strong> , ч т о м асти C lu b со о т­<br />

в<strong>е</strong>тству<strong>е</strong>т зн ач<strong>е</strong>ни<strong>е</strong> 1, а м асти H e a rt - зн ач<strong>е</strong>ни<strong>е</strong> 3. Э то п <strong>е</strong> рво<strong>е</strong> различи<strong>е</strong>. В то р о <strong>е</strong> различи<strong>е</strong>,<br />

ка к л <strong>е</strong> гко догадаться, — с та р ш и н с тв о карт. Р азличном у ко л и ч <strong>е</strong> ств у б а й т такж <strong>е</strong> им <strong>е</strong><strong>е</strong>тся объя<br />

сн<strong>е</strong>ни<strong>е</strong>: о б ъ <strong>е</strong> кты м огл и н а хо д и ть ся в р а зны х п р о с тр а н с тв а х им <strong>е</strong>н, ч т о и зм <strong>е</strong>нило длину<br />

файла.<br />

Помнит<strong>е</strong>, каким образом информация<br />

о пространств<strong>е</strong> им<strong>е</strong>н<br />

ёкАюча<strong>е</strong>тся в с<strong>е</strong>ри^изованньТ<br />

пространства им<strong>е</strong>н<br />

различаются, разм<strong>е</strong>р байтов<br />

о сохран<strong>е</strong>нном файл<strong>е</strong> такж<strong>е</strong><br />

оуо<strong>е</strong>т отличаться.<br />

Получа<strong>е</strong>тся, что <strong>е</strong>сли байт в с<strong>е</strong>риализованном<br />

файл<strong>е</strong> соотв<strong>е</strong>тству<strong>е</strong>т м а ­<br />

сти, мы смож<strong>е</strong>м пом<strong>е</strong>нять масть карты,<br />

прочитав файл, изм<strong>е</strong>нив один байт и снова<br />

записав информацию в файл. (Им<strong>е</strong>йт<strong>е</strong><br />

в виду, что в ваия<strong>е</strong>м с<strong>е</strong>риализованном<br />

файл<strong>е</strong> информация о масти мож<strong>е</strong>т быть<br />

сохран<strong>е</strong>на в другом м<strong>е</strong>ст <strong>е</strong>)<br />

Если числа,<br />

которы<strong>е</strong> вы<br />

однаружи -<br />

ли в сво<strong>е</strong>м<br />

файл<strong>е</strong>, о т ­<br />

личаются<br />

от наших,<br />

подставьт<strong>е</strong><br />

их сюда.<br />

Вручную создадим новый ф айл с корол<strong>е</strong>м пик.<br />

О тр <strong>е</strong> д а кти р у<strong>е</strong> м о д и н из п р о ч и т а н н ы х м ассивов и снова запиш <strong>е</strong>м <strong>е</strong>го в файл.<br />

f i r s t F i l ^ [ 3 2 2 ] \ = (b y te ) S u i t s . S p ad es ;<br />

f i r s t F i l A ,|3 8 2 y =<br />

F i l e . D e l e t e ( " k in g -s . dat" ) ;<br />

(b y te ) V a lu e s . K ing;<br />

F i l e .W r i t e A l l B y t e s ( " k i n g - s .d a t " , f i r s t F i l e ) ;<br />

Т <strong>е</strong>п<strong>е</strong>рь д <strong>е</strong> с <strong>е</strong> р и а л и з у й т <strong>е</strong> ф а й л k i n g - s . d a t и уб<strong>е</strong>дит<strong>е</strong>сь, ч т о в н<strong>е</strong>м с д <strong>е</strong> р ж и т с я к о р о л ь п и к !<br />

Зная, каки<strong>е</strong> им<strong>е</strong>нно байты сод<strong>е</strong>ржат<br />

информацию о масти и знач<strong>е</strong>нии<br />

карты, мы р<strong>е</strong>дактиру<strong>е</strong>м эти байты<br />

п<strong>е</strong>р<strong>е</strong>д записью в файл king-s.dat.<br />

440 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Сло)кности работы с двоичными файлами<br />

Ч т о д<strong>е</strong>лать, <strong>е</strong>сли вы н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong> т о ч н о , какая и н ф о р м а ц и я со д <strong>е</strong> р ж и тся в файл<strong>е</strong>? Н <strong>е</strong> и зв<strong>е</strong>стн о даж<strong>е</strong>, каким<br />

п р и л о ж <strong>е</strong> н и <strong>е</strong> м э то т ф айл б ы л создан, а п р и о т к р ы т и и <strong>е</strong>го в Б л о кн о т<strong>е</strong> вы в и д и т<strong>е</strong> то л ь ко мусор. Я сн о<br />

то л ь ко , ч т о Б л о к н о т н<strong>е</strong> слиш ком п о д х о д и т для о т к р ы т и я т а к о го рода ф айлов.<br />

П<strong>е</strong>р<strong>е</strong>д вами с<strong>е</strong>риализованная карма,<br />

открытая в Злокнот<strong>е</strong>. Вряд ли кто -<br />

то смож<strong>е</strong>т воспользоваться этой<br />

информаци<strong>е</strong>й.<br />

3 king-s - Notepad<br />

File Edit Formst View H dp<br />

p s e r la liz e a deck of cards, v e r s io r -l 0 .0 .0 ,<br />

I ^ ____— . d T T i г- — « - - ч - і Л - ї т л -л A fs jr -h ’ л -Р i— »г*<br />

Cu1ture=neutra1, PublicKeyToken=nuI и sen an ze_a_aecK _or_caras.tai u-<br />

ik__Back1ngFie1dTk__Back1ngFie1d-JSeriali2e_a_deck_of_cards. su its,<br />

s e r ia lі ze_a_deck_of_cards.values, , iÿyÿÿserialize_a_deck_of.c a r d s .s u its<br />

•value__ a lüÿyÿ ser1a1ize_a_deck_of_cards.values «value<br />

Ho этой информации явно н<strong>е</strong>достаточно.<br />

С ущ <strong>е</strong>ству<strong>е</strong>т та к о й ф орм ат как дамп д а н н ы х (h e x d u m p ), о б ы ч н о использу<strong>е</strong>м ы й для п р о с м о тр а д в о и ч ­<br />

н о й и н ф о р м а ц и и . О н н а м н о го бол<strong>е</strong><strong>е</strong> и н ф о р м ати в <strong>е</strong> н . К а ж д ы й б а й т пр<strong>е</strong>дставл<strong>е</strong>н в вид<strong>е</strong> двух сим волов<br />

в ш <strong>е</strong> с тн а д ц а т<strong>е</strong> р и ч н о й сист<strong>е</strong>м <strong>е</strong>, ч т о позво л я <strong>е</strong> т с к о н ц <strong>е</strong> н тр и р о в а т ь м н о го ч и с л <strong>е</strong> н н ы <strong>е</strong> д анны <strong>е</strong> в н<strong>е</strong>больш<br />

ом объ<strong>е</strong>м<strong>е</strong>. Д в о и ч н ы <strong>е</strong> д анны <strong>е</strong> такж <strong>е</strong> х о р о ш о п р<strong>е</strong>дставл ять в стр о к а х д л и н о й п о 8 ,1 6 и л и 32 байта, так<br />

как о н и д<strong>е</strong>лятся и м <strong>е</strong> н н о на та ки <strong>е</strong> кусо чки . К прим <strong>е</strong>ру, ф орм ат i n t заним а<strong>е</strong>т до 4 байт, со о тв <strong>е</strong> тств <strong>е</strong> н н о ,<br />

и м <strong>е</strong> н н о та кую д л и н у о н им <strong>е</strong><strong>е</strong>т посл<strong>е</strong> с<strong>е</strong>риализации. В о т как наш ф айл вы гл я д и т в вид<strong>е</strong> ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч­<br />

н о го дампа:<br />

М ож но сразу<br />

увид<strong>е</strong>ть числ<strong>е</strong>нно<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong><br />

каждого байта.<br />

Число в начал<strong>е</strong><br />

каждой строки<br />

указыва<strong>е</strong>т на<br />

сдвиг п<strong>е</strong>рвого<br />

байта о оч<strong>е</strong>р<strong>е</strong>ди.<br />

; (Bj C:\Windows\system52\cmd.exe<br />

Г500О ; 00 01 00 00 00 fd fd fd -- fd 01 00 00 00 00 00 00<br />

С1010: 00 0c 02 00 00 00 3f, 43 -- 68 6,1 78 74 65 72 33 2c ..... ?Chapter9,<br />

0020; 20 56 65 72 73 69 6f Se -- 3d 31 2e 30 2e 30 2e 38 Uersion=1,0.0.0<br />

0030; 2c 20 43 75 6c 74 75 72 -- 65 3d 6e 65 75 74 72 61 . Culture=neu'tra<br />

0040; 0c. ;.r 20 50 75 62 Sc 69 -- 63 4b 65 73 54 6f 6b 65 1, PublicKeyToke’<br />

75 6c 6c 05 01 — 08 00 00 0d 43 Є8 61 70 n=riull.... ;Chap<br />

0060: 74 72 39 2e 43. 61 72 -- 64 02 80, 00 00 04 53 75 ter9.Card, .. .Su<br />

69 74 05 s'e 61 6c 75 65 -- 04 04 13 43 68 61 70 74 i t .Ualue...Chapt<br />

ж о ї в ) ) 65 ,72 39 2e 43 61 72 64 -- 2b'53 75 69 74 73 02 00 erS.Card+Suits.,<br />

m w 00 00 14 43 68 81 70 74 -- 65 72 33 2e 43 61 72 64 ...Chapters.Card<br />

08a0 2b 56 61 6c 75 65 ,73. 02 -- 80 00 00 02 08 80 00 .05 +Ualues.........<br />

00Ь0 fd fd fd fd 13 43 68 61 -- 70 74 65 72 39 2e 43 61 .... Chapters.Ca<br />

150с0 72 64 2b 53 75 69 74 73 -- 01 00 '00 00 07 76 61 Ec rd+Suits.....yal<br />

P)0d0 ?5 65 5f 5f 00 08 82 00 -- 00 00 01 00 00 08 05 fd ue<br />

0О<strong>е</strong>0 fd fd fd 14 43 68 61 70 -- 74 65 72 39 2© 43 61 72 ... Chapters.Car<br />

nofo 64 2b 56 61 6c 75 65 73 -- 01 00 00 00 07 76 61 6c d+Ualues.... ual<br />

ul 00 7S 65 5f 5f 00 S8 02 00 -- 80 00 03 00 00 00 0b 02<br />

...........<br />

........serisliir^<br />

:110 80 00 00 03 00 00 oa Ob -- 73 65 72 6Э 61 6c G9 ?3<br />

ei 20 65 ?2 2e 43 61 72 64 2b. -- 56 61 6c 75 65 Î3 01 08 er.Card+Ualues. .<br />

П130 00 00 9T 76 61 6c 75 65 -~ 5f 5f 00 08 02 00 00 00 ...ualue ....:.<br />

Ul 40 03 00 00 00 Ob --<br />

Г|<br />

Вы мож<strong>е</strong>т<strong>е</strong><br />

читать<br />

исходный<br />

т<strong>е</strong>кст, а м у ­<br />

сор зам<strong>е</strong>н<strong>е</strong>н<br />

точками.<br />

дальш<strong>е</strong> ¥ 441


69 73 6<strong>е</strong> 27 74 20 74 68 69 73 20 66 75 6<strong>е</strong> 3f0a<br />

Программа для создания дампа<br />

Д а м п о м д а н н ы х (h e x d u m p ) назы ва<strong>е</strong>тся пр<strong>е</strong>дставл <strong>е</strong>ни<strong>е</strong> со д <strong>е</strong> р ж и м о го ф айла в ш<strong>е</strong>стнадцат<strong>е</strong>ричном вид<strong>е</strong>.<br />

Э то пр<strong>е</strong>дставл <strong>е</strong>ни<strong>е</strong> часто использу<strong>е</strong>тся для п о л уч<strong>е</strong>ния св<strong>е</strong>д<strong>е</strong>ний о в н у тр <strong>е</strong> н н <strong>е</strong> й стр уктур <strong>е</strong> ф айла. В больш<br />

и н с тв <strong>е</strong> о п <strong>е</strong> р а ц и о н н ы х сист<strong>е</strong>м им <strong>е</strong><strong>е</strong>тся в стр о <strong>е</strong> н н а я прогр а м м а для р а б о ты с дам пом д а н н ы х. К сож ал<strong>е</strong>н<br />

и ю , W in d o w s в и х ч и сло н<strong>е</strong> входит, поэто м у создадим п р о гр а м м у сам остоят<strong>е</strong>льно.<br />

Создани<strong>е</strong> дампа данных<br />

Н а ч н <strong>е</strong> м с т<strong>е</strong>кста:<br />

We t h e P e o p le o f th e U n ite d S t a t e s , i n O rder t o form a more p e r f e c t U n i o n . ..<br />

В о т как о н буд<strong>е</strong>т вы гляд<strong>е</strong>ть в дамп<strong>е</strong> д а н н ы х:<br />

Вы мож<strong>е</strong>т<strong>е</strong> вид<strong>е</strong>ть числ<strong>е</strong>нно<strong>е</strong><br />

пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> каждого байта.<br />

0000: 57 65 20 74 6 8 6 5 ( ^ 5 0<br />

0010: 20 74 68 65 20 55 6 <strong>е</strong> 69<br />

0020: 65 73 2с 20 69 6 <strong>е</strong> 20 4 f<br />

0030: 6 6 6 f 72 6 d 20 61 20 6 d<br />

65 63 74 20 55 6 e 69 6 f<br />

65<br />

74<br />

72<br />

Число в начало каждой строки добавля<strong>е</strong>тся,<br />

используя см<strong>е</strong>ш,<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>рвого байта.<br />

6 f 70<br />

65 64<br />

64 65<br />

6 f 72 65<br />

6 e 2 e 2 e<br />

6 c<br />

20<br />

72<br />

20<br />

2 e<br />

65<br />

53<br />

20<br />

70<br />

20 6 f 66<br />

74 61 74<br />

74<br />

65<br />

6 f<br />

72<br />

20<br />

66<br />

We t h e P e o p le o f<br />

th e U n ite d S t a t<br />

e s , i n O rder t o<br />

form a more p e r f<br />

e c t U n io n .. .<br />

Мусор был<br />

зам<strong>е</strong>н<strong>е</strong>н<br />

точками.<br />

К аж до<strong>е</strong> из э т и х чис<strong>е</strong>л — 57, 65, 6F — зн ач<strong>е</strong>ни<strong>е</strong> о д н о го байта в файл<strong>е</strong> в ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч н о м пр<strong>е</strong>дставл<strong>е</strong>н<br />

и и (h e x ). Е сли в д <strong>е</strong> с я ти ч н о й сист<strong>е</strong>м <strong>е</strong> вы использу<strong>е</strong>т<strong>е</strong> числа о т О до 9, т о зд<strong>е</strong>сь к числам добавляю тся<br />

<strong>е</strong>щ<strong>е</strong> и буквы о т А до F.<br />

К аж дая с тр о ч к а в дамп<strong>е</strong> д а н н ы х пр<strong>е</strong>дставля<strong>е</strong>т ш <strong>е</strong>стнадцать в ы в о д и м ы х сим волов, из к о т о р ы х о н а собств<br />

<strong>е</strong> н н о и была создана. П <strong>е</strong> р в ы <strong>е</strong> ч<strong>е</strong>ты р <strong>е</strong> ц и ф р ы в наш <strong>е</strong>м случа<strong>е</strong> — это см <strong>е</strong>щ <strong>е</strong>ни<strong>е</strong> в н у т р и ф айла: п<strong>е</strong>рвая<br />

с тр о ч к а начина<strong>е</strong>тся с О, сл<strong>е</strong>дующ ая с 16 (в ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч н о й сист<strong>е</strong>м <strong>е</strong> э то 10), сл<strong>е</strong>дующ ая с 32 и т. д.<br />

(Д руги<strong>е</strong> ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч н ы <strong>е</strong> дам пы м о гут вы гляд<strong>е</strong>ть по-другому.)<br />

Работа 6 ш<strong>е</strong>стнадцат<strong>е</strong>ричной сист<strong>е</strong>м<strong>е</strong> счисл<strong>е</strong>ния<br />

Для ввода ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч н ы х чи с<strong>е</strong>л в п рогр а м м у д о ста то ч н о д обавить<br />

п<strong>е</strong>р<strong>е</strong>д о б ы ч н ы м числом сим волы Ох (н о л ь, а зат<strong>е</strong>м х ):<br />

i n t j = 0 x 2 0 ;<br />

M e s s a g e B o x .S h o w ("T h e v a lu e i s " + j ) ;<br />

О п <strong>е</strong> р а то р +, п р <strong>е</strong> о б р а зую щ и й чи сл а в с т р о к и , возвращ а<strong>е</strong>т зн ач<strong>е</strong>ни<strong>е</strong> в д<strong>е</strong>ся<br />

ти ч н у ю сист<strong>е</strong>м у с числ<strong>е</strong>ния. Д ля пр<strong>е</strong>образо вания к ш <strong>е</strong> с тн а д ц а т<strong>е</strong> р и ч н о й<br />

сист<strong>е</strong>м <strong>е</strong> пользуйт<strong>е</strong>сь ста ти ч <strong>е</strong> ски м м <strong>е</strong>тодом S t r i n g . F o rm a t { ) :<br />

s t r i n g h = S t r i n g . F o r m a t { " { о : x 2 } " , j ) ;<br />

М<strong>е</strong>тод Strina. Formate)<br />

использу<strong>е</strong>т 8 кач<strong>е</strong>ств<strong>е</strong><br />

парам<strong>е</strong>тра м<strong>е</strong>тод<br />

Console. WriteUneQ,<br />

так что вы б<strong>е</strong>з пробл<strong>е</strong>м<br />

мож<strong>е</strong>т<strong>е</strong> с ним<br />

работать.<br />

442 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

Д остаточно StreamReader и StreamVl/riter<br />

Н аш а програм м а буд<strong>е</strong>т писать данны <strong>е</strong> н <strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно в файл. Так как мы<br />

записыва<strong>е</strong>м вс<strong>е</strong>го л и ш ь т<strong>е</strong>кст, воспользу<strong>е</strong>мся объ<strong>е</strong>ктом S t r e a m W r it e r . Н ам<br />

потр<strong>е</strong>бу<strong>е</strong>тся такж <strong>е</strong> м<strong>е</strong>тод R e a d B lo c k O объ<strong>е</strong>кта S t r e a m R e a d e r , читаю ш ;ий<br />

б локи сим волов в массив ти п а c h a r ; н уж н о то л ько указать разм<strong>е</strong>р блока. Так<br />

как в строк<strong>е</strong> м ы отображ а<strong>е</strong>м 16 сим волов, о н буд<strong>е</strong>т б л оки ч и та ть им <strong>е</strong> н н о так<br />

о го разм<strong>е</strong>ра.<br />

Д обавьт<strong>е</strong> ф орм <strong>е</strong> <strong>е</strong>щ<strong>е</strong> одну кнопку, с н <strong>е</strong> й м ы свяж <strong>е</strong>м п р о гр а м м у создания дампа<br />

д а н н ы х. И зм <strong>е</strong> н и т<strong>е</strong> м а р ш р уты доступа в п <strong>е</strong> р в ы х двух с тр о ч к а х , ч т о б ы ohki<br />

указы вали на р<strong>е</strong>альны <strong>е</strong> ф айлы . Н а ч н и т <strong>е</strong> с с <strong>е</strong> р и а л и зо в а н н о го ф айла C ard.<br />

М <strong>е</strong> т о З н а з ы в а <strong>е</strong> т с я<br />

R e a d B lo c k (). п о т о -<br />

ч т о п р и в ы з о в <strong>е</strong><br />

он « б л о к и р у <strong>е</strong> т с я »<br />

( т о <strong>е</strong> с т ь н <strong>е</strong> в о з в р а ­<br />

щ а <strong>е</strong> т с я 6 п р о г р а м м у ,<br />

а р а б о т а <strong>е</strong> т ) , п о к а<br />

н<strong>е</strong> п р о ч и т а <strong>е</strong> т и л и в с <strong>е</strong><br />

з а к а з а н н ы <strong>е</strong> в а м и с и м ­<br />

в о л ы и л и ф а й л до к о н ц а .<br />

u s in g (Stream R ead er r e a d e r = new S t r e a m R e a d e r (@"c:\ f i l e s \ i n p u t F i l e . t x t " ))<br />

u s in g (S trea m W riter w r i t e r = new S tr e a m W r ite r ( © " c : \ f i l e s \ o u t p u t F i l e . t x t " , f a l s e ) )<br />

f ^ С в о й с т в о E n d O f S t r e a m о б ъ <strong>е</strong> к т а S t r e a m R e a d e r в о з в р а щ а <strong>е</strong> т з н а ч <strong>е</strong> -<br />

. / ^ ^ 1 Т ^ , п ^ ^ о с т а ю т с я п р <strong>е</strong> д н а з н а ч <strong>е</strong> н н ь > <strong>е</strong> д л я ч т <strong>е</strong> н и я с и м в о л ы .<br />

i n t p o s it io n 0 ; Этот м<strong>е</strong>тод ReadBlockO ч и -<br />

т а <strong>е</strong> т в м а с с и в т и п а c h a r б л о -<br />

w h ile ( 1r e a d e r . EndOf Stream ) { Ки р а з м <strong>е</strong> р о м до с и м в о л о в .<br />

c h a r [] b u f f e r = new c h a r [1 6 ]; ^ __ _<br />

i n t c h a r a c te r s R e a d = r e a d e r .R e a d B lo c k ( b u f f e r , 0, 16);<br />

w r i t e r . W r i t e ( " { 0 } : ", S t r in g .F o r m a t ( " { O :x4}", p o s i t i o n ) ) ;<br />

p o s i t i o n += c h a r a c te r s R e a d ;<br />

f o r ( i n t і = 0 ; і < 16; i++ ) {<br />

i f ( i < c h a r a c te r s R e a d ) {<br />

Э т о т ц и к л<br />

п о о ч <strong>е</strong> р <strong>е</strong> д и s t r i n g h e x = S t r i n g . F o rm a t( ' { 0 :x 2 }", ( b y t e ) b u f f e r [І] )<br />

в ы в о д и т w r i t e r .W r it e ( h e x + " " );<br />

в с <strong>е</strong> с и м в о ­<br />

лы .<br />

}<br />

}<br />

e l s e<br />

w r i t e r . W r i t e (" ') ;<br />

i f ( і == 7) { w r i t e r .W r i t e ( " - - " ); }<br />

м Г з а м <strong>е</strong> н я <strong>е</strong> м их т и к а м и .<br />

i f ( b u f f e r [i] < 32 I I b u f f e r [ i ] > 250) { b u f f e r [ i ] =<br />

s t r i n g b u f f e r C o n t e n t s = new string (buff er) ; ^ ^ ^<br />

w r i t e r W r it e L in e ("<br />

" + b u f f e r C o n t e n t s .Substring(0, charactersRead));<br />

Статич<strong>е</strong>ский м<strong>е</strong>тод<br />

String.ForMat пр<strong>е</strong>образу -<br />

<strong>е</strong>т числа в строки. Запись<br />

«(О: х 4 } » указыва<strong>е</strong>т<br />

м<strong>е</strong>тоду Format Q выв<strong>е</strong>сти<br />

второй парам<strong>е</strong>тр,<br />

в наш<strong>е</strong>м случа<strong>е</strong>, position,<br />

о вид<strong>е</strong> ^--значного ш <strong>е</strong>стнадцат<strong>е</strong>ричного<br />

числа.<br />

Массив char[] можно<br />

пр<strong>е</strong>образовать<br />

в строку, п<strong>е</strong>р<strong>е</strong>дав<br />

<strong>е</strong>го п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нному<br />

конструктору п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

string ^<br />

М<strong>е</strong>тод Substring возвраща<strong>е</strong>т фрагм<strong>е</strong>нт строки. В данном случа<strong>е</strong> он возвраща<strong>е</strong>т п<strong>е</strong>рвы<strong>е</strong><br />

символы п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной charactersRead, отсчитывая ик от начала (position О). (Посмотрит<strong>е</strong> на<br />

проц<strong>е</strong>дуру задания п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной charactersRead в цикл<strong>е</strong> while —м<strong>е</strong>тод ReadBlockO возвраща<strong>е</strong>т<br />

в массив число прочитанных им символов.)<br />

дальш<strong>е</strong> у 443


постро<strong>е</strong>ни<strong>е</strong> дампа данных<br />

Чт<strong>е</strong>ни<strong>е</strong> байтоб из потока<br />

С т<strong>е</strong>кстовы м и ф айлами наш а програм м а пр<strong>е</strong>кр а сн о работа<strong>е</strong>т. Н о п опробуйт<strong>е</strong> воспользоваться м<strong>е</strong>тодом<br />

F i l e . W r i t e A l l B y t e s () для записи в ф айл массива б айтов со знач<strong>е</strong>ниям и больш <strong>е</strong> 127 и п о см о тр и т<strong>е</strong> на<br />

дамп данны х. В ы обнаруж ит<strong>е</strong> то л ько набор сим волов «fd»! Д <strong>е</strong>ло в том , ч т о объ<strong>е</strong>кт StreamReader пр<strong>е</strong>дназнач<strong>е</strong>н<br />

для чт<strong>е</strong>ния т<strong>е</strong>кстовых файлов, сод<strong>е</strong>рж ащ их б а й ты со знач<strong>е</strong>ниям и до 128. Д авайт<strong>е</strong> п рочита <strong>е</strong> м байт<br />

ы н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно из п о то ка п р и п о м о щ и м<strong>е</strong>тода Stream. Read О . М ы получим п р а кти ч <strong>е</strong> ски р<strong>е</strong>ально<strong>е</strong><br />

п р и л о ж <strong>е</strong> н и <strong>е</strong> для р аботы с дампом д анны х: вы см ож <strong>е</strong>т<strong>е</strong> даж<strong>е</strong> п<strong>е</strong>р<strong>е</strong>давать <strong>е</strong>му им <strong>е</strong>на ф айлов как аргум<strong>е</strong>нты<br />

из командной строки.<br />

С оздайт<strong>е</strong> ко н сольно<strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> с им <strong>е</strong>н<strong>е</strong>м hexdumper. К о д для н <strong>е</strong> го н а хо д и тся на сл<strong>е</strong>дую щ <strong>е</strong>й с тр а н и ­<br />

ц<strong>е</strong>, а в о т как в ы гл я д и т р<strong>е</strong>зультат <strong>е</strong>го р а б о ты :<br />

Попытка зап \стить наш<strong>е</strong><br />

прилож<strong>е</strong>ни<strong>е</strong> гб<strong>е</strong>з указания ш ими м <strong>е</strong>­-<br />

ни файла приводит к сооби^<strong>е</strong>нию<br />

об ошибк<strong>е</strong>.<br />

При попытк<strong>е</strong> п<strong>е</strong>р<strong>е</strong>дать прилож<strong>е</strong>нию<br />

имя н<strong>е</strong>суш,<strong>е</strong>ствующ<strong>е</strong>го файла<br />

появля<strong>е</strong>тся сооби^<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>.<br />

I C;\Windo№s\system32Sc!nd.f<br />

|‘,::\teiiip>hexdurapei* 1<br />

111 sage - >iexdrkpe;I- ,fils--to~dl np<br />

1<br />

г :\t e rap ^Jiexdumpe i* dotJS~!11./t~exiSt-dat<br />

1lie doe:s not ISXi:St: doe not“exist -dat'<br />

usage - hexdpipejr file-' to "'.durip<br />

^ — "<br />

r‘:\temp>hexduripei' kina-s.dat<br />

‘«100: 00 01 00 00 00 ff ff ff 01 08 00 .00 00 00 00 ..<br />

00 0c 02 00 80 00,/50 53 — 65 72 69 61 6c 69 7a 65 . . , - ..PSes'ialxae<br />

И020: 20 61 20 64 65 63 6b 20 6f 66 2,0 63 61 72 ■64 73 cl d.i?ck of cai'ds<br />

ЙЙ30: 2 c 20 S6 6S 72 69 6f 6e 3d 31 2e 30 2e 30 2e . Uersion =1.0,0.<br />

H040: 30 2c 20 43 75 бЗ 74 75 — 72 65 3d 6e 65 75 74 72 .0, Gultui'e -neiiti'<br />

И0\.0:- 61 6 c 2c 20 50 7S 62 6c — 69 63 4b 65 79 54 6f 6b al, PublicKeA^Tok i<br />

И060: 65 6e 3d 6e 7S 6|fc 6c 05 — 01 00 00 '00 le 53 65 72 e n 1111..... 8 e r<br />

И07В: 69 61 6c 69 7a 6Б Sf 61 — Sf 64 6S 63 6b Sf 6f 66 ia i is e _;a__dec k_o f<br />

ИИ80: 5f 63 61 72 64 ,?3 2e 43 — 61 72 64 02 00 80 00 15 „cai'-ds,Card.....<br />

ИЯ90: 3c S3 75 69 74 3e 6b Sf — Sf 42 61 63 6b 69 6e 67 k_.Backing<br />

46 69 65 6c 6(4 16 3c 56 — 61 6c 75 65 3e 6b 5f 5f<br />

H0b0:<br />

Fie id.k__<br />

42 61 63 6b 6:9 б<strong>е</strong> 67 46 69 65 6c 64 04 04 If &3<br />

И0С0:<br />

BackingField...S<br />

65 72 69 61 6c 69 7a 65 — ' Sf 61 Sf 64 65 63 6 b ey ia 1 ia'e _a deck<br />

ti!Jd0: 6f 66 Sf 63 61 72 64 73 2e 53 75 69 74 73 02 00<br />

Ии<strong>е</strong>В:<br />

of __cai'ds .Suits ..<br />

00 0Й 20 S3 65 72 69 6,1 — 6 c 69 7a 65 5f 61 5f 64<br />

it0f0:<br />

-- St^rialise_a_.d<br />

65 63 6b Sf 6f 66 5f 6;-! 61 72 64 73 2e 56 .61 6c e c k„o f ,_c ards .U a 1<br />

Й10Й: ?5 6S 73 02 j00 00 00 00 00 00 05 fd ff ff ff wes.............<br />

И110: If 53 65 72 69 61 « 6jV 7a 6S 5f 61 Sf 64 65 63 .Sei*iali2 e_a dec<br />

(1120: 6 b 5f 6f 66 Sf 63 i i 64 73 2e 53 7S 69 74 73 ^—0 f _cai'ds .Suits<br />

W130: 01 00 00 00 07 76 t 1 75 65 Sf Sf 00 08 02 m «....value<br />

HI 40: 00 00 00 00; 00 08 05 ff ff ff 20 53 65 72 69 Seri<br />

i!lS0: 61 6c 69 7a ,65 Sf 61 64 65 63 6b Sf 6f 66 5f a 1 ;ijje ,_a„de c k.__of „<br />

«160: 63 61 72 64, 73 2e Su ,1 ■--- 6 c 75 65 73 01 00 00 00 carcts.Ualues«...<br />

(S178: 07 76 61 .6cj 75 65 Sf k t ■— 00 08 02 00 00 00 0d m -value_-..... .<br />

И180; 00 08 0b “ .<br />

1<br />

;C:\tenp><br />

I<br />

А ам п данных<br />

суи^<strong>е</strong>ствуюи^<strong>е</strong>го<br />

файла выводится<br />

на консоль.<br />

Обычно вывод на<br />

консоль осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

м<strong>е</strong>тодом<br />

Console.WriteLineO.<br />

Но мы воспользовались<br />

м <strong>е</strong>т о­<br />

дом Console.Error.<br />

WriteLineQ для<br />

вывода сообщ<strong>е</strong>ний<br />

об ошибк<strong>е</strong>.<br />

Для п<strong>е</strong>р<strong>е</strong>дачи аргум<strong>е</strong>нтов комаиР}ипГ ^ Р


о Е сл и с в о й с т в о a r q s .L e n a th н <strong>е</strong> р а в н о 1 , чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

^ f ^ 9 a 4 u а р г у м <strong>е</strong> н т о б з н а ч и т , в к о м а н д н у ю с т р о к у а р г у -<br />

к о м а н д н о й ч / м <strong>е</strong> н т ы н <strong>е</strong> п <strong>е</strong> р <strong>е</strong> д а ю т с я и л и , н а о б о р о т ,<br />

з у <strong>е</strong> т с я п а р а м р ^ ' \ ф п <strong>е</strong> р <strong>е</strong> д а <strong>е</strong> т с я б о л <strong>е</strong> <strong>е</strong> о д н о го а р г у м <strong>е</strong> н т а .<br />

s t a t i c v o i d M a in ( s t r in g [ ] a r g s) в н и м а н и <strong>е</strong> , к а к E x it() з а в <strong>е</strong> р ш а <strong>е</strong> т<br />

з д <strong>е</strong> с ь и с п о л ь з у <strong>е</strong> т с я м <strong>е</strong> т о д п р о г р а м м у . В о т в <strong>е</strong> т н л<br />

i f (a r g s .L e n g th != 1 )<br />

C o n s o le .E r r o r .W r ite U n e Q .<br />

п <strong>е</strong> р <strong>е</strong> д а ч у <strong>е</strong> м у з н а ч <strong>е</strong> н и я т и п а<br />

^ ~ im n f t ОН пи в о зврз в юа аш ,аа <strong>е</strong> т к о д о ш и о<br />

C o n s o le .E r r o r .W r it e L in e ( " u s a g e : hexdm per f i le - t o - d u m p " ); (что п о л <strong>е</strong> з н о п р и н а п и<br />

S y stem .E n v iro n m en t .E x it (1) ;<br />

са н и и к о м а н д н ы к с ц <strong>е</strong> н а р и <strong>е</strong> в<br />

и к о м а н д н ы х ф а й л о в ).<br />

f { ' F i l e . E x i s t s ( a r g s [0] ) )<br />

. ^ Е с л и п <strong>е</strong> р <strong>е</strong> д а н н о г о ф а й л а<br />

н <strong>е</strong> с у щ <strong>е</strong> с т в у <strong>е</strong> т , в ы в о -<br />

C o n s o le .E . Er r o r .W. W riteL Lim<br />

in e ( " F ile d o e s n o t e x i s t :<br />

S y s t e m .E n v ir o n m e n t .E x it (2 );<br />

{O}", a r g s [ 0 ] ) ; д и т с я друго<strong>е</strong> с о о б щ <strong>е</strong> н и <strong>е</strong><br />

и в о з в р а щ а <strong>е</strong> т с я д р у г о й<br />

-у к о д о ш и б к и .<br />

u s in g (Stream in p u t = F ile .O p e n R e a d (a r g s [0] ) )<br />

т а к к а к б а й т ы ч и т а - М <strong>е</strong> т о д S t r e a m .<br />

i n t p o s i t i o n = 0 ; ю т с я н <strong>е</strong> п о с р <strong>е</strong> д с т в <strong>е</strong> н н о R -ead() ч и т а <strong>е</strong> т<br />

b y t e [ ] b u f f e r = new b y t e [1 6 ]; и з п о т о к а . — ^ а й т ы в б у ф <strong>е</strong> р .<br />

w h ile ( p o s i t i o n < i n p u t . L ength) i ^ д а н н о м с л у ч а <strong>е</strong><br />

{ о и ф <strong>е</strong> р а и г р а <strong>е</strong> т<br />

i n t c h a r a c te r s R e a d = i n p u t . Read (bu f f e r , 0, b u f f e r . L ength) ; f e d b M b ^ ^ ^ a c M ^ ’<br />

i f (c h a r a c te r s R e a d > 0) б а й т ы и з т <strong>е</strong> к с т а -<br />

{ в о г о ф а й л а .<br />

C o n s o le .W r it e (" { 0 } : ", S t r in g .F o r m a t (" { о : х 4 } ", p o s i t i o n ) ) ;<br />

p o s i t i o n += c h a r a c te r s R e a d ;<br />

/ f o r ( i n t i = 0 ; i < 16; i++ )<br />

i f ( i < c h a r a c te r s R e a d )<br />

Э т а ч а с т ь<br />

п р о г р а м м ы<br />

о с т а л а с ь н <strong>е</strong> и з ­<br />

м <strong>е</strong> н н о й , п р о с т о<br />

б у ф <strong>е</strong> р т <strong>е</strong> п <strong>е</strong> р ь<br />

с о д <strong>е</strong> р ж и т б а й ­<br />

т ы , а н <strong>е</strong> с и м ­<br />

в о л ы (но м <strong>е</strong> т о д<br />

S tr in g . fo r m a tQ }<br />

р а б о т а <strong>е</strong> т \<br />

в л ю б о м с л у ч а <strong>е</strong> ). \<br />

}<br />

e l s e<br />

s t r i n g h e x = S t r in g .F o r m a t ( " { 0 : x 2 } " , ( b y t e ) b u f f e r [ i ] );<br />

C o n s o le .W r it e ( h e x + " " );<br />

C o n s o le .W r it e (" " );<br />

i f ( i == 7)<br />

C o n s o le . W r it e (" -- " ) ;<br />

i f ( b u f f e r [ i ] < 32 I I b u f f e r [ i ] > 250) { b u f f e r [ i ] = ( b y t e ) ' . ' ; }<br />

}<br />

s t r i n g b u f f e r C o n t e n t s = E ncodin g.U T F 8 .G e t S t r i n g ( b u f f e r ) ;<br />

C o n so le .W r ite L in e ( " b u f f e r C o n t e n t s . S u b s t r in g (0, c h a r a c t e r s R e a d ) ) ;<br />

и ж<strong>е</strong> м ассив a« “ з“«<br />

дальш<strong>е</strong> * 445


часто задава<strong>е</strong>мы<strong>е</strong> вопросы<br />

_ Чаацо<br />

Поч<strong>е</strong>му посл<strong>е</strong> м<strong>е</strong>тодов<br />

File.ReadAllTextо и File.<br />

WriteAllText О я н<strong>е</strong> пользуюсь<br />

м<strong>е</strong>тодом Close () ?<br />

Q ; в класс<strong>е</strong> F i l e присутствуют<br />

н<strong>е</strong>сколько статич<strong>е</strong>ских м<strong>е</strong>тодов, которы<strong>е</strong><br />

автоматич<strong>е</strong>ски открывают файл,<br />

читают или пишут данны<strong>е</strong> и зат<strong>е</strong>м<br />

автоматич<strong>е</strong>ски закрывают <strong>е</strong>го. Вдобавок<br />

к уж<strong>е</strong> упомянутым сюда относятся<br />

м<strong>е</strong>тоды R e a d A llB y te s ()<br />

и W r ite A llB y te s ( ) , работающи<strong>е</strong><br />

с массивами байтов, а такж<strong>е</strong><br />

м<strong>е</strong>тоды R e a d A llL in e s ()<br />

и W r it e A llL in e s ( ) , читающи<strong>е</strong><br />

строковы<strong>е</strong> массивы, в которых каждая<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная становится новой строкой<br />

в файл<strong>е</strong>. Вс<strong>е</strong> эти м<strong>е</strong>тоды автоматич<strong>е</strong>ски<br />

открывают и закрывают потоки, поэтому<br />

дополнит<strong>е</strong>льны<strong>е</strong> оп<strong>е</strong>раторы вам н<strong>е</strong> тр<strong>е</strong>буются.<br />

Если в класс<strong>е</strong> FileStream<br />

им<strong>е</strong>ются м<strong>е</strong>тоды чт<strong>е</strong>ния и записи, зач<strong>е</strong>м<br />

нужны классы StreamReader<br />

и StreamWriter?<br />

^ ! Класс F ile S tr e a m использу<strong>е</strong>тся<br />

для чт<strong>е</strong>ния и записи байтов в двоичный<br />

файл. Его м<strong>е</strong>тоды работают с байтами<br />

и массивами байтов. Но <strong>е</strong>сть и программы,<br />

работающи<strong>е</strong> только с т<strong>е</strong>кстовыми<br />

данными, наприм<strong>е</strong>р, наша п<strong>е</strong>рвая<br />

в<strong>е</strong>рсия программы Excuse Generator.<br />

Там мы использовали м<strong>е</strong>тоды классов<br />

S tream R ead er ИStream W riter,<br />

созданны<strong>е</strong> сп<strong>е</strong>циально для работы со<br />

строками т<strong>е</strong>кста. Б<strong>е</strong>з них вам приходилось<br />

бы сначала читать массив байтов<br />

и писать цикл, ищущий в этом массив<strong>е</strong><br />

знаки п<strong>е</strong>р<strong>е</strong>носа строки, так что иногда эти<br />

классы сильно обл<strong>е</strong>гчают жизнь.<br />

Когда использу<strong>е</strong>тся класс File,<br />

а когда класс Filelnfo?<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Б о 11| > о с ь 1<br />

Q ; Основным их различи<strong>е</strong>м явля<strong>е</strong>тся<br />

тот факт, что м<strong>е</strong>тоды класса F i l e<br />

являются статич<strong>е</strong>скими, поэтому вам<br />

н<strong>е</strong> нужно создавать их экз<strong>е</strong>мпляры.<br />

А класс F i l e l n f o тр<strong>е</strong>бу<strong>е</strong>т создания<br />

экз<strong>е</strong>мпляра с указани<strong>е</strong>м им<strong>е</strong>ни файла.<br />

Его н<strong>е</strong> им<strong>е</strong><strong>е</strong>т смысла использовать для<br />

<strong>е</strong>диничных оп<strong>е</strong>раций (наприм<strong>е</strong>р, удал<strong>е</strong>ния<br />

или п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ния одного файла). Но для<br />

многочисл<strong>е</strong>нных оп<strong>е</strong>раций с одним файлом<br />

он бол<strong>е</strong><strong>е</strong> эфф<strong>е</strong>ктив<strong>е</strong>н, так как вам<br />

достаточно один раз п<strong>е</strong>р<strong>е</strong>дать имя этого<br />

файла. Выбор класса зависит только от<br />

конкр<strong>е</strong>тной ситуации. Грубо говоря, для<br />

<strong>е</strong>диничных оп<strong>е</strong>рации выбира<strong>е</strong>м класс<br />

F ile , а для посл<strong>е</strong>доват<strong>е</strong>льного р<strong>е</strong>дактирования<br />

— класс F i l e l n f o .<br />

г» Поч<strong>е</strong>му символы в слов<strong>е</strong><br />

1г<strong>е</strong>ка!» записываются как <strong>е</strong>диничны<strong>е</strong><br />

байты, в то вр<strong>е</strong>мя как для записи букв<br />

<strong>е</strong>вр<strong>е</strong>йского алфавита тр<strong>е</strong>бу<strong>е</strong>тся по два<br />

байта? И что это за символы FF FE<br />

в начал<strong>е</strong>?<br />

О! Вы увид<strong>е</strong>ли разницу м<strong>е</strong>жду двумя<br />

13K0 связанными кодировками Юникод.<br />

Латинским буквам, цифрам, знакам пр<strong>е</strong>пинания,<br />

а такж<strong>е</strong> ряду стандартных символов<br />

(фигурным скобкам, амп<strong>е</strong>рсандам и<br />

другим эл<strong>е</strong>м<strong>е</strong>нтам ваш<strong>е</strong>й клавиатуры)<br />

соотв<strong>е</strong>тствуют н<strong>е</strong>больши<strong>е</strong> знач<strong>е</strong>ния Юникод<br />

— от О до 127. (Аналогичная ситуация<br />

с символами кодировки ASCII.) Если файл<br />

сод<strong>е</strong>ржит только таки<strong>е</strong> символы, они выводятся<br />

в вид<strong>е</strong> одиночных байтов.<br />

Вс<strong>е</strong> усложня<strong>е</strong>тся, когда на сц<strong>е</strong>ну выходят<br />

символы с большими знач<strong>е</strong>ниями. В<strong>е</strong>дь<br />

байт мож<strong>е</strong>т им<strong>е</strong>ть знач<strong>е</strong>ни<strong>е</strong> от О до 255,<br />

и н<strong>е</strong> больш<strong>е</strong>. А вот в двух байтах уж<strong>е</strong><br />

можно хранить числа от О до 65,536 —<br />

в ш<strong>е</strong>стнадцат<strong>е</strong>ричной сист<strong>е</strong>м<strong>е</strong> счисл<strong>е</strong>ния<br />

это FFFF. Чтобы сообщить программ<strong>е</strong>,<br />

которая буд<strong>е</strong>т открывать файл, о наличии<br />

символов с высокими знач<strong>е</strong>ниями в начало<br />

файла пом<strong>е</strong>ща<strong>е</strong>тся зар<strong>е</strong>з<strong>е</strong>рвированная<br />

посл<strong>е</strong>доват<strong>е</strong>льность символов: FF FE. Это<br />

так называ<strong>е</strong>мая «отм<strong>е</strong>тка порядка байтов».<br />

Находя <strong>е</strong><strong>е</strong>, программа узна<strong>е</strong>т, что<br />

вс<strong>е</strong> символы закодированы в двух байтах.<br />

Поч<strong>е</strong>му эти символы называются<br />

отм<strong>е</strong>ткой порядка байтов?<br />

И; Помнит<strong>е</strong>, мы м<strong>е</strong>няли порядок<br />

ййтов? Знач<strong>е</strong>ни<strong>е</strong> буквы Shin в Юникод<br />

U+05E9 было записано в файл как Е9<br />

05. В<strong>е</strong>рнит<strong>е</strong>сь к коду, записывающ<strong>е</strong>му<br />

эти байты, и пом<strong>е</strong>няйт<strong>е</strong> тр<strong>е</strong>тий парам<strong>е</strong>тр<br />

наW r it e A llT e x t О : E n co d in g .<br />

B ig E n d ia n U n ico d e. Порядок сл<strong>е</strong>дования<br />

байтов стан<strong>е</strong>т прямым 05 Е9. Изм<strong>е</strong>нится<br />

и отм<strong>е</strong>тка порядка байтов: FE FF. Кстати,<br />

написанно<strong>е</strong> вами прилож<strong>е</strong>ни<strong>е</strong> Simple Text<br />

Editor мож<strong>е</strong>т читать как в прямом, так и в<br />

обратном порядк<strong>е</strong>!<br />

Символы с н<strong>е</strong>большими<br />

знач<strong>е</strong>ниями<br />

Юникод записываются<br />

но одному<br />

в байт, в то вр<strong>е</strong>мя<br />

как для записи символов<br />

Юникод выд<strong>е</strong>ляются<br />

два байта.<br />

Это использу<strong>е</strong>мм в -NET по<br />

ум олчлнм ю кодировка называ<strong>е</strong>тся<br />

U T F -8 . Д ля см<strong>е</strong>ны кодировки<br />

нужно п<strong>е</strong>р<strong>е</strong>дать м<strong>е</strong>тоду File.<br />

WriteAllTextO друго<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

446 глава 9


чт<strong>е</strong>ни<strong>е</strong> и запись файлов<br />

___ О тр<strong>е</strong>д актиру<strong>е</strong>м програм м у Б р а й а н а E x c u se M a n a g e r таким образом , чтобы она<br />

а Ж Н б Н К б н ач ала р аботать с двои чны м и ф айлам и, сод<strong>е</strong>рж ащ им и с<strong>е</strong>риали зован н ы <strong>е</strong> объ ­<br />

<strong>е</strong>кты E x c u s e .<br />

О<br />

О<br />

С<strong>е</strong>риализация класса Excuse<br />

П ом <strong>е</strong>тьт<strong>е</strong> класс E x c u s e а тр и б уто м [ S e r i a l i z a b l e ] . П о тр <strong>е</strong> б у<strong>е</strong>тся<br />

такж <strong>е</strong> доб авить с тр о ч к у u s i n g :<br />

u s i n g S y s t e m . R u n t i m e . S e r i a l i z a t i o n . F o r m a t t e r s . B i n a r y ;<br />

О тр<strong>е</strong>дактируйт<strong>е</strong> м<strong>е</strong>тод Excuse.Save О<br />

Т <strong>е</strong>п<strong>е</strong>рь м <strong>е</strong>тод S a v e о вм <strong>е</strong>сто и спользо вания о б ъ <strong>е</strong>кта S t r e a m W r i t e r ,^ ^ ^ <strong>е</strong> в о <strong>е</strong> Т л о в о<br />

д о л ж <strong>е</strong> н о тк р ы в а ть ф айл и с<strong>е</strong> р иализовы вать <strong>е</strong>го. Вам н у ж н о п о н я ть , ка-<br />

КИМ образом п р о и с х о д и т д <strong>е</strong>с<strong>е</strong>риализация т<strong>е</strong> кущ <strong>е</strong> го класса.<br />

О тр<strong>е</strong>дактируйт<strong>е</strong> м <strong>е</strong>тод Excuse.OpenFile О<br />

Вам п отр<strong>е</strong>бу<strong>е</strong>тся в р <strong>е</strong> м <strong>е</strong> н н ы й объ<strong>е</strong>кт E x c u s e , в к о т о р ы й буд<strong>е</strong>т п р о и с ­<br />

х о д и ть д<strong>е</strong>с<strong>е</strong>риализация, посл<strong>е</strong> ч <strong>е</strong> го <strong>е</strong> го поля с к о п и р у ю т с я в т<strong>е</strong> к у щ и й<br />

класс.<br />

Подсказка: Используйт<strong>е</strong><br />

возвраща<strong>е</strong>т<br />

ссылку на<br />

эт от ж <strong>е</strong> класс.<br />

Отр<strong>е</strong>дактируйт<strong>е</strong> срорму<br />

М ы больш <strong>е</strong> н<strong>е</strong> работа<strong>е</strong>м с т<strong>е</strong> к с т о в ы м и ф айлам и, п о это м у р а сш и р <strong>е</strong> н и <strong>е</strong> . t x t н<strong>е</strong> подходит.<br />

И зм <strong>е</strong> н и т<strong>е</strong> о к н а диалога, заданны <strong>е</strong> п о ум о л ч а н и ю им <strong>е</strong> на ф айлов и код п о и ска<br />

п а п к и , подстави в туда разр<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong> * . e x c u s e .<br />

Потрясающ<strong>е</strong>! В<strong>е</strong>сь код для<br />

сохран<strong>е</strong>ния и открытия оправданий находится внутри<br />

класса Excuse. Изм<strong>е</strong>н<strong>е</strong>ния вносились в класс, форму почти<br />

н<strong>е</strong> трогали. И форма работа<strong>е</strong>т вн<strong>е</strong> зависимости от того, как класс<br />

сохраня<strong>е</strong>т данны<strong>е</strong>. Она просто п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т имя (райла, и индюрмация<br />

сохраня<strong>е</strong>тся. ~ '<br />

Разум <strong>е</strong><strong>е</strong>тся! Код так л<strong>е</strong>гко р<strong>е</strong>дактиру<strong>е</strong>тся благодаря<br />

инкапсуляции класса.<br />

К ласс, в к о то р о м вс<strong>е</strong> в н у тр <strong>е</strong> н н и <strong>е</strong> о п <strong>е</strong> р а ц и и с к р ы т ы о т остальн<br />

о й ч а сти п р о гр а м м ы , а о т к р ы т ы м явля<strong>е</strong>тся то л ь к о т о , ч т о<br />

н<strong>е</strong>обхо д и м о , назы ва<strong>е</strong>тся инкапсулированным. В п р о гр а м м <strong>е</strong> ’<br />

Excuse IM anager ф орм а н<strong>е</strong> им <strong>е</strong><strong>е</strong>т и н ф о р м а ц и и о то м , ка ким<br />

образом о правдания с о х р а н я ю тс я в ф айл. О н а вс<strong>е</strong>го л и ш ь<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т им я ф айла классу, а у ж о н д<strong>е</strong>ла<strong>е</strong>т вс<strong>е</strong> н<strong>е</strong>обходим о<strong>е</strong>.<br />

И м <strong>е</strong> н н о п о это м у в ы см о гл и т а к л <strong>е</strong> гк о о тр <strong>е</strong> д а кти р о в а ть способ<br />

р а б о ты класса с ф айлам и. Ч <strong>е</strong>м лучш <strong>е</strong> и н ка п сул и р о в а н класс,<br />

т<strong>е</strong>м п р о щ <strong>е</strong> вам р аботать с н и м в будущ<strong>е</strong>м.<br />

ПoмнumeJ что инкапсуляция<br />

явля<strong>е</strong>тся<br />

одним из ч<strong>е</strong>тыр<strong>е</strong>х<br />

основных при -<br />

- знаков объ<strong>е</strong>ктноори<strong>е</strong>нтированного<br />

!лрограммирования?<br />

Вот наглядный прим<strong>е</strong>р<br />

того_, каким образом<br />

она обл<strong>е</strong>гча<strong>е</strong>т<br />

нам жизнь.<br />

дальш<strong>е</strong> > 447


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

1Н2НИ2<br />

<strong>е</strong> ш ш <strong>е</strong><br />

выглядит код программы Excuse Manager посл<strong>е</strong> р<strong>е</strong>дактирования.<br />

8 форм<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся отр<strong>е</strong>дактировать только три оп<strong>е</strong>ратора: два в обработчик<strong>е</strong><br />

событии кнопки Save и один для кнопки Open, они м<strong>е</strong>няют расилир<strong>е</strong>ни<strong>е</strong><br />

(раилоб и задают имя, под которым файлы сохраняются по умолчанию<br />

p r i v a t e v o i d s a v e _ C l i c k ( o b j e c t se n d e r , E v en tA rg s e) {<br />

// с у щ <strong>е</strong> с т в у ю щ и й к о д<br />

saveFileDialogl.Filter = "Excuse files (*.excuse)|*.excuse<br />

saveFileDialogl.FileName = description.Text + ".excuse";<br />

// с у щ <strong>е</strong> с т в у ю щ и й к о д<br />

}<br />

p r i v a t e v o id o p e n _ C lic k ( o b j e c t<br />

// с у щ <strong>е</strong> с т в у ю щ и й к о д<br />

openFileDialogl.Filter =<br />

"Excuse files (».excuse)I*.<br />

// с у щ <strong>е</strong> с т в у ю щ и й к о д<br />

}<br />

s e n d e r , E v en tA rg s e) {<br />

excuse|All files (*.*}!*.*")<br />

Это код вс<strong>е</strong>го класса Excuse.<br />

[ S e r i a l i z a b l e ]<br />

c l a s s E x cu se {<br />

p u b l i c s t r i n g D e s c r i p t i o n { g e t ; s e t ;<br />

p u b l i c s t r i n g R e s u lt s { g e t ; s e t ■ }<br />

p u b l i c D ateT im e L a stU se d { g e t ; s e t ;<br />

p u b l i c s t r i n g E x c u se P a th { g e t ; s e t ;<br />

p u b l i c E x cu se 0 {<br />

E x c u se P a th =<br />

}<br />

p u b l i c E x c u s e ( s t r i n g e x c u se P a th )<br />

O p e n F ile ( e x c u s e P a t h ) ;<br />

}<br />

All files<br />

( * . * ) I* .* » ;<br />

Ч д т и с ч о л о з з к » « «<br />

} 1 и о т о р л я онй<br />

p u b l i c Excuse(R andom random, s t r i n g f o l d e r ) {<br />

s t r i n g [ ] file N a m e s = D i r e c t o r y . G e t F i l e s ( f o l d e r , " * .e x c u se " )<br />

O p e n F ile ( f ile N a m e s [ r a n d o m .N e x t ( f ile N a m e s .L e n g t h ) ] ) ;<br />

}<br />

p r i v a t e v o i d O p e n F il e ( s t r in g e x c u se P a th ) {<br />

t h i s .E x c u s e P a t h = e x c u s e P a th ;<br />

B in a r y F o r m a tte r f o r m a t t e r = new B in a r y F o r m a tte r () ;<br />

E x cu se tem p E xcuse;<br />

u s in g (Stream in p u t = F ile .O p e n R e a d ( e x c u s e P a t h ) ) {<br />

^ tem p E xcuse = ( E x c u s e ) f o r m a t t e r .D e s e r i a l iz e ( i n p u t )<br />

}<br />

D e s c r i p t i o n = t e m p E x c u s e .D e s c r ip t io n ;<br />

R e s u lt s = t e m p E x c u s e .R e s u lts ;<br />

L a stU se d = te m p E x c u se . L a stU sed ;<br />

{<br />

Конструктор, загружаюш,ий<br />

случайны<strong>е</strong><br />

оправдания, т<strong>е</strong>п<strong>е</strong>рь<br />

ищ<strong>е</strong>т расшир<strong>е</strong>ни<strong>е</strong><br />

.excuse вм<strong>е</strong>сто расшир<strong>е</strong>ния<br />

*.txt.<br />

p u b l i c v o i d S a v e ( s t r i n g file N a m e ) {<br />

B in a r y F o r m a tte r f o r m a t t e r = new B in a r y F o r m a tte r ( );<br />

u s in g (Stream o u tp u t = File.O per^Jjsifee (file N a m e ) ) {<br />

f o r m a t t e r . S e r i a l i z e (o u tp u t, ( t h i s ) ) ; у и a<br />

} ^ ------С - X Ключ<strong>е</strong>во<strong>е</strong> слово this т ут ф игуриj<br />

ру<strong>е</strong>т , так как тр<strong>е</strong>бу<strong>е</strong>тся с<strong>е</strong>риалы -<br />

зооать им<strong>е</strong>нно эт от класс.<br />

448 глава 9


1 0 о б | > а б о 1 ] [ 1 х а и с : 1 С Я 1 « ч ; <strong>е</strong> н и й<br />

Борьба с огн<strong>е</strong>м надо<strong>е</strong>да<strong>е</strong>т ^<br />

Программисты н<strong>е</strong> должны уподобляться пожарным.<br />

Вы ус<strong>е</strong>рдно работали, ш тудировали т<strong>е</strong>хнич<strong>е</strong>ски<strong>е</strong> руководства и након<strong>е</strong>ц<br />

достигли в<strong>е</strong>ршины: т<strong>е</strong>п<strong>е</strong>рь вы главны й програм м ист. Но<br />

вам до сих пор продолжают звонить с работы по ночам, потому что<br />

програм м а упала или работа<strong>е</strong>т н<strong>е</strong>правильно. Ничто так н<strong>е</strong> вы бива<strong>е</strong>т<br />

из кол<strong>е</strong>и, как н<strong>е</strong>обходимость устранять странны <strong>е</strong> ошибки... но<br />

благодаря обработк<strong>е</strong> исклю ч<strong>е</strong>ний вы смож<strong>е</strong>т<strong>е</strong> написать код, который<br />

сам буд<strong>е</strong>т разбираться с возможны ми пробл<strong>е</strong>м ами.


мобильны<strong>е</strong> программы, мобильны<strong>е</strong> пробл<strong>е</strong>мы<br />

Брайану ну>кнЬ1мобильны<strong>е</strong> опрабдания<br />

Н <strong>е</strong> д а вно Б р а й а н п<strong>е</strong>р<strong>е</strong>ш <strong>е</strong>л в м <strong>е</strong> ж д ународны й отд<strong>е</strong>л и т<strong>е</strong> п <strong>е</strong> р ь о н пут<strong>е</strong>ш <strong>е</strong>­<br />

ству<strong>е</strong>т п о вс<strong>е</strong>му миру. Н о <strong>е</strong>му п о-пр<strong>е</strong>ж н <strong>е</strong>м у п р и х о д и тс я оправды ваться,<br />

п о это м у о н уста н о вил н а п и са н н ую нам и п рогр а м м у на ноутбук.<br />

Г<br />

Старит<br />

о п я т ь и щ <strong>е</strong> т п о б о д<br />

сб<strong>е</strong>жать с работы<br />

Программу для<br />

г<strong>е</strong>н<strong>е</strong>раций оправданий<br />

установил на<br />

^ ґ ^ о у т б у к , и она<br />

ос<strong>е</strong>гда под рукой.<br />

Но программа н<strong>е</strong> работа<strong>е</strong>т!<br />

П о сл <strong>е</strong> щ <strong>е</strong>лчка н а к н о п к <strong>е</strong> R a n d o m Excuse (С лучайно<strong>е</strong> о п равдани<strong>е</strong>) п о ­<br />

явля<strong>е</strong>тся сообщ <strong>е</strong>ни<strong>е</strong> об ош и бк<strong>е</strong>. О п р а в д а н и я н<strong>е</strong> найд<strong>е</strong>ны ? К а к ж <strong>е</strong> так?<br />

ІЖШЄ Manager<br />

UnharidledetcefrtionhBsocainBdiiyotK-apf^c^jn. If you «Л*<br />

Corttwe. Л <strong>е</strong> ар(йс0*іоп wffl іщтог<strong>е</strong> We « w and rtlempt to oorthue. ff<br />

you eW t Оій, the aw^icatism w l dose immeSatdy.<br />

W ee was oijside the ixsunds of the atray.<br />

И<strong>е</strong>обработанно<strong>е</strong><br />

и с к л ю ч <strong>е</strong> н и <strong>е</strong> ... эту<br />

пробл<strong>е</strong>му МЫ н<strong>е</strong><br />

учли.<br />

0 Ш<br />

450 глава 10


Возьми в руку карандаш<br />

обработка исключ<strong>е</strong>ний<br />

Вот прим<strong>е</strong>р н<strong>е</strong>работающ<strong>е</strong>го кода. Справа вы видит<strong>е</strong> сообщ<strong>е</strong>ния о пяти<br />

исключ<strong>е</strong>ниях. Укажит<strong>е</strong>, каки<strong>е</strong> строки кода стали причиной появл<strong>е</strong>ния<br />

этих сообщ<strong>е</strong>ний.<br />

p u b l i c s t a t i c v o i d B e e P r o c e s s o r {) {<br />

o b j e c t myBee = new H o n ey B ee( 3 6 .5 , " Z ip p o" );<br />

f l o a t howMuchHoney = (flo a t)m y B e e ;<br />

H oneyBee a n o th er B e e = new H o n ey B ee( 1 2 .5 , "Buzzy")<br />

d o u b le beeName = d o u b l e . P a rse(a n o th er B e e.M y N a m e);<br />

М <strong>е</strong> т о Э dowW e.ParseC'SZ )<br />

CO зн(яч<strong>е</strong>нм<strong>е</strong>м 32..<br />

d o u b le t o ta lH o n e y = 3 6 .5 + 1 2 .5 ;<br />

s t r i n g beesW eCanFeed =<br />

f o r ( i n t 1 = 1 ; i < ( i n t ) t o ta lH o n e y ; i+ + ) {<br />

}<br />

beesW eCanFeed += i . T o S t r i n g ( );<br />

f l o a t f =<br />

f l o a t . P a rse(b ee sW e C a n F e ed );<br />

i n t d r o n e s = 4;<br />

i n t q u een s = 0 ;<br />

i n t d ro n esP erQ u een = d r o n e s / q u ee n s;<br />

a n o th er B e e = n u l l ;<br />

i ^ NullReferenceException was unhandled<br />

; \ OvertlowException was unhandled ( J<br />

Vdue was ather too large or too sma# for a Single.<br />

I Object refererrce not set to m hstance o f an object<br />

t\ I nvaHdCastExceptlon was unhandled<br />

у / i f (d ron esP erQ u een < 10) {j SpecifledcastisnotvaW.<br />

[ an oth erB ee.D oM yJob O ;<br />

\ '<br />

\ Присво<strong>е</strong>ни<strong>е</strong><br />

\ ссылк<strong>е</strong><br />

знач<strong>е</strong>ния nul!<br />

означа<strong>е</strong>т^ что<br />

она никуда н<strong>е</strong><br />

в<strong>е</strong>д<strong>е</strong>т.<br />

i<br />

DivldeBvZeroException was unhandled<br />

1 Attempted to dMde by zero.<br />

Troubleshooting tips;<br />

Ea!s.§...M§_..!b§..Yalue,of.^e je n o [riia to [Js not г<strong>е</strong>го<br />

Get general help for thiis exception,<br />

, -v'<br />

Search for more Help Otiine,,.<br />

FomiatException was unhandled<br />

I Input string was not in a correct format<br />

Troubleshooting tips;<br />

[Make sure your..m e#gia!3 u m e n t ^ e Jn,,tii^<br />

When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object,<br />

Get general help for this exception.<br />

j Search for more Help Online,,.<br />

дальш<strong>е</strong> > 451


вопр<strong>е</strong>ки правилам<br />

Возьми в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот каки<strong>е</strong> строки кода стали причиной<br />

появл<strong>е</strong>ния сообщ <strong>е</strong>ний об ошибках.<br />

o b j e c t myBee = new H o n ey B ee( 3 6 .5 , " Z ip p o" );<br />

f l o a t howMuchHoney = (flo a t)m y B e e ;<br />

клнзч<strong>е</strong>нмм InvalidCastBxception.<br />

t l \ InvafidCastException was unharKfled<br />

Spedfied cast is not vatel.<br />

H oneyBee a n o th e r B e e = new H o n ey B ee( 1 2 .5 ,<br />

"Buzzy")<br />

d o u b le beeName = d o u b le . P a rse(a n o th er B e e.M y N a m e);<br />

н у ж н о п<strong>е</strong>р<strong>е</strong>дать<br />

6 опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нном форма-<br />

'лл<strong>е</strong>. При этом м<strong>е</strong>тод н<strong>е</strong> зна-<br />

, <strong>е</strong>т, как пр<strong>е</strong>образовать строки<br />

Виггу в число. Это и становится<br />

о С Г л сообщ <strong>е</strong>ниГ<br />

.1 \ FwmatEKceptlQn was unhancRed<br />

Input string was not h a correct format<br />

Troubleshooting tips;<br />

I '—....... ............ — .-------------------- :—<br />

j When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object<br />

•I^Get general help for this except]on,<br />

m<br />

v<br />

Search for more Help O rin e ..,<br />

d o u b le t o ta lH o n e y = 3 6 .5 + 1 2 .5 ;<br />

s t r i n g beesW eCanFeed = "";<br />

f o r ( i n t i = 1; i < ( in t ) t o ta lH o n e y ; i+ + ) {<br />

beesW eCanFeed += i . T o S t r i n g ();<br />

Ц и к л for созда<strong>е</strong>т строку beesVJeCanFeed.<br />

сод<strong>е</strong>ржаилцю число, которо<strong>е</strong> состоит<br />

бол<strong>е</strong><strong>е</strong> ‘^<strong>е</strong>Т и з 6 0<br />

float н<strong>е</strong>возможно присвоить ст м ь<br />

больило<strong>е</strong> число, им<strong>е</strong>нно поэтому мы<br />

видим исключ<strong>е</strong>ни<strong>е</strong> OverflowException.<br />

}<br />

f l o a t f = f l o a t . P a rse(b ee sW e C a n F e ed );<br />

OverflowException was uniiandled<br />

Vakje was either too large or too smd for a Single.<br />

Разум<strong>е</strong><strong>е</strong>тся, вс<strong>е</strong> эти исключ<strong>е</strong>ния<br />

появляются по оч<strong>е</strong>р<strong>е</strong>ди, программа<br />

выводит п<strong>е</strong>рво<strong>е</strong> из них и останавлива<strong>е</strong>тся.<br />

Второ<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> вы мож<strong>е</strong>т<strong>е</strong> увид<strong>е</strong>ть,<br />

только посл<strong>е</strong> того как исправит<strong>е</strong> ошибку,<br />

прив<strong>е</strong>дшую к п<strong>е</strong>рвому исключ<strong>е</strong>нию.<br />

452 глава 10


обработка исключ<strong>е</strong>ний<br />

i n t d r o n e s = 4;<br />

i n t q u ee n s = 0 ;<br />

i n t d ro n esP erQ u een = d r o n e s / q u ee n s;<br />

Увид<strong>е</strong>ть тако<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong><br />

об ошибк<strong>е</strong> оч<strong>е</strong>нь л<strong>е</strong>гко.<br />

Достаточно под<strong>е</strong>лить<br />

любую п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную на ноль.<br />

[ Ж MwkleByZeroException was unhandled<br />

Attempted to dvide by zero.<br />

Troubleshooting tips;<br />

Make sure the value o f the denom inator is no t zero before perform ing a division operation ,.<br />

Get general help for this exception.<br />

Search for more Help O nlne.,,<br />

i<br />

Чтобы пр<strong>е</strong>дотвратить появл<strong>е</strong>ни<strong>е</strong> ошибки, до- U \<br />

статочно пров<strong>е</strong>рить знач<strong>е</strong>ни<strong>е</strong> парам<strong>е</strong>тра queens, |<br />

п<strong>е</strong>р<strong>е</strong>д т <strong>е</strong> м как д<strong>е</strong>лить на н<strong>е</strong>го п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную drones.<br />

a n o th e r B e e = n u l l ;<br />

i f (d ron esP erQ u een


арахисовая карам<strong>е</strong>ль<br />

Объ<strong>е</strong>кт Exception<br />

И та к , вы узнали, ка ким образом .N E T сообщ а<strong>е</strong>т вам,<br />

ч т о с п р о гр а м м о й ч то -то н<strong>е</strong> так, — это и с к л ю ч <strong>е</strong> ­<br />

н и я (e x c e p tio n ). П р и и х п о я в л <strong>е</strong> н и и созда<strong>е</strong>тся объ<strong>е</strong>кт,<br />

к о т о р ы й назы ва<strong>е</strong>тся, ка к н <strong>е</strong> сл о ж н о догадаться.<br />

E x c e p t i o n .<br />

П р<strong>е</strong>дставьт<strong>е</strong> м ассив из ч <strong>е</strong> т ы р <strong>е</strong> х эл<strong>е</strong>м <strong>е</strong>нтов. А т<strong>е</strong> п <strong>е</strong> р ь<br />

п о п ы та й т<strong>е</strong> с ь п о л уч и ть д оступ к эл<strong>е</strong>м <strong>е</strong>нту н ом <strong>е</strong>р ш <strong>е</strong>стнадцать<br />

(с и н д <strong>е</strong> ксом 15, та к ка к о тсч <strong>е</strong> т в<strong>е</strong>д<strong>е</strong>тся с нуля):<br />

int[] апАггау = {З, 4 , 1 ,<br />

i n t aValue = апАггау[1 5 ];<br />

11};<br />

Оч<strong>е</strong>видно,<br />

что это<br />

ошибочный<br />

код.<br />

ис-клю-ч<strong>е</strong>-ни<strong>е</strong>, сущ.<br />

ч<strong>е</strong>лов<strong>е</strong>к или в<strong>е</strong>щь, выдающи<strong>е</strong>ся<br />

из общ<strong>е</strong>го ряда,<br />

н<strong>е</strong> подчиняющи<strong>е</strong>ся правилам.<br />

<strong>Дж</strong>им н<strong>е</strong>навидит<br />

арахисово<strong>е</strong> масло, но д<strong>е</strong>ла<strong>е</strong>т<br />

исключ<strong>е</strong>ни<strong>е</strong> для конф<strong>е</strong>т<br />

от К<strong>е</strong>на.<br />

При возникнов<strong>е</strong>нии<br />

1ясключ<strong>е</strong>ния созда<strong>е</strong>тся ^<br />

объ<strong>е</strong>кт, сод<strong>е</strong>ржаш,ий<br />

св<strong>е</strong>д<strong>е</strong>ния об ошибк<strong>е</strong>.<br />

■КТ Ехс«'^<br />

Detail<br />

Д л ^ просмотра подробной<br />

информации щ<strong>е</strong>лкнит<strong>е</strong><br />

на строчк<strong>е</strong> View Detail 6 окн<strong>е</strong><br />

с сообщ<strong>е</strong>ни<strong>е</strong>м о н<strong>е</strong>обработанном<br />

исключ<strong>е</strong>нии.<br />

ф<br />

<strong>е</strong> строк<strong>е</strong> Message<br />

обьясня<strong>е</strong>тсй смысл<br />

ошибки, а такж<strong>е</strong><br />

со Э <strong>е</strong> р ж и тся список в<strong>е</strong><strong>е</strong>к<br />

обращ<strong>е</strong>ний к памяти,<br />

к событию,<br />

ставш<strong>е</strong>му причинои<br />

ошибки.<br />

_____<br />

Exception snapshot<br />

л System.Ind€3cOutDffengeException {"Ind©( was outside the bounds of the array."} |<br />

[System,b\dexOtJtOfRengeException] {"Index was outside the bounds of the array,”} 1<br />

^ Data<br />

{System.Col!ectior\s.ListDictiDnaf>^nternal}<br />

HefpLink<br />

nutt<br />

Inr>erExceptior><br />

nuff<br />

■ ытзт H Index was outside the bounds of the array.<br />

Source<br />

Broken Code Exceptions<br />

StackTrace<br />

at Broken_Code_Excepttons.Program.BeeProcessor1<br />

i> TargetSite {Void BeeProcessorO}<br />

...J<br />

.N E T созда<strong>е</strong>т объ<strong>е</strong>кт, ч т о б ы п р <strong>е</strong> д о ставить вам и н ф о р м а ц и ю об ош и б к<strong>е</strong> , ставш <strong>е</strong>й п р и ч и н о й и с кл ю ч <strong>е</strong> н и я .<br />

М о ж <strong>е</strong> т потр <strong>е</strong> б о ваться р <strong>е</strong> д а кти р о в а н и <strong>е</strong> кода и л и д р уги <strong>е</strong> изм <strong>е</strong>н<strong>е</strong>ния.<br />

В д а н ном случа<strong>е</strong> и с к л ю ч <strong>е</strong> н и <strong>е</strong> IndexOutOfRangeException указы ва<strong>е</strong>т на п о п ы тк у о б р а ти ться к эл<strong>е</strong>м <strong>е</strong>нту<br />

м ассива с н<strong>е</strong>сущ<strong>е</strong>ствуюыцим инд<strong>е</strong>ксом . К р о м <strong>е</strong> т о го , вы зна<strong>е</strong>т<strong>е</strong>, в каком м<strong>е</strong>ст<strong>е</strong> п р о гр а м м ы возн икл а<br />

пробл<strong>е</strong>м а. То <strong>е</strong>сть вы м ож <strong>е</strong>т<strong>е</strong> л <strong>е</strong> гко лока л изовать <strong>е</strong><strong>е</strong> даж <strong>е</strong> в случа<strong>е</strong> о ч <strong>е</strong> н ь д л и н н о го кода.<br />

454 глава 10


обработка исключ<strong>е</strong>ний<br />

Чаапо<br />

з а д а в а <strong>е</strong> м ы <strong>е</strong><br />

Borij=»oc:bi<br />

Поч<strong>е</strong>му исключ<strong>е</strong>ний так много?<br />

! Сущ<strong>е</strong>ству<strong>е</strong>т много способов сд<strong>е</strong>лать ошибку. В случа<strong>е</strong><br />

оНщ<strong>е</strong>й формулировки («Пробл<strong>е</strong>ма в строчк<strong>е</strong> 37») сложно<br />

понять смысл пробл<strong>е</strong>мы. Ошибку прощ<strong>е</strong> исправить, когда<br />

точно зна<strong>е</strong>шь, в ч<strong>е</strong>м она заключа<strong>е</strong>тся.<br />

Б<br />

• Так что ж<strong>е</strong> тако<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong>?<br />

Q ; Это объ<strong>е</strong>кт, который .NET созда<strong>е</strong>т в случа<strong>е</strong> возникнов<strong>е</strong>ния<br />

пробл<strong>е</strong>м. Впроч<strong>е</strong>м, вы и сами мож<strong>е</strong>т<strong>е</strong> создавать таки<strong>е</strong><br />

объ<strong>е</strong>кты (об этом мы поговорим чуть позж<strong>е</strong>).<br />

Что? Это объ<strong>е</strong>кты?<br />

^ ! Да, исключ<strong>е</strong>ни<strong>е</strong> — это объ<strong>е</strong>кт. Свойства объ<strong>е</strong>кта сообщают<br />

вам информацию об исключ<strong>е</strong>нии. Наприм<strong>е</strong>р, свойство<br />

M e s s a g e — ЭТО строка вида «Указанно<strong>е</strong> присво<strong>е</strong>ни<strong>е</strong> н<strong>е</strong>осущ<strong>е</strong>ствимо»<br />

или «Слишком большо<strong>е</strong> или слишком мал<strong>е</strong>нько<strong>е</strong><br />

знач<strong>е</strong>ни<strong>е</strong> для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных данного типа», которая появля<strong>е</strong>тся<br />

во всплывающ<strong>е</strong>м окн<strong>е</strong>. Вам да<strong>е</strong>тся максимум возможной<br />

информации о том, что им<strong>е</strong>нно происходит при выполн<strong>е</strong>нии<br />

оп<strong>е</strong>ратора, который стал причиной исключ<strong>е</strong>ния.<br />

К сожал<strong>е</strong>нию я вс<strong>е</strong> равно н<strong>е</strong> понял, зач<strong>е</strong>м нужно<br />

тако<strong>е</strong> колич<strong>е</strong>ство исключ<strong>е</strong>ний?<br />

Q ; Потому что способов н<strong>е</strong>корр<strong>е</strong>ктной работы кода в<strong>е</strong>лико<strong>е</strong><br />

множ<strong>е</strong>ство. Сущ<strong>е</strong>ствуют ситуации, в которых код просто<br />

п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т работать. Н<strong>е</strong> зная, что стало причиной, устранить<br />

пробл<strong>е</strong>му крайн<strong>е</strong> сложно. Создавая разны<strong>е</strong> исключ<strong>е</strong>ния,<br />

.NET да<strong>е</strong>т вам информацию, позволяющую отсл<strong>е</strong>дить ошибку<br />

и исправить <strong>е</strong><strong>е</strong>.<br />

То <strong>е</strong>сть исключ<strong>е</strong>ния придуманы, чтобы помочь<br />

пользоват<strong>е</strong>лям?<br />

0 ; Да! Большинство пользоват<strong>е</strong>л<strong>е</strong>й расстраиваются при<br />

вид<strong>е</strong> сообщ<strong>е</strong>ния об исключ<strong>е</strong>нии. Но эти сообщ<strong>е</strong>ния нужно<br />

воспринимать как помощь в отсл<strong>е</strong>живании ошибок.<br />

Правда ли, что появл<strong>е</strong>ни<strong>е</strong> исключ<strong>е</strong>ния вовс<strong>е</strong> н<strong>е</strong><br />

означа<strong>е</strong>т, что я сд<strong>е</strong>лал что-то н<strong>е</strong> так?<br />

^ ; Правда. Иногда данны<strong>е</strong> в<strong>е</strong>дут с<strong>е</strong>бя н<strong>е</strong> так, как вы<br />

ожида<strong>е</strong>т<strong>е</strong>, наприм<strong>е</strong>р, можно написать м<strong>е</strong>тод, который буд<strong>е</strong>т<br />

работать с массивом иной длины, ч<strong>е</strong>м изначально пр<strong>е</strong>дполагалось.<br />

Сл<strong>е</strong>ду<strong>е</strong>т помнить, что пользоват<strong>е</strong>ли д<strong>е</strong>йствуют<br />

н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>мым образом. Благодаря исключ<strong>е</strong>ниям<br />

программы н<strong>е</strong> останавливаются в н<strong>е</strong>типичных ситуациях,<br />

а продолжают работу.<br />

Посл<strong>е</strong> сообщ<strong>е</strong>ний об ошибках стало ясно, что код<br />

на пр<strong>е</strong>дыдущ<strong>е</strong>й страниц<strong>е</strong> работать н<strong>е</strong> буд<strong>е</strong>т. Вс<strong>е</strong>гда ли<br />

исключ<strong>е</strong>ния позволяют понять, что происходит?<br />

^ ! к сожал<strong>е</strong>нию, иногда локализовать пробл<strong>е</strong>му, просто<br />

посмотр<strong>е</strong>в на код, н<strong>е</strong>возможно. Поэтому в ИСР сущ<strong>е</strong>ству<strong>е</strong>т<br />

отладчик. Он выполня<strong>е</strong>т программу строчка за строкой,<br />

оп<strong>е</strong>ратор за оп<strong>е</strong>ратором, показыва<strong>е</strong>т мгнов<strong>е</strong>нно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

каждой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной и каждого поля. Это позволя<strong>е</strong>т обнаружить,<br />

гд<strong>е</strong> им<strong>е</strong>нно код работа<strong>е</strong>т н<strong>е</strong> так, как вы пр<strong>е</strong>дполагали.<br />

Исключ<strong>е</strong>ния помогают<br />

обнаружить и исправить<br />

код, который работа<strong>е</strong>т н<strong>е</strong><br />

так, как вы думали.<br />

дальш<strong>е</strong> > 455


никто н<strong>е</strong> ожидал, что...<br />

Код Брайана работа<strong>е</strong>т н<strong>е</strong> так, как пр<strong>е</strong>дполагалось<br />

К о гд а м ы п и са л и п р о гр а м м у для п о и с к а о п р а вданий,<br />

н и к т о н<strong>е</strong> пр<strong>е</strong>дполагал, ч т о пользоват<strong>е</strong>ль н а ч н <strong>е</strong> т и с­<br />

кать оправдания в п усто й папк<strong>е</strong>.<br />

О П о сл <strong>е</strong> п<strong>е</strong>р<strong>е</strong>н<strong>е</strong>с<strong>е</strong> н и я п р о гр а м м ы Excuse M a n a g e r на ноутб ук, она стала<br />

ссы латься на пустую папку. В и т о г<strong>е</strong> щ <strong>е</strong>лчок на кн о п к <strong>е</strong> R a n d o m п р и в<strong>е</strong>л<br />

к п о я в л <strong>е</strong> н и ю о к н а с со общ <strong>е</strong>ни<strong>е</strong>м об н <strong>е</strong> о б р а б о та н н о м и с к л ю ч <strong>е</strong> н и и :<br />

Excuse M anager<br />

©<br />

IW ieidedare^itiw hasoccunBdhyoiffappteatton. fyoucW c<br />

Cortmue. the вдрИсайда igrasne this w w aid Л<strong>е</strong>пфі to conttiue. tf<br />

you d c k ОЛ. tfie адЛсгйоп чЛ dose іпта<strong>е</strong>сіій<strong>е</strong>іу.<br />

W e t was w ia d e Йш boimds trf the апау.<br />

Mato<br />

□<br />

Ccrtm je а л<br />

О О к н о сообщ а<strong>е</strong>т, ч т о инд<strong>е</strong>кс вы ш <strong>е</strong>л за гр а н и ц ы массива. П о с м о тр и м на<br />

код для о б р а б о тчика с о б ы т и й к н о п к и R a n d o m Excuse:<br />

p r i v a t e v o id r a n d o m E x c u s e _ C lic k (o b je c t se n d e r , E v en tA rg s e) {<br />

i f (C heckC hanged0 ) {<br />

c u r r e n tE x c u s e = new E xcu se(ran d om , s e l e c t e d F o l d e r ) ;<br />

U p d a t e F o r m ( f a ls e ) ;<br />

}<br />

}<br />

М а сси вов ту т н<strong>е</strong>т. З ато п р и п о м о щ и о д н о го из п <strong>е</strong> р <strong>е</strong> гр у ж <strong>е</strong> н н ы х к о н ­<br />

стр у к т о р о в созда<strong>е</strong>тся объ<strong>е</strong>кт E x c u s e . М о ж <strong>е</strong> т б ы ть, м ассив сод<strong>е</strong>рж и тся<br />

в код<strong>е</strong> э т о го констр укто ра?<br />

p u b l i c Excuse(R andom random, s t r i n g F o ld e r ) {<br />

}<br />

s t r i n g ! ] file N a m e s = D i r e c t o r y . G e t F i l e s ( F o l d e r , " * .e x c u s e<br />

O p e n F ile ( f ile N a m e s [ r a n d o m .N e x t ( f ile N a m e s .L e n g t h ) ] ) ;<br />

В о т оно! М ы н а ш л и<br />

м а с с и в . Д о л ж н о б ы т ь ,<br />

м ы п о п ы т а л и с ь у к а<br />

з а т ь и н д <strong>е</strong> к с , в ы х о д я -<br />

щым зй <strong>е</strong> г о гр а н и ц ы .<br />

456 глава 10


обработка исключ<strong>е</strong>ний<br />

О казы ва<strong>е</strong>тся, м <strong>е</strong>тод D i r e c t o r y . G e t F i l e s { ) , посл<strong>е</strong> т о г о ка к вы<br />

указали на пустую папку, стал возвращ ать п у с то й массив. И с п р а в и ть<br />

ситуацию м о ж н о , добавив п р о в <strong>е</strong> р к у с о д <strong>е</strong> р ж и м о го п а п к и п<strong>е</strong>р<strong>е</strong>д о т­<br />

к р ы ти <strong>е</strong> м ф айла. И вм <strong>е</strong>сто о к н а с и н ф о р м а ц и <strong>е</strong> й о н <strong>е</strong> о б р а б о та н н о м иск<br />

л ю ч <strong>е</strong> н и и буд<strong>е</strong>т п оявляться о к н о с сообщ <strong>е</strong>ни<strong>е</strong>м .<br />

p r i v a t e v o id r a n d o m E x c u s e _ C lic k (o b je c t s e n d e r , E ven tA rgs e) {<br />

s t r i n g [ ] file N a m e s = D i r e c t o r y . G e t F i l e s ( s e l e c t e d F o l d e r , " * . e x c u s e " );<br />

i f ( f ile N a m e s . L en g th == 0) {<br />

M essa g eB o x .S h o w (" P lea se s p e c i f y a f o l d e r w it h e x c u s e f i l e s i n i t '<br />

} e l s e {<br />

"No e x c u s e f i l e s fo u n d " );<br />

i f (C heckC hanged0 == tr u e ) {<br />

C u rren tE x cu se = new E x cu se(ra n d o m , F o ld er )<br />

U p d a t e F o r m ( f a ls e ) ;<br />

Пров<strong>е</strong>рив наличи<strong>е</strong><br />

Гайлов с. оправданиял/{14<br />

папк<strong>е</strong> ^ создания<br />

о 6 ъ <strong>е</strong> к т 1 ^ Е х с и 5 <strong>е</strong> , м ы<br />

пр<strong>е</strong>дотвраща<strong>е</strong>м<br />

появл<strong>е</strong>ни<strong>е</strong> сообщ<strong>е</strong>ния<br />

об исключ<strong>е</strong>нии —<br />

и вызыва<strong>е</strong>м окно<br />

с вспомогат<strong>е</strong>льной<br />

информаци<strong>е</strong>й.<br />

Я понял, что исключ<strong>е</strong>ния — это н<strong>е</strong> вс<strong>е</strong>гда<br />

плохо. Порой они указывают на ошибки, хотя<br />

в большинств<strong>е</strong> случа<strong>е</strong>в мн<strong>е</strong> просто сообща<strong>е</strong>тся,<br />

что вс<strong>е</strong> ид<strong>е</strong>т н<strong>е</strong> так, как я думал.<br />

И м <strong>е</strong>нно так. И склю ч<strong>е</strong>ния являю тся пол<strong>е</strong>зны м<br />

инструм <strong>е</strong>нтом , которы й находит код, работаю щ ий<br />

н<strong>е</strong>ож иданны м для нас способом .<br />

М н о ги <strong>е</strong> п р о гр а м м и с ты р а сстр а и в а ю тся , когда вп<strong>е</strong>рвы <strong>е</strong> сталки<br />

в а ю тся с и скл ю ч<strong>е</strong>ни<strong>е</strong>м . Н о и с к л ю ч <strong>е</strong> н и я м о ж н о п р <strong>е</strong> в р а ти ть<br />

в пр<strong>е</strong>им ущ <strong>е</strong>ство. В<strong>е</strong>дь о н и даю т к л ю ч к п о н и м а н и ю п р и ч и н н<strong>е</strong>в<br />

<strong>е</strong> р н о й р а б о ты кода. И вы м ож <strong>е</strong>т<strong>е</strong> разработать н о в ы й , бол<strong>е</strong><strong>е</strong><br />

уд а ч ны й с ц <strong>е</strong> н а р и й п р о гр а м м ы .<br />

дальш<strong>е</strong> ► 457


г<strong>е</strong>н<strong>е</strong>алогия исключ<strong>е</strong>ний<br />

исключ<strong>е</strong>ния насл<strong>е</strong>дуют о т объ<strong>е</strong>кта Exception<br />

в .N E T сущ <strong>е</strong>ству<strong>е</strong>т м н о ж <strong>е</strong> ств о и с к л ю ч <strong>е</strong> н и й . Т ак ка к м н о ги <strong>е</strong> из н и х схо ­<br />

ж и , им <strong>е</strong><strong>е</strong>т см ы сл го в о р и т ь о насл<strong>е</strong>довании. .N E T опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т б азовы й<br />

класс E x c e p t io n , о т к о т о р о го и насл<strong>е</strong>дую т вс<strong>е</strong> т и п ы и с к л ю ч <strong>е</strong> н и й .<br />

С во й ств о M e s s a g e э т о го класса с о д <strong>е</strong> р ж и т сообщ <strong>е</strong>ни<strong>е</strong> об ош и б к<strong>е</strong>. А свойство<br />

S ta c k T r a c e указы ва<strong>е</strong>т, ка ко й код в ы п о л н я л ся в м о м <strong>е</strong>нт п о я вл<strong>е</strong>ния<br />

и с к л ю ч <strong>е</strong> н и я и ч т о и м <strong>е</strong> н н о п р и в <strong>е</strong> л о к <strong>е</strong> го п о я в л <strong>е</strong> н и ю .<br />

М<strong>е</strong>тод ToStringO<br />

суммиру<strong>е</strong>т всю<br />

информацию<br />

из пол<strong>е</strong>й объ<strong>е</strong>кта<br />

и возвраща<strong>е</strong>т <strong>е</strong><strong>е</strong><br />

в вид<strong>е</strong> строки.<br />

Message<br />

StackTrace<br />

Exception<br />

GetBaseExceptionO<br />

ToStringO<br />

ции. Прочитав т<strong>е</strong>кст<br />

исключ<strong>е</strong>ния, вы<br />

мож<strong>е</strong>т<strong>е</strong> понять, что<br />

им<strong>е</strong>нно ид<strong>е</strong>т н<strong>е</strong> так.<br />

458 глава 10


контрольно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

Поиск ошибки 6 п|>ило}к<strong>е</strong>нии Excuse Manager с помощью отладчика<br />

В оспользу<strong>е</strong>м ся отл а д чи ком для п о и с к а о ш и б к и в п р и л о ж <strong>е</strong> н и и Excuse<br />

M anager. В п р <strong>е</strong>ды д ущ и х главах вам уж <strong>е</strong> п р и х о д и л о с ь р аботать с эти м<br />

и н стр ум <strong>е</strong> н то м , т<strong>е</strong>м н<strong>е</strong> м<strong>е</strong>н<strong>е</strong><strong>е</strong> р ассм о тр и м п роц<strong>е</strong>дуру п о ш а го в о , ч т о ­<br />

б ы н<strong>е</strong> у п усти ть н и к а к и х д<strong>е</strong>тал<strong>е</strong>й.<br />

^ I<br />

Отладьт<strong>е</strong><br />

Точка останова у обработчика событий кнопки Random<br />

В ы зна<strong>е</strong>т<strong>е</strong>, с ч <strong>е</strong> го начать: и с к л ю ч <strong>е</strong> н и <strong>е</strong> п о я в и л о сь п осл<strong>е</strong> щ <strong>е</strong>лчка на к н о п к <strong>е</strong> R a n d o m Excuse. П о э ­<br />

том у о т к р о й т <strong>е</strong> код э т о й к н о п к и , п о м <strong>е</strong> сти т<strong>е</strong> курсо р в п <strong>е</strong> рвую с тр о ч к у м <strong>е</strong>тода и в ы б <strong>е</strong> р и т<strong>е</strong> в м <strong>е</strong>ню<br />

D e b u g ком анду T oggle B re a k p o in t. З апустит<strong>е</strong> програм м у. В ы д <strong>е</strong>лит<strong>е</strong> пустую п а п ку и щ <strong>е</strong> л книт<strong>е</strong> на<br />

кн о п к <strong>е</strong> R a n d o m для п<strong>е</strong>р<strong>е</strong>хода к т о ч к <strong>е</strong> останова:<br />

^<br />

private void randoraExcuse_Click(object sender, EventArgs e)<br />

{<br />

Ш І fileWawes = Directory.6etFiles(selectedFolder, "‘.excuse“)<br />

if (fileNames.Length == #) у f ier4ames.Length == 0 true<br />

{<br />

}<br />

else<br />

{<br />

MessageBox.Sho«("Please specify a folder with excuse files in it",<br />

"No excuse files found”);<br />

if (CheckChanged0 )<br />

{<br />

}<br />

currentExcuse « new Excuse(random, selectedFolder)j<br />

UpdateForra(false);<br />

I<br />

-Нав<strong>е</strong>дит<strong>е</strong> указат<strong>е</strong>ль<br />

мыши<br />

на свойство<br />

f iie N a m e s .L e n g th ,<br />

а когда появится<br />

oкиoJ щ<strong>е</strong>лкнит<strong>е</strong><br />

на кнопк<strong>е</strong><br />

со значком<br />

скр<strong>е</strong>пки, чтобы<br />

<strong>е</strong>го зафиксировать.<br />

Обработчик собы тий и конструктор Excuse<br />

В оспользуйт<strong>е</strong>сь ком а н д о й S te p In t o для п р о с м о тр а п р о гр а м м ы с тр о ч к а за с т р о ч к о й . Т ак как вы<br />

вы д <strong>е</strong>лили пустую п а п к у вы увид и т<strong>е</strong> , ч т о посл<strong>е</strong> в ы п о л н <strong>е</strong> н и я д и р <strong>е</strong> к ти в ы M e s s a g e B o x .S h o w O<br />

п р о и з о й д <strong>е</strong> т вы ход из о б р а б о тч и ка с о б ы ти й .<br />

Т <strong>е</strong>п<strong>е</strong>рь в ы д <strong>е</strong> л и т <strong>е</strong> п а п ку, с о д <strong>е</strong> р ж а щ у ю ф а й л ы о п р а в д а н и й , и сн ова щ <strong>е</strong> л кн и т<strong>е</strong> на кн о п к <strong>е</strong><br />

R a n d o m . П о ш а го в о п р о с м о тр и т<strong>е</strong> код. (В ы д о л ж н ы пользоваться ф у н кц и <strong>е</strong> й Step In to , а н<strong>е</strong> Step<br />

Over, х о т я и им <strong>е</strong><strong>е</strong>т см ы сл о б о й т и м <strong>е</strong>тод C h e c k C h a n g e d ( ) .) П <strong>е</strong>р<strong>е</strong>д создани<strong>е</strong>м объ<strong>е</strong>кта E x c u s e<br />

уп равл<strong>е</strong>ни<strong>е</strong> буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дано к о н с т р у к т о р у О б о й д и т<strong>е</strong> п <strong>е</strong> р вую строчку, та к как в н <strong>е</strong> й зада<strong>е</strong>тся<br />

зн а ч<strong>е</strong>ни<strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й f i l e N a m e s va ria b le . Зат<strong>е</strong>м нав<strong>е</strong>дит<strong>е</strong> указат<strong>е</strong>ль м ы ш и на п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нную ,<br />

ч т о б ы увид <strong>е</strong>ть <strong>е</strong><strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

460 глава 10


обработка исключ<strong>е</strong>ний<br />

Работа с отладчиком<br />

П <strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м как добавлять о б р а б о тку и с к л ю ч <strong>е</strong> н и я , н у ж н о п о н я ть , каки<strong>е</strong><br />

и м <strong>е</strong> н н о о п <strong>е</strong> р а то р ы стали п р и ч и н о й <strong>е</strong>го п о я вл<strong>е</strong>ния. В этом вам п о м о ж <strong>е</strong> т<br />

в с т р о <strong>е</strong> н н ы й в И С Р о т л а д ч и к . Вам уж <strong>е</strong> п р и х о д и л о с ь им пользоваться, н о<br />

давайт<strong>е</strong> т<strong>е</strong> п <strong>е</strong> р ь рассм о тр и м <strong>е</strong> го п о д р о б н о . П о сл <strong>е</strong> <strong>е</strong>го запуска появля<strong>е</strong>тся<br />

пан<strong>е</strong>ль и н с тр у м <strong>е</strong> н то в с кн о п кам и . П о о ч <strong>е</strong> р <strong>е</strong> д и нав<strong>е</strong>дит<strong>е</strong> курсо р на каж дую<br />

из н и х и п о с м о тр и т<strong>е</strong> на р<strong>е</strong>зультат:<br />

Пан<strong>е</strong>ль инструм<strong>е</strong>нтов<br />

Debug появля<strong>е</strong>тся только<br />

в р<strong>е</strong>жим<strong>е</strong> отладки программы.<br />

Остановить отладку:<br />

выходит из р<strong>е</strong>жима<br />

отладки<br />

Продолжить:<br />

выполня<strong>е</strong>т программу<br />

до сл<strong>е</strong>дующ<strong>е</strong>й точки<br />

останова или конца<br />

Показать сл<strong>е</strong>дующий<br />

оп<strong>е</strong>ратор<br />

Bug пан<strong>е</strong>ли Debug 6 р<strong>е</strong>)ким<strong>е</strong> Expert<br />

Шаг с обходом: выполня<strong>е</strong>т<br />

сл<strong>е</strong>дующий оп<strong>е</strong>ратор. М<strong>е</strong>тоды<br />

выполняются как один<br />

оп<strong>е</strong>ратор<br />

‘л"} Ф «1 Сз % } Н<strong>е</strong>* -г<br />

Шаг с заходом: выполня<strong>е</strong>т<br />

сл<strong>е</strong>дующий оп<strong>е</strong>ратор.<br />

В м<strong>е</strong>тод<strong>е</strong> выполня<strong>е</strong>тся<br />

лучш<strong>е</strong> вс<strong>е</strong>го п<strong>е</strong>рвый<br />

оп<strong>е</strong>ратор<br />

Включа<strong>е</strong>т и выключа<strong>е</strong>т<br />

ш<strong>е</strong>стнадцат<strong>е</strong>ричный вывод<br />

Вывод: показыва<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

вс<strong>е</strong>х локальных п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных,<br />

которы<strong>е</strong> находятся в памяти<br />

Шаг с выходом: запуска<strong>е</strong>т<br />

вс<strong>е</strong> остальны<strong>е</strong> оп<strong>е</strong>раторы<br />

т<strong>е</strong>кущ<strong>е</strong>го м<strong>е</strong>тода и пр<strong>е</strong>рыва<strong>е</strong>т<br />

выполн<strong>е</strong>ни<strong>е</strong>, когд<strong>е</strong> они<br />

заканчиваются<br />

П о ум о л ч а н и ю V isu a l S tu d io 2010 Express н а хо д и тся в р<strong>е</strong>ж и м <strong>е</strong> Basic Settings, к о т о р ы й зам <strong>е</strong>чат<strong>е</strong>льно подх<br />

о д и т для н а ч и н а ю щ и х . Н о т<strong>е</strong> п <strong>е</strong> р ь давайт<strong>е</strong> п<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>м к р а сш и р <strong>е</strong> н н ы м парам <strong>е</strong>трам . Д ля э то го вы б <strong>е</strong> р и т<strong>е</strong><br />

в м <strong>е</strong>ню T o o ls ком анду S e ttin g s » E x p e rt S e ttin g s (п <strong>е</strong> р <strong>е</strong> хо д в д р уго й р <strong>е</strong> ж и м м о ж <strong>е</strong> т занять н <strong>е</strong> ко то р о <strong>е</strong><br />

вр<strong>е</strong>м я). П осл <strong>е</strong> э т о го на п ан<strong>е</strong>ли и н с тр у м <strong>е</strong> н то в D e b u g вы о б н а р уж и т<strong>е</strong> дв<strong>е</strong> н о в ы <strong>е</strong> к н о п к и :<br />

Пр<strong>е</strong>рвать вс<strong>е</strong>: пр<strong>е</strong>краща<strong>е</strong>т<br />

работу программы, как при<br />

достиж<strong>е</strong>нии точки останова<br />

П<strong>е</strong>р<strong>е</strong>запустить: останавлива<strong>е</strong>т<br />

работу программы и начина<strong>е</strong>т <strong>е</strong><strong>е</strong><br />

сначала<br />

Ш<strong>е</strong>стнадцат<strong>е</strong>ричный Вывод<br />

Н а ж м и т<strong>е</strong> H e x для в к л ю ч <strong>е</strong> н и я р<strong>е</strong>ж и м а ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч н о го вы вода и нав<strong>е</strong>дит<strong>е</strong> кур со р на лю б о <strong>е</strong> пол<strong>е</strong><br />

и л и п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нную . С нова щ <strong>е</strong> л кн и т<strong>е</strong> на к н о п к <strong>е</strong> для возвращ <strong>е</strong>ния в о б ы ч н ы й р<strong>е</strong>ж и м . П р <strong>е</strong> о б р а зо вани<strong>е</strong> знач<br />

<strong>е</strong> н и я в ш <strong>е</strong> стн а д ц а т<strong>е</strong> р и ч н ую сист<strong>е</strong>м у сч и сл <strong>е</strong> н и я буд<strong>е</strong>т осущ <strong>е</strong>ствл<strong>е</strong>но а вто м а ти ч<strong>е</strong>ски . В п р о ш л о й глав<strong>е</strong><br />

вы узнали, зач<strong>е</strong>м э то н уж но.<br />

¥ va(uel0 k3 sfb8 3 d9<br />

Это одно число, сл<strong>е</strong>ва<br />

в ш<strong>е</strong>стнадцат<strong>е</strong>ричной,------ ^<br />

дальш<strong>е</strong> * 459


обработка исключ<strong>е</strong>ний<br />

О Работа с окном W a tc h<br />

Щ <strong>е</strong> л к н и т <strong>е</strong> п р а в о й к н о п к о й м ы ш и н а п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й f i l e N a m e s и в ы б <strong>е</strong> р и т<strong>е</strong> команду<br />

Expression: ‘fileN am es’ » Add Watch. Зат<strong>е</strong>м щ<strong>е</strong>лкнит<strong>е</strong> на пустой строчк<strong>е</strong> под п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

fileN am es и вв<strong>е</strong>дит<strong>е</strong> r a n d o m .N e x t ( f i l e N a m e s . L e n g t h ) , ч т о б ы о тл адчик добавил<br />

к о н тр о л ь н о <strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. В о т ка к буд<strong>е</strong>т вы гляд<strong>е</strong>ть о к н о W atch для п а п к и с тр <strong>е</strong> м я ф айлам и<br />

о п р а в д а н и й (ко гд а п <strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная f i l e N a m e s им <strong>е</strong> <strong>е</strong>т д л и н у 3).<br />

Окно Watch использу<strong>е</strong>тся<br />

для воспроизв<strong>е</strong>д<strong>е</strong>ния^<br />

ситуации, прив<strong>е</strong>дыл<strong>е</strong>й ''<br />

к появл<strong>е</strong>нию исключ<strong>е</strong>ния-<br />

Мы начали с добавл<strong>е</strong>ния<br />

массива fileNames.<br />

W atch<br />

Füaäi' Value Type<br />

random,Next(fileNames.Length) j 2 int<br />

a<br />

П р исвоим п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной fileN am es пустой строковый массив<br />

О к н о W atch позволя<strong>е</strong>т м<strong>е</strong>нять знач<strong>е</strong>ния ото б р а ж а <strong>е</strong> м ы х п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы х и п ол<strong>е</strong>й. В ы даж <strong>е</strong> м о­<br />

ж <strong>е</strong>т<strong>е</strong> выполнять м<strong>е</strong>тоды и создавать новы<strong>е</strong> объ<strong>е</strong>кты, в э т и м ом <strong>е</strong>нты появля<strong>е</strong>тся значок<br />

( ® ) , ш;<strong>е</strong>лчок на к о то р о м п р и в о д и т к п о в то р н о м у в ы п о л н <strong>е</strong> н и ю с тр о к и . В<strong>е</strong>дь м <strong>е</strong>тод R a n d o m<br />

ка ж д ы й раз да<strong>е</strong>т д р уго й р<strong>е</strong>зультат.<br />

Д важды щ <strong>е</strong>лкнит<strong>е</strong> на строчк<strong>е</strong> f i l e N a m e s , ч то б ы вы д<strong>е</strong>лить т <strong>е</strong> к с т {s t r i n g [3 ] }. Зам<strong>е</strong>нит<strong>е</strong><br />

<strong>е</strong>го на new<br />

s t r i n g [ 0 ] . Тут ж <strong>е</strong> исч<strong>е</strong>зн<strong>е</strong>т квадратик со знаком «плюс» рядом с п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нной<br />

f i le N a m e s , так как т<strong>е</strong>п<strong>е</strong>рь э то т массив пуст. А рядом со стр о ч к о й r a n d o m . N e x t {) появится<br />

значок {Щ. Щ <strong>е</strong> л к н и т <strong>е</strong> на н<strong>е</strong>м, ч то б ы <strong>е</strong>щ<strong>е</strong> раз в ы п о л н и ть м<strong>е</strong>тод. О н долж <strong>е</strong>н в<strong>е</strong>рнуть 0.<br />

Так как источником<br />

пробл<strong>е</strong>мы<br />

явля<strong>е</strong>тся пустой<br />

массив fileNames,<br />

мы смод<strong>е</strong>лиру<strong>е</strong>м<br />

эту ситуацию<br />

в окн<strong>е</strong> Watch.<br />

W atch<br />

Name<br />

Value<br />

leNam es {string[0]} b !^ in § D<br />

Ф ra n d o m .N e x t{file M a m e s.L e n g th)<br />

int<br />

Этот значок<br />

иницииру<strong>е</strong>т<br />

повторно<strong>е</strong><br />

выполн<strong>е</strong>ни<strong>е</strong><br />

м<strong>е</strong>тода<br />

NextQ.<br />

^ Воссоздани<strong>е</strong> пробл<strong>е</strong>джой ситуации<br />

Д обавьт<strong>е</strong> в о тл адчик с тр о к у с о п <strong>е</strong> р а то р о м , к о т о р ы й стал п р и ч и н о й и с кл ю ч <strong>е</strong> н и я :<br />

f i l e N a m e s [ r a n d o m .N e x t ( f i l e N a m e s . L e n g t h ) ] . Э то в ы р а ж <strong>е</strong> н и <strong>е</strong> буд<strong>е</strong>т об считы в а ться<br />

в окн <strong>е</strong> W a tch... и вы ув и д и т<strong>е</strong> сообщ <strong>е</strong> н и <strong>е</strong> об и с к л ю ч <strong>е</strong> н и и . Сл<strong>е</strong>ва п о я в и тс я значок с в о скл и ­<br />

цат<strong>е</strong>льны м знаком , а в столбц<strong>е</strong> V alu e — т<strong>е</strong> к с т и с к л ю ч <strong>е</strong> н и я .<br />

Э т о т значок<br />

в окн<strong>е</strong> Watch<br />

сообш,а<strong>е</strong>т об<br />

обнаруж<strong>е</strong>нии<br />

исключ<strong>е</strong>ния.<br />

" Л<br />

Watch<br />

Name<br />

*: fiieName$<br />

# random .N extP eN am es.Lengti)<br />

^"^lieNam es[randQm .Next{f»eNames.Lengtti)]<br />

Value<br />

{sfringfOl}<br />

0<br />

Out ofbounds array index<br />

’Г □ X<br />

Type<br />

stringD<br />

Ф tnt<br />

sfring<br />

В ы в с <strong>е</strong> гд а м о ж <strong>е</strong> т <strong>е</strong> в о с п р о и з в <strong>е</strong> с т и с п о м о щ ь ю о т л а д ч и к а с и т у а ц и ю , с т а в ш у ю п р и ч и н о й<br />

п о я в л <strong>е</strong> н и я и с к л ю ч <strong>е</strong> н и я .<br />

дальш<strong>е</strong> > 461


сд<strong>е</strong>ла<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>рыв<br />

Часщо<br />

з а д а в а <strong>е</strong> м ы <strong>е</strong><br />

B o IlJ > o C b i<br />

Поч<strong>е</strong>му сообщ<strong>е</strong>ни<strong>е</strong> о н<strong>е</strong>обработанном<br />

исключ<strong>е</strong>нии, которо<strong>е</strong> получил<br />

Брайан, отлича<strong>е</strong>тся от мо<strong>е</strong>го?<br />

Q ; Запуская программу в ИСР, вы<br />

работа<strong>е</strong>т<strong>е</strong> из отладчика, который при<br />

обнаруж<strong>е</strong>нии исключ<strong>е</strong>ния пр<strong>е</strong>рыва<strong>е</strong>т<br />

выполн<strong>е</strong>ни<strong>е</strong> (как при нажатии кнопки<br />

Break АН или при вставк<strong>е</strong> точки останова).<br />

При этом появля<strong>е</strong>тся окно с сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

Это позволя<strong>е</strong>т иссл<strong>е</strong>довать объ<strong>е</strong>кт<br />

E x c e p tio n , а такж<strong>е</strong> поля и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

ваш<strong>е</strong>й программы, и понять, в ч<strong>е</strong>м им<strong>е</strong>нно<br />

состоит пробл<strong>е</strong>ма.<br />

Программа, с которой работал Брайан,<br />

была установл<strong>е</strong>на на <strong>е</strong>го компьют<strong>е</strong>р.<br />

Помнит<strong>е</strong>, вы д<strong>е</strong>лали это в глав<strong>е</strong> 1 для<br />

прилож<strong>е</strong>ния со списком контактов? Для<br />

запуска программы вн<strong>е</strong> ИСР достаточно<br />

построить р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>, то <strong>е</strong>сть получить<br />

исполня<strong>е</strong>мый файл, который находится в<br />

папк<strong>е</strong> b in /, влож<strong>е</strong>нной в папку про<strong>е</strong>кта.<br />

Посл<strong>е</strong> этого вы буд<strong>е</strong>т<strong>е</strong> вид<strong>е</strong>ть таки<strong>е</strong> ж<strong>е</strong><br />

окна с сообщ<strong>е</strong>ниями об исключ<strong>е</strong>ниях, как<br />

и Брайан.<br />

То <strong>е</strong>сть <strong>е</strong>сли программа работа<strong>е</strong>т<br />

вн<strong>е</strong> ИСР, с появл<strong>е</strong>ни<strong>е</strong>м сообщ<strong>е</strong>ния об<br />

исключ<strong>е</strong>нии <strong>е</strong><strong>е</strong> выполн<strong>е</strong>ни<strong>е</strong> просто<br />

останавлива<strong>е</strong>тся, и пользоват<strong>е</strong>ль нич<strong>е</strong>го<br />

н<strong>е</strong> мож<strong>е</strong>т сд<strong>е</strong>лать?<br />

Ql Да, программа останавлива<strong>е</strong>тся,<br />

столкнувшись с н<strong>е</strong>обработанным исключ<strong>е</strong>ни<strong>е</strong>м.<br />

Но в<strong>е</strong>дь нигд<strong>е</strong> н<strong>е</strong> сказано, что вс<strong>е</strong><br />

исключ<strong>е</strong>ния относятся к н<strong>е</strong>обработанным!<br />

О способах обработки исключ<strong>е</strong>ний и о том,<br />

каким образом создать программу б<strong>е</strong>з сообщ<strong>е</strong>ний<br />

о н<strong>е</strong>обработанных исключ<strong>е</strong>ниях,<br />

мы поговорим чуть поздн<strong>е</strong><strong>е</strong>.<br />

Как выбрать м<strong>е</strong>сто для точки<br />

останова?<br />

Q ; Это хороший вопрос, который, к сожал<strong>е</strong>нию,<br />

н<strong>е</strong> им<strong>е</strong><strong>е</strong>т однозначного отв<strong>е</strong>та.<br />

При появл<strong>е</strong>нии исключ<strong>е</strong>ний, им<strong>е</strong><strong>е</strong>т смысл<br />

начинать с оп<strong>е</strong>раторов, которы<strong>е</strong> стали их<br />

причиной. Но обычно пробл<strong>е</strong>ма гн<strong>е</strong>здится<br />

в пр<strong>е</strong>дьщущих строках кода, а исключ<strong>е</strong>ни<strong>е</strong><br />

явля<strong>е</strong>тся н<strong>е</strong> бол<strong>е</strong><strong>е</strong> ч<strong>е</strong>м посл<strong>е</strong>дстви<strong>е</strong>м,<br />

к прим<strong>е</strong>ру, оп<strong>е</strong>ратор, ставший причиной<br />

появл<strong>е</strong>ния исключ<strong>е</strong>ния «Д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> на<br />

ноль», мож<strong>е</strong>т использовать знач<strong>е</strong>ния, вычисл<strong>е</strong>нны<strong>е</strong><br />

д<strong>е</strong>сятком строк ран<strong>е</strong><strong>е</strong>. Поэтому<br />

отв<strong>е</strong>т на вопрос о м<strong>е</strong>ст<strong>е</strong> точки останова<br />

в каждом конкр<strong>е</strong>тном случа<strong>е</strong> буд<strong>е</strong>т<br />

отличаться. Но <strong>е</strong>сли вы пр<strong>е</strong>дставля<strong>е</strong>т<strong>е</strong><br />

принцип работы сво<strong>е</strong>го кода, пробл<strong>е</strong>мы с<br />

выбором м<strong>е</strong>ста н<strong>е</strong> буд<strong>е</strong>т.<br />

Любой м<strong>е</strong>тод можно запускать<br />

в окн<strong>е</strong> Watch?<br />

И ; Да, любы<strong>е</strong> корр<strong>е</strong>ктны<strong>е</strong> оп<strong>е</strong>раторы<br />

сд ут работать в окн<strong>е</strong> Watch. Даж<strong>е</strong> т<strong>е</strong>,<br />

которы<strong>е</strong> н<strong>е</strong> им<strong>е</strong><strong>е</strong>т смысла запускать. Запустит<strong>е</strong><br />

программу, пр<strong>е</strong>рвит<strong>е</strong> <strong>е</strong><strong>е</strong> выполн<strong>е</strong>ни<strong>е</strong><br />

и добавьт<strong>е</strong> в окно Watch строку: S y stem .<br />

T h r e a d in g .T h r e a d .S le e p (2000).<br />

(Как вы помнит<strong>е</strong>, этот м<strong>е</strong>тод вызыва<strong>е</strong>т<br />

двухс<strong>е</strong>кундную зад<strong>е</strong>ржку работы программы.)<br />

Использовать <strong>е</strong>го н<strong>е</strong>т смысла, но<br />

инт<strong>е</strong>р<strong>е</strong>сно посмотр<strong>е</strong>ть, что произойд<strong>е</strong>т: на<br />

дв<strong>е</strong> с<strong>е</strong>кунды, которы<strong>е</strong> занима<strong>е</strong>т выполн<strong>е</strong>ни<strong>е</strong><br />

этого м<strong>е</strong>тода, появится изображ<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>сочных часов. Так как м<strong>е</strong>тод s l e e p ()<br />

н<strong>е</strong> возвраща<strong>е</strong>т знач<strong>е</strong>ния, в окн<strong>е</strong> Watch<br />

появится сообщ<strong>е</strong>ни<strong>е</strong>. E x p r e s s io n h a s<br />

b e e n e v a lu a t e d and h a s no v a lu e ,<br />

информирующ<strong>е</strong><strong>е</strong> об отсутствии возвраща<strong>е</strong>мых<br />

знач<strong>е</strong>ний.<br />

у» То <strong>е</strong>сть я могу запустить в окн<strong>е</strong><br />

I /а!сЬ что-то, м<strong>е</strong>няющ<strong>е</strong><strong>е</strong> способ работы<br />

программы?<br />

0 ; Да! Пусть н<strong>е</strong> вс<strong>е</strong>гда, но зд<strong>е</strong>сь вы<br />

мож<strong>е</strong>т<strong>е</strong> влиять на кон<strong>е</strong>чный р<strong>е</strong>зультат<br />

работы программы. Бол<strong>е</strong><strong>е</strong> того, даж<strong>е</strong> нав<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

указат<strong>е</strong>ля мыши на поля внутри<br />

отладчика мож<strong>е</strong>т пом<strong>е</strong>нять пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

программы, так как при этом выполня<strong>е</strong>тся<br />

м<strong>е</strong>тод чт<strong>е</strong>ния свойства. И <strong>е</strong>сли<br />

этот м<strong>е</strong>тод зада<strong>е</strong>т како<strong>е</strong>-то знач<strong>е</strong>ни<strong>е</strong>, оно<br />

п<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>т в программу. Тако<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

д<strong>е</strong>ла<strong>е</strong>т р<strong>е</strong>зультаты отладки н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>мыми.<br />

Программисты в шутку называют<br />

таки<strong>е</strong> р<strong>е</strong>зультаты г<strong>е</strong>йз<strong>е</strong>нб<strong>е</strong>ргскими (эта<br />

шутка понятна только физикам и котам<br />

в ящик<strong>е</strong>).<br />

Зацущ<strong>е</strong>нная в ИСР<br />

профамма при<br />

появл<strong>е</strong>нии н<strong>е</strong>обработанных<br />

исключ<strong>е</strong>ний<br />

пр<strong>е</strong>рыва<strong>е</strong>тся,<br />

как при достиж<strong>е</strong>нии<br />

точки останова.<br />

462 глава 10


обработка исключ<strong>е</strong>ний<br />

А код Вс<strong>е</strong> раВно н<strong>е</strong> работа<strong>е</strong>т...<br />

Б райан усп <strong>е</strong>ш но пользовался Excuse M a n a g e r п р и н а л и ч и и п а п ­<br />

ки , н а п о л н <strong>е</strong> н н о й ф айлам и с оправданиям и , к о то р у ю о н создал<br />

во вр<strong>е</strong>м я н а п и сания п р о гр а м м ы , н о о н забыл п р о эту папку и<strong>е</strong>с<strong>е</strong><br />

риализаци<strong>е</strong>й п р о гр а м м ы . И в о т ч т о случилось....<br />

П р и л о ж <strong>е</strong> н и <strong>е</strong> Б л о к н о т п озволя<strong>е</strong>т воссоздать ф айлы с о правданиям и. П <strong>е</strong> р ­<br />

вая стр о к а — о правдани<strong>е</strong>, в то р а я — р<strong>е</strong>зультат <strong>е</strong> го п р и м <strong>е</strong> н <strong>е</strong> н и я , тр <strong>е</strong> тья —<br />

дата <strong>е</strong>го посл<strong>е</strong>дн<strong>е</strong>го исп о л ьзо вания ( « 1 0 /4 /2 0 0 7 12:08:13 Р М »).<br />

© В ы зо в и т<strong>е</strong> Excuse M anager и о т к р о й т <strong>е</strong> оправдани<strong>е</strong>. П р и п о я в л <strong>е</strong> н и и и с к л ю ч <strong>е</strong> н и я ш ;<strong>е</strong>лкнит<strong>е</strong><br />

на к н о п к <strong>е</strong> D etails. О б р а ти т<strong>е</strong> вним а н и <strong>е</strong> н а ст<strong>е</strong>к вызова - и м <strong>е</strong> н н о та к назы ва<strong>е</strong>тся м <strong>е</strong>тод, вы ­<br />

з ы в а ю щ и й д р уго й м <strong>е</strong>тод, к о т о р ы й , в свою оч<strong>е</strong>р<strong>е</strong>дь, то ж <strong>е</strong> вы зы ва<strong>е</strong>т м <strong>е</strong>тод и т. д.<br />

Программа сообща<strong>е</strong>т, что исключ<strong>е</strong>ни<strong>е</strong> появля<strong>е</strong>тся при<br />

с<strong>е</strong>риализации. Можно ли из подробного описания поняты.<br />

Excuse M anager " какая строка кода явля<strong>е</strong>тся причиной <strong>е</strong>го появл<strong>е</strong>ния?<br />

IMimidted<br />

Cortinue, the<br />

ушсЛЛОіЛ.Л<strong>е</strong><br />

Index was outside<br />

* * * * * * * * * * * * * * Exception Text * * * * * * * * * * * * * *<br />

System.Runtime.Serialization.SerializationException: End of Stream encountered before parsing<br />

was completed.<br />

atSystem.Runtime.Serialization.Formatters.Binary._BinaryParser.Run()<br />

пробл<strong>е</strong>ма с классом<br />

BinaryFormatter.<br />

Это пр<strong>е</strong>дполож<strong>е</strong>ни<strong>е</strong><br />

им<strong>е</strong><strong>е</strong>т смысл,<br />

так как прилож<strong>е</strong>ни<strong>е</strong><br />

пыталось д<strong>е</strong>с<strong>е</strong>риализовать<br />

т<strong>е</strong>кстовый<br />

файл.<br />

Много<strong>е</strong> можно узнать из<br />

г.т<strong>е</strong>ка вызова, в<strong>е</strong>дь там<br />

показыва<strong>е</strong>тся список<br />

запущ<strong>е</strong>нных А/івтодов.<br />

Вы видит<strong>е</strong>, что м <strong>е</strong>­<br />

тод OpenFileQ класса<br />

Excuse вызыва<strong>е</strong>тся <strong>е</strong>го<br />

конструктором (.ctor),<br />

который, в свою оч<strong>е</strong>р<strong>е</strong>дь,<br />

вызыва<strong>е</strong>тся обработчиком<br />

событии кнопки<br />

Random Excuse.<br />

atSystem.Runtime.Serialization.Fon7iatters.Binary.ObjectReader.Deserialize(HeaderHandler<br />

handler, _BinaryParserserParser, Boolean fCheck, Boolean isCrossAppDomain,<br />

IMethodCallMessage methodCallMessage)<br />

at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream<br />

serializationStream, HeaderHandler handler, Boolean fCheck, Boolean IsCrossAppDomain,<br />

IMethodCallMessage methodCallMessage)<br />

atSystem.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream<br />

serializationStream)<br />

'a t Chapter10.Excuse.OpenFile(String ExcusePath) in C:\Documents and Settings\Administrator\<br />

^My DocumentsWisua! Studio 2005\Projects\Chapter10\Chapter10\Excuse.cs:line 40<br />

at Chapter10.Excuse..ctor(Random random, String Folder) in C:\Documents and Settings\<br />

^dministrator\My DocumentsWisual Studio 2005\Projects\Chapter10\Chapter10\Excuse.cs:line 30<br />

^C hapter10.Form 1.random Excuse_Click(O bject sender, EventArgs e) in C:\Documents and<br />

Settings\AdministratortMy DocumentsWisual Studio 2005\Projects\Chapter10\Chapter10\Form1.<br />

csiline 146<br />

© Щ <strong>е</strong> л ч о к на к н о п к <strong>е</strong> D etails п озволя<strong>е</strong>т м н о го <strong>е</strong> узнать о п р и ч и н а х в о зн и к ш <strong>е</strong> й пробл<strong>е</strong>м ы . Есть<br />

ид<strong>е</strong>и, что со вс<strong>е</strong>м этим д<strong>е</strong>лать?<br />

дальш<strong>е</strong> ► 463


н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>мость пользоват<strong>е</strong>л<strong>е</strong>й<br />

Разум<strong>е</strong><strong>е</strong>тся, программа должна<br />

была пр<strong>е</strong>кратить работу, в<strong>е</strong>дь я дала <strong>е</strong>й н<strong>е</strong><br />

тот сршл. Пользоват<strong>е</strong>ли вс<strong>е</strong> вр<strong>е</strong>мя д<strong>е</strong>лают<br />

что-то н<strong>е</strong> то, и с этим н<strong>е</strong>возможно бороться<br />

На сам ом д<strong>е</strong>л <strong>е</strong> бороться с этим можно.<br />

Разум<strong>е</strong><strong>е</strong>тся, пользоват<strong>е</strong>ли п о с т о я н н о д<strong>е</strong>лаю т ч то -то н<strong>е</strong><br />

так. Такова ж и зн ь . Н о сущ <strong>е</strong>ствую т п р о гр а м м ы , сп о со б н ы <strong>е</strong><br />

р аботать с н <strong>е</strong> в <strong>е</strong> р н ы м и д а н н ы м и , о ш и б ка м и п р и и х ввод<strong>е</strong><br />

и д р у ги м и н <strong>е</strong> о ж и д а н н ы м и си туа ц и я м и ; и х н а зы ваю т робастными<br />

(robust). И н с тр у м <strong>е</strong> н ты о б р а б о тки и с к л ю ч <strong>е</strong> н и й<br />

C # д а ю т вам во зм о ж н о сть создавать и м <strong>е</strong> н н о та ки <strong>е</strong> п р о ­<br />

грам м ы . Разум<strong>е</strong><strong>е</strong>тся, вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> к о н тр о л и р о в а ть д<strong>е</strong>йс<br />

тв и я пользоват<strong>е</strong>л<strong>е</strong>й, н о вы мож<strong>е</strong>т<strong>е</strong> га р а н ти р о в а ть , ч т о<br />

п р о гр а м м а н<strong>е</strong> п р <strong>е</strong> к р а т и т работу, ч т о бы о н и н<strong>е</strong> д<strong>е</strong>лали.<br />

ро-баст-ный, прил.<br />

прочный; способный<br />

противостоять н<strong>е</strong>благоприятным<br />

условиям.<br />

рр у д ы н <strong>е</strong><br />

o a i l o j = > o ^ H b i !<br />

Класс BinaryFormatter сообщ а<strong>е</strong>т<br />

I об исклю ч<strong>е</strong>нии в случа<strong>е</strong><br />

пробл<strong>е</strong>м с с<strong>е</strong>риализованным<br />

ф айлом.<br />

Получить тако<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> для программы<br />

Excuse Manager прощ<strong>е</strong> простого<br />

— дайт<strong>е</strong> <strong>е</strong>й файл, который н<strong>е</strong> явля<strong>е</strong>тся<br />

с<strong>е</strong>риализованным объ<strong>е</strong>ктом Excuse. Класс<br />

B inaryF orm atter ожида<strong>е</strong>т, что файл<br />

буд<strong>е</strong>т сод<strong>е</strong>ржать с<strong>е</strong>риазированный обь<strong>е</strong>кт<br />

нужного типа. Если ж<strong>е</strong> файл сод<strong>е</strong>ржит чтото<br />

друго<strong>е</strong>, м<strong>е</strong>тод D e s e r ia liz e () отобразит<br />

исключ<strong>е</strong>ни<strong>е</strong> S e ria liza tio ziE x c e p tio n .<br />

464 глава 10


обработка исключ<strong>е</strong>ний<br />

Ключ<strong>е</strong>вы<strong>е</strong> сАоВа try и catch<br />

П р о и схо д я щ <strong>е</strong> <strong>е</strong> в C # м о ж н о о п и сать ф разой «Прот<strong>е</strong>стируйт<strong>е</strong> (try) э т о т код и п р и п о я в л <strong>е</strong> н и и искл ю ч <strong>е</strong> ­<br />

н и я пр<strong>е</strong>рвит<strong>е</strong> (catch) <strong>е</strong>го другим кодом ». Т<strong>е</strong>стиру<strong>е</strong>м ая часть кода назы ва<strong>е</strong>тся блоком tr y , а часть, обрабаты<br />

ваю щ ая и с к л ю ч <strong>е</strong> н и я , - блоком c a tc h . В блок<strong>е</strong> c a t c h м о ж н о добавить сообщ <strong>е</strong>ни<strong>е</strong> об о ш и б к<strong>е</strong> , н<strong>е</strong><br />

давая п р о грам м <strong>е</strong> а в а р и й н о зав<strong>е</strong>рш и ть работу.<br />

private void randomExcuse_Click(object sender, EventArgs e)<br />

__ зд<strong>е</strong>сь код, добавл<strong>е</strong>нш т н<strong>е</strong>сколько страниц назад.<br />

s t r y {<br />

if (CheckChangedО == true) {<br />

currentExcuse = new<br />

Excuse(random, selectedFolder);<br />

UpdateForm (false) ;<br />

Ключ<strong>е</strong>во<strong>е</strong> слово catch означа<strong>е</strong>тj что <strong>е</strong>л<strong>е</strong>дующий<br />

за ним блок оп<strong>е</strong>раторов сод<strong>е</strong>ржит<br />

оораоотчик исключ<strong>е</strong>ния.<br />


сомнит<strong>е</strong>льны<strong>е</strong> д<strong>е</strong>лишки<br />

Вызоб сомнит<strong>е</strong>льного м<strong>е</strong>тода<br />

П о л ьзоват<strong>е</strong>ли н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>м ы . О н и вводят в п р о гр а м м у с тр а н н ы <strong>е</strong> данны <strong>е</strong> , щ <strong>е</strong>лкаю т на кн о п ка х. И это<br />

п р <strong>е</strong> кр а сн о , в<strong>е</strong>дь вы м ож <strong>е</strong>т<strong>е</strong> сп р а в и ться с п о сл <strong>е</strong>дствиям и ввода т а к и х д а н н ы х, обрабаты вая и скл ю ч <strong>е</strong> н и я .<br />

( D Пр<strong>е</strong>дположим, пользоват<strong>е</strong>ль<br />

вводит н<strong>е</strong> т<strong>е</strong><br />

данны <strong>е</strong>.<br />

Пользоват<strong>е</strong>ль<br />

Вводимы<strong>е</strong><br />

данны<strong>е</strong><br />

Написанный<br />

вами класс<br />

М <strong>е</strong>тод д <strong>е</strong>л а<strong>е</strong>т что-то<br />

странно<strong>е</strong>, что мож<strong>е</strong>т и<br />

н<strong>е</strong> сработать во вр<strong>е</strong>мя<br />

прогона.<br />

Вр<strong>е</strong>м<strong>е</strong>н<strong>е</strong>м прогона (Runtime) называ<strong>е</strong>тся<br />

вр<strong>е</strong>мя работы ваш<strong>е</strong>й программы. Исключ<strong>е</strong>ния<br />

иногда <strong>е</strong>щ<strong>е</strong> называют «ошибками<br />

при исполн<strong>е</strong>нии» (runtime erro rs).<br />

Вы должны знать, что<br />

вы зы ва<strong>е</strong>мы й м<strong>е</strong>тод сомнит<strong>е</strong>л<strong>е</strong>н.<br />

Написанный<br />

вами класс<br />

p u b l i c v o id<br />

}<br />

P r o c e s s ( I n p u t i ) {<br />

i f ( i .I s B a d O )<br />

e x p l o d e ( ) ;<br />

{<br />

A что буд<strong>е</strong>т,<br />

<strong>е</strong>сли щ<strong>е</strong>лкнуть<br />

зд<strong>е</strong>сь...<br />

}<br />

М<strong>е</strong>тод ProcessQ<br />

н<strong>е</strong> работа<strong>е</strong>т с<br />

н<strong>е</strong>корр<strong>е</strong>ктными<br />

данными! ,—<br />

Л<br />

у<br />

Лучш<strong>е</strong> вс<strong>е</strong>го, <strong>е</strong>сли вы пр<strong>е</strong>дусмотрит<br />

<strong>е</strong> обходной пут ь на случай<br />

возникнов<strong>е</strong>ния исключ<strong>е</strong>ний! Впроч<strong>е</strong>м<br />

полностью устранить риск н<strong>е</strong> Пользоват<strong>е</strong>ль<br />

получится, поэтому сл<strong>е</strong>ду<strong>е</strong>т поступать<br />

так. \<br />

V<br />

( 5 ) в этом случа<strong>е</strong> вы см ож<strong>е</strong>т<strong>е</strong><br />

написать код, обрабаты ваю<br />

щ ий исклю ч<strong>е</strong>ни<strong>е</strong>. Если оно<br />

появится, вы буд<strong>е</strong>т<strong>е</strong> готовы.<br />

Программа д<strong>е</strong>йствит<strong>е</strong>льно<br />

стабильна!<br />

ваша программа<br />

НаПИклппы и<br />

вами класс<br />

Пользоват<strong>е</strong>ль<br />

Ваш класс т<strong>е</strong>п<strong>е</strong>рь<br />

ум<strong>е</strong><strong>е</strong>т обрабатывать<br />

исключ<strong>е</strong>ния<br />

466 глава 10


обработка исключ<strong>е</strong>ний<br />

^ J Так когда используются ключ<strong>е</strong>вы<strong>е</strong><br />

слова t r y и c a tc h ?<br />

Q ; в случаях, когда вы пиш<strong>е</strong>т<strong>е</strong> сомнит<strong>е</strong>льный<br />

код, который мож<strong>е</strong>т прив<strong>е</strong>сти<br />

к исключ<strong>е</strong>ниям. Сложн<strong>е</strong><strong>е</strong> вс<strong>е</strong>го понять,<br />

что код явля<strong>е</strong>тся сомнит<strong>е</strong>льным.<br />

Вы уж<strong>е</strong> вид<strong>е</strong>ли, что сомнит<strong>е</strong>льную<br />

работу кода мож<strong>е</strong>т инициировать ввод<br />

н<strong>е</strong>в<strong>е</strong>рных данных. Пользоват<strong>е</strong>ли могут<br />

выбирать н<strong>е</strong> т<strong>е</strong> файлы, вводить буквы<br />

вм<strong>е</strong>сто цифр и им<strong>е</strong>на вм<strong>е</strong>сто дат, а <strong>е</strong>щ<strong>е</strong><br />

они нажимают вс<strong>е</strong> кнопки, до которых<br />

могут дотянуться. Хорошая программа<br />

должна работать пр<strong>е</strong>дсказу<strong>е</strong>мо вн<strong>е</strong><br />

зависимости от вводимых данных. Пользоват<strong>е</strong>ль<br />

мож<strong>е</strong>т н<strong>е</strong> получить нужного<br />

р<strong>е</strong>зультата, но по крайн<strong>е</strong>й м<strong>е</strong>р<strong>е</strong> он узна<strong>е</strong>т<br />

о наличии пробл<strong>е</strong>мы и ознакомится<br />

с пр<strong>е</strong>длож<strong>е</strong>нным р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>м.<br />

А как можно пр<strong>е</strong>дложить р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

пробл<strong>е</strong>мы, о сущ<strong>е</strong>ствовании которой<br />

заран<strong>е</strong><strong>е</strong> н<strong>е</strong>изв<strong>е</strong>стно?<br />

Q ; Для этого вам потр<strong>е</strong>бу<strong>е</strong>тся блок<br />

c a tc h , который выполня<strong>е</strong>тся только<br />

посл<strong>е</strong> того, как блок t r y выдаст исключ<strong>е</strong>ни<strong>е</strong>.<br />

Вы да<strong>е</strong>т<strong>е</strong> пользоват<strong>е</strong>лю сигнал:<br />

что-то ид<strong>е</strong>т н<strong>е</strong> так и ситуацию можно<br />

и нужно исправить.<br />

Часто<br />

з а д а в а <strong>е</strong> м ы <strong>е</strong><br />

Б оЦ Р о СЬ!<br />

Аварийно<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> работы программы<br />

при ввод<strong>е</strong> н<strong>е</strong>корр<strong>е</strong>ктных данных<br />

б<strong>е</strong>спол<strong>е</strong>зно. Н<strong>е</strong>т таюк<strong>е</strong> никакой пользы<br />

от попыток читать вс<strong>е</strong> вводимы<strong>е</strong> данны<strong>е</strong>.<br />

А вот появл<strong>е</strong>ни<strong>е</strong> окна с сообщ<strong>е</strong>ни<strong>е</strong>м о н<strong>е</strong>возможности<br />

прочитать файл позволя<strong>е</strong>т<br />

принять в<strong>е</strong>рно<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong>.<br />

То <strong>е</strong>сть отладчик нуж<strong>е</strong>н для поиска<br />

причины исключ<strong>е</strong>ний?<br />

г ; Н<strong>е</strong>т. Вы уж<strong>е</strong> н<strong>е</strong> раз вид<strong>е</strong>ли, что отладчик<br />

работа<strong>е</strong>т с любым кодом. Иногда<br />

им<strong>е</strong><strong>е</strong>т смысл пошагово просмотр<strong>е</strong>ть<br />

знач<strong>е</strong>ния опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных пол<strong>е</strong>й и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

— им<strong>е</strong>нно так можно гарантировать<br />

корр<strong>е</strong>ктную работу сложных м<strong>е</strong>тодов.<br />

Но основным назнач<strong>е</strong>ни<strong>е</strong>м отладчика<br />

явля<strong>е</strong>тся поиск и устран<strong>е</strong>ни<strong>е</strong> д<strong>е</strong>ф<strong>е</strong>ктов<br />

программы. Исключ<strong>е</strong>ния такж<strong>е</strong> относятся<br />

к д<strong>е</strong>ф<strong>е</strong>ктам. Но отладчик р<strong>е</strong>ша<strong>е</strong>т пробл<strong>е</strong>мы<br />

и другого рода, наприм<strong>е</strong>р, поиск кода,<br />

дающ<strong>е</strong>го н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>мый р<strong>е</strong>зультат.<br />

Я н<strong>е</strong> совс<strong>е</strong>м понимаю принцип<br />

работы с окном Watch.<br />

Q ; в проц<strong>е</strong>сс<strong>е</strong> отладки обраща<strong>е</strong>тся внимани<strong>е</strong><br />

на знач<strong>е</strong>ния опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных пол<strong>е</strong>й<br />

и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных. Им<strong>е</strong>нно для этого нужно<br />

окно Watch. П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>, к которым<br />

были добавл<strong>е</strong>ны контрольны<strong>е</strong> знач<strong>е</strong>ния,<br />

обновляют свои знач<strong>е</strong>ния в окн<strong>е</strong> Watch<br />

с каждым сл<strong>е</strong>дующим шагом. Это позволя<strong>е</strong>т<br />

отсл<strong>е</strong>живать, что им<strong>е</strong>нно с ними<br />

происходит посл<strong>е</strong> выполн<strong>е</strong>ния каждого<br />

оп<strong>е</strong>ратора.<br />

В окно Watch можно вв<strong>е</strong>сти любой<br />

оп<strong>е</strong>ратор и увид<strong>е</strong>ть <strong>е</strong>го знач<strong>е</strong>ни<strong>е</strong>. Если<br />

оп<strong>е</strong>ратор влия<strong>е</strong>т на знач<strong>е</strong>ния пол<strong>е</strong>й<br />

и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных, значит, он буд<strong>е</strong>т выполнять<br />

<strong>е</strong>щ<strong>е</strong> и эту функцию. Это позволя<strong>е</strong>т<br />

м<strong>е</strong>нять парам<strong>е</strong>тры, н<strong>е</strong> пр<strong>е</strong>рывая работу<br />

программы, что да<strong>е</strong>т вам <strong>е</strong>щ<strong>е</strong> один<br />

инструм<strong>е</strong>нт для отсл<strong>е</strong>живания д<strong>е</strong>ф<strong>е</strong>ктов<br />

и исключ<strong>е</strong>ний.<br />

Р<strong>е</strong>дактировани<strong>е</strong> данных в окн<strong>е</strong><br />

VJatck влия<strong>е</strong>т на их состояни<strong>е</strong><br />

в памяти на вр<strong>е</strong>мя работы<br />

программы. Д ля возвращ<strong>е</strong>ния<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нным исходных<br />

знач<strong>е</strong>ний достаточно п<strong>е</strong>р<strong>е</strong>загрузить<br />

программу.<br />

Блок catch выполня<strong>е</strong>тся<br />

только при<br />

обнаруж<strong>е</strong>нии исключ<strong>е</strong>ния<br />

в блок<strong>е</strong><br />

try. Это да<strong>е</strong>т возможность<br />

снабдить<br />

пользоват<strong>е</strong>ля информаци<strong>е</strong>й<br />

о путях<br />

р<strong>е</strong>ш<strong>е</strong>ния пробл<strong>е</strong>мы.<br />

дальш<strong>е</strong> > 467


плыв<strong>е</strong>м по т<strong>е</strong>ч<strong>е</strong>нию<br />

Р<strong>е</strong>зультаты прим<strong>е</strong>н<strong>е</strong>ния ключ<strong>е</strong>бых слоб try/catch<br />

Сл<strong>е</strong>ду<strong>е</strong>т п о м н и ть , ч т о п р и о б н а р у ж <strong>е</strong> н и и и с к л ю ч <strong>е</strong> н и я в блок<strong>е</strong> t r y<br />

остальная часть кода и гн о р и р у <strong>е</strong> тся. П р о гр а м м а н<strong>е</strong>м <strong>е</strong>дл<strong>е</strong>нно п<strong>е</strong>р<strong>е</strong>х<br />

о д и т на п <strong>е</strong> рвую с тр о ч к у блока c a tc h . Впроч<strong>е</strong>м, вы мож<strong>е</strong>т<strong>е</strong> н<strong>е</strong> <strong>е</strong><strong>е</strong>рить<br />

нам на слово...<br />

^<br />

О ш Л а Д ь ш <strong>е</strong> э щ о !<br />

В<strong>е</strong>сь п р <strong>е</strong> д о ставл <strong>е</strong> н н ы й в э т о й глав<strong>е</strong> код н у ж н о в с тр о и ть в о б р а б о т ч и к с о б ы т и й к н о п к и<br />

R a n d o m Excuse. Т о чку о станова сл<strong>е</strong>ду<strong>е</strong>т п о м <strong>е</strong> сти ть в п <strong>е</strong> р вую строчку. И запусти ть п р о гр а м ­<br />

му. Щ <strong>е</strong> л к н и т <strong>е</strong> на к н о п к <strong>е</strong> F o ld e r и в ы б <strong>е</strong> р и т<strong>е</strong> п а п ку с <strong>е</strong> д и н ств<strong>е</strong>нны м ф айлом в н <strong>е</strong>й. У б<strong>е</strong>дит<strong>е</strong>сь,<br />

ч т о э то н<strong>е</strong>корр<strong>е</strong>ктный файл с оправдани<strong>е</strong>м (н <strong>е</strong> см о тр я на р а с ш и р <strong>е</strong> н и <strong>е</strong> .excuse). Щ <strong>е</strong> л к ­<br />

н и т <strong>е</strong> на к н о п к <strong>е</strong> R a n d o m Excuse, а зат<strong>е</strong>м ш <strong>е</strong>сть раз щ <strong>е</strong> л кн и т<strong>е</strong> на к н о п к <strong>е</strong> Step O v e r (и л и наж<br />

м и т<strong>е</strong> F10) для п<strong>е</strong>р<strong>е</strong>хода к оп<strong>е</strong>ратору, вы зы ваю щ <strong>е</strong>м у к о н с тр у к т о р E x c u s e . В о т ка к долж <strong>е</strong>н<br />

вы гляд<strong>е</strong>ть ваш экр а н на это м этап<strong>е</strong>:<br />

Э т о точка<br />

останова, которую<br />

МЫ пом<strong>е</strong> -<br />

стили в п<strong>е</strong>рвую<br />

строчку одра - ~~<br />

ботчика событий.<br />

Нажимайт<strong>е</strong> Рй-О,<br />

пока н<strong>е</strong> дойд<strong>е</strong>т<strong>е</strong><br />

до строки, пр<strong>е</strong>дш<strong>е</strong>ствующ<strong>е</strong>й<br />

^<br />

созданию объ<strong>е</strong>кта<br />

Excuse.<br />

p r i v a t e v o i d r a n d c n B E x c u s e _ C l i c k ( o b j e c t s e n d e r ^ E v e n tA r g s e )<br />

{<br />

s t r i n g [ j f i l e n a m e s = P i r e c t o r y . 6 e t F i l e 5 ( s e l e c t e d F o I r f e r . " * . e x c o s e " ) j<br />

i f ( f i l e N a i s e s . L e n g t h = = 0 )<br />

}<br />

t r y<br />

{<br />

M e s s a g e B o x .S h o w C ’P l e a s e s p e c i f y a f o l d e r w i t h e x c u s e f i l e s i n i t ” ,<br />

[if (CheckChanged{) =« tr u e )<br />

{<br />

"H o e x c u s e f i l e s f o u n d " ) ;<br />

c u r r e n t E x c u s e = n ew E x c u s e ( r a n d a ® , s e l e c t e d F o l d e r ) j<br />

U p d a t e F o r r e ( f a l s e ) ;<br />

}<br />

}<br />

Используйт<strong>е</strong> команду Step<br />

Over (Fio) для обхода м <strong>е</strong>-<br />

c a t c h ( s e r i a i i z a t i o n e x c e p t i o n ) moda Ch.eckCkanged().<br />

{<br />

}<br />

M e s s a g e B o x .Show(<br />

" Y o u r e x c u s e f i l e w a s i n v a l i d . ” ,<br />

" U n a b l e t o o p e n a ra n d c M e x c u s e " ) ;<br />

© Н а ж м и т<strong>е</strong> F I 1 для п р осм о тра оп<strong>е</strong>ратора new. ОтлаДник. пом <strong>е</strong> сти т ж <strong>е</strong>лтую п олоску над стр о ко й<br />

объявл<strong>е</strong>ния в код<strong>е</strong> констр укто ра E x c u s e . Н а ж м и т<strong>е</strong> F11, ч то б ы попасть в м<strong>е</strong>тод O p e n F ile ()<br />

и посм отр<strong>е</strong>ть, ч т о случится на стр очк<strong>е</strong> D e s e r i a l i z e { ) .<br />

Посл<strong>е</strong> оп<strong>е</strong>ратора<br />

new отладчик начина<strong>е</strong>т<br />

просмат ривать<br />

код констриктора.<br />

^jublic Excuse(Random random, string folder)<br />

{<br />

string[] fileNames = D ir e c to r y .GetFiles(folder, "».excuse");<br />

OpenFile(fileNanies [random,Next(fileNaraes.Length) ]);<br />

><br />

468 глава 10


обработка исключ<strong>е</strong>ний<br />

О П о сл <strong>е</strong> в ы п ол н <strong>е</strong>н и я о п <strong>е</strong> р а т о р а D e s e r i a l i z e () п оя в и тся и ск л ю ч <strong>е</strong>н и <strong>е</strong>, и п рограм м а, п р о ­<br />

и гн ор и р ов ав вы зов м <strong>е</strong>то д а U p d a te F o r m ( ) , п<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>т н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно к блоку c a tc h .<br />

Отладчик выд<strong>е</strong>лит<br />

ж<strong>е</strong>лтым<br />

строчку с ключ<strong>е</strong>вым<br />

словом catcl^J<br />

в то вр<strong>е</strong>мя как<br />

остальной код<br />

блока буд<strong>е</strong>т по-'~'<br />

м<strong>е</strong>ч<strong>е</strong>н с<strong>е</strong>рым, то<br />

<strong>е</strong>сть готовым<br />

к выполн<strong>е</strong>нию.<br />

private void randOTiExcuse_Click(object sender, EventArgs e)<br />

{<br />

Stringt] fileWaiaes = Directory.6etPiles(selecteelFolder, "•.excuse");<br />

if (fileNames.Length == 0)<br />

{<br />

}<br />

try<br />

{<br />

>5essageBox.Show(“PIease specify a folder with excuse files in it",<br />

"No excuse files found");<br />

if (CheckChanged0 == true)<br />

{<br />

currentExcuse = new £xcuse(randoiB, selectedFolder);<br />

UpdateFormCfalse);<br />

’<br />

c«tch (SerializationException)<br />

{<br />

MessageSox.Sho«(<br />

"Your excuse file was invalid.”,<br />

"Unable to open a randoai excuse”);<br />

}<br />

Н а ж м и т <strong>е</strong> клавиигу F5 для запуска програм м ы . О н а н ач н <strong>е</strong>т вы полняться с о стр очк и , п о м <strong>е</strong>­<br />

ч <strong>е</strong> н н о й ж <strong>е</strong>лты м , в наш <strong>е</strong>м случа<strong>е</strong> с блок а c a t c h .<br />

Сов<strong>е</strong>т на будущ<strong>е</strong><strong>е</strong>:<br />

Инт<strong>е</strong>рвью<br />

с соискат<strong>е</strong>лями<br />

на должность<br />

программиста<br />

часто включают<br />

в с<strong>е</strong>бя вопрос<br />

о том, как сл<strong>е</strong>ду<strong>е</strong>т<br />

поступать<br />

с исключ<strong>е</strong>ниями<br />

в конструктор<strong>е</strong>.<br />

А ккуоатн<strong>е</strong><strong>е</strong> с исклю ч<strong>е</strong>ниям и в конструктор<strong>е</strong>!<br />

Рр у |Дып<strong>е</strong> д ы п <strong>е</strong><br />

осш^роЖНьїІ Думаю, выуж<strong>е</strong> зам<strong>е</strong>тили, что у конструктора отсутству<strong>е</strong>т<br />

возвраща<strong>е</strong>мо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>. Д<strong>е</strong>ло в том, что <strong>е</strong>го назнач<strong>е</strong>ни<strong>е</strong>м<br />

явля<strong>е</strong>тся инициализация объ<strong>е</strong>кта, и им<strong>е</strong>нно поэтому так сложно обрабатывать<br />

исключ<strong>е</strong>ния, возникши<strong>е</strong> внутри конструктора. Наличи<strong>е</strong><br />

исключ<strong>е</strong>ния означа<strong>е</strong>т, что оп<strong>е</strong>ратор, создающий экз<strong>е</strong>мпляр класса, н<strong>е</strong><br />

смог <strong>е</strong>го получить. Блок try/catch в этом случа<strong>е</strong> им<strong>е</strong><strong>е</strong>т смысл пом<strong>е</strong>стить<br />

в обработчик событий кнопки, чтобы код н<strong>е</strong> ожидал найти<br />

в класс<strong>е</strong> CurrentExcuse корр<strong>е</strong>ктный объ<strong>е</strong>кт Excuse.<br />

дальш<strong>е</strong> > 469


уб<strong>е</strong>ри за собой<br />

Ключ<strong>е</strong>бо<strong>е</strong> слоВо finally^<br />

в случа<strong>е</strong> исключ<strong>е</strong>ния возможны два варианта развития событий. Н<strong>е</strong> обработанно<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> в<strong>е</strong>д<strong>е</strong>т<br />

к аварийному зав<strong>е</strong>рш<strong>е</strong>нию программы. В противном случа<strong>е</strong> управл<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>ходит к блоку c a tc h . Но<br />

что происходит с остальным кодом блока try ? Пр<strong>е</strong>дставьт<strong>е</strong>, что в этой части закрывался поток. Тогда<br />

этот код н<strong>е</strong>обходимо выполнить, н<strong>е</strong>смотря на исключ<strong>е</strong>ни<strong>е</strong>. На помощь в этой ситуации приходит блок<br />

f i n a l l y . Он за п у с к а <strong>е</strong> т с я в с <strong>е</strong> г д а , вн<strong>е</strong> зависимости от появл<strong>е</strong>ния или отсутствия исключ<strong>е</strong>ния. Вот как<br />

нужно закончить обработчик событий кнопки Random Excuse:<br />

блок finally гарантиру<strong>е</strong>т,<br />

что Me- }<br />

‘-'P/ateFormQ<br />

буд<strong>е</strong>т выполн<strong>е</strong>н вн<strong>е</strong><br />

заоисимости от<br />

исключ<strong>е</strong>ния. Соот-<br />

Ь<strong>е</strong>т^ств<strong>е</strong>нно, м<strong>е</strong>тод<br />

UpdateFormO буд<strong>е</strong>т<br />

Ьызван н<strong>е</strong> только <strong>е</strong>сли<br />

конструктор Excuse<br />

усп<strong>е</strong>шно прочитал<br />

оправдани<strong>е</strong>, но и 6<br />

"луча<strong>е</strong>, когда появилось<br />

исключ<strong>е</strong>ни<strong>е</strong> и<br />

раил с оправдани<strong>е</strong>м<br />

>ыл очищ<strong>е</strong>н. }<br />

p r i v a t e v o id ran d o m E x c u se_ C lic k (o b je ct s e n d e r, E ventA rgs e) {<br />

s t r i n g [ ] fileN am es = D ir e c to r y .G e tF ile s ( s e le c te d F o ld e r , " * .e x c u s e " ) ;<br />

i f (file N a m e s.L e n g th ==0) {<br />

M essageB ox.S how ("P lease s p e c if y a f o ld e r w ith ex cu se f i l e s in i t " ,<br />

"No e x cu se f i l e s fo u n d " );<br />

} e l s e {<br />

t r y {<br />

i f (C heckC hanged0 == tr u e ) {<br />

}<br />

c u rre n tE x c u s e = new E xcuse(random , s e le c te d F o ld e r ) ;<br />

c a t c h ( S e r i a l i z a t i o n E x c e p t i o n ) {<br />

c u rre n tE x c u s e = new E x c u se ( );<br />

c u r r e n tE x c u s e .D e s c rip tio n = "";<br />

c u rre n tE x c u s e .R e s u lts = " " ;<br />

c u rre n tE x c u s e .L a s tU se d = DateTime.Now;<br />

M essageBox. Show(<br />

"Your ex c u se f i l e was i n v a l i d . " ,<br />

"U nable t o open a random e x c u s e " ) ;<br />

f i n a l l y {<br />

}<br />

U p d a te F o rm (fa ls e );<br />

•При появл<strong>е</strong>нии исключ<strong>е</strong>ния<br />

в конструктор<strong>е</strong> Excuse у з­<br />

нать знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

CurrentExcuse н<strong>е</strong>возможно,<br />

так как экз<strong>е</strong>мпляр txcuse о т ­<br />

сутству<strong>е</strong>т. Поэтому в блок<strong>е</strong><br />

catch созда<strong>е</strong>тся этот обь<strong>е</strong>кт<br />

и очищаются вс<strong>е</strong> <strong>е</strong>го поля.<br />

SerializationException находится в пространств<strong>е</strong><br />

им<strong>е</strong>н System.Runtime.Serialization, поэтому<br />

в в<strong>е</strong>рхнюю часть файла формы нужно добавить<br />

строчку u s i n g S y ste m .R u n tim e . S e r i a l i z a t i o n ;<br />

Р я д о м с к л ю ч <strong>е</strong> в ы м с л о в о м c a tc h у к а з а н о , ч т о о т с л <strong>е</strong> ж и в а <strong>е</strong> т с я и с к л ю ч <strong>е</strong> н и <strong>е</strong> S e r i a l i z a t i o n ­<br />

E x c e p t i o n . Это принятый в <strong>C#</strong> код c a t c h ( E x c e p t i o n ) , хотя тип исключ<strong>е</strong>ния можно и опустить, оставив<br />

только слово c a t c h . В этом случа<strong>е</strong> б у д у т о т с л <strong>е</strong> ж и в а т ь с я в с <strong>е</strong> в о з м о ж н ы <strong>е</strong> и с к л ю ч <strong>е</strong> н и я . Хотя это<br />

«<strong>е</strong> оч<strong>е</strong>нь хорошо. Лучш<strong>е</strong> указывать, како<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> вы хотит<strong>е</strong> отсл<strong>е</strong>дить и указывать, как можно бол<strong>е</strong><strong>е</strong><br />

подробно.<br />

470 глава 10


обработка исключ<strong>е</strong>ний<br />

Когда ж<strong>е</strong>лтая<br />

строка<br />

достига<strong>е</strong>т<br />

точки<br />

останова,<br />

над крас -<br />

ной точкой<br />

на поляк<br />

появля<strong>е</strong>тся<br />

ж<strong>е</strong>лтая<br />

стр<strong>е</strong>лка.<br />

Д т <strong>е</strong> п <strong>е</strong> р о т л а д и м !<br />

. %<br />

Обновит<strong>е</strong> обработчик событий кнопки Random Excuse, вставив туда код с пр<strong>е</strong>дыдущ<strong>е</strong>й<br />

страницы. Пом<strong>е</strong>стит<strong>е</strong> точку останова на п<strong>е</strong>рвую строку м<strong>е</strong>тода и отладьт<strong>е</strong> программу.<br />

© Запустит<strong>е</strong> программу и уб<strong>е</strong>дит<strong>е</strong>сь, что когда программа указыва<strong>е</strong>т на папку с файлами<br />

оправданий, кнопка Random Excuse работа<strong>е</strong>т корр<strong>е</strong>ктно. Программа пр<strong>е</strong>рв<strong>е</strong>тся на заданной<br />

вами точк<strong>е</strong> останова:<br />

■О<br />

-Г7Г<br />

private void randoraEKcuse_Cllck(object sender, EventArgs e)<br />

{<br />

string[] -fileNames = Directory,Ge1:Files(selectedFolder, "*.excuse")j<br />

if (fileNames,Length == в)<br />

}<br />

else<br />

{<br />

try<br />

А<br />

MessageBox.Show("Please specify a folder with excuse files in it”<br />

" N o excuse files found")J<br />

if (CheckChanged() == true)<br />

{<br />

currentExcuse = new Excuse(randoiBj selectedFolder);<br />

}<br />

><br />

catch (SerializationException)<br />

{<br />

currentExcuse - new ExcuseO;<br />

currentExcuse.Description = ""j;<br />

currentExcuse.Results =<br />

currentExcuse.LastUsed = OateTirae.Now;<br />

Hessage0cfx.5hciw(<br />

"Your excuse file was invalid.",<br />

"Unable to open a random excuse");<br />

}<br />

finally<br />

{<br />

UpdateForm(false);<br />

}<br />

^<br />

©<br />

О<br />

Пошагово просмотрит<strong>е</strong> обработчик событий кнопки Random Excuse и уб<strong>е</strong>дит<strong>е</strong>сь, что<br />

она работа<strong>е</strong>т корр<strong>е</strong>ктно. Посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния блока t r y долж<strong>е</strong>н произойти п<strong>е</strong>р<strong>е</strong>ход к блоку<br />

f i n a l l y , так как исключ<strong>е</strong>ний н<strong>е</strong> обнаруж<strong>е</strong>но.<br />

Т<strong>е</strong>п<strong>е</strong>рь укажит<strong>е</strong> папку, сод<strong>е</strong>ржащую вс<strong>е</strong>го один д<strong>е</strong>ф<strong>е</strong>ктный файл, и снова щ<strong>е</strong>лкнит<strong>е</strong> на<br />

кнопк<strong>е</strong> Random Excuse. Из блока t r y при обнаруж<strong>е</strong>нии исключ<strong>е</strong>ния управл<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>йд<strong>е</strong>т<br />

к блоку c a tc h . Посл<strong>е</strong> того как будут просмотр<strong>е</strong>ны вс<strong>е</strong> <strong>е</strong>го оп<strong>е</strong>раторы, начн<strong>е</strong>т выполняться<br />

блок f i n a l l y .<br />

дальш<strong>е</strong> ► 471


исключ<strong>е</strong>ния как причина н<strong>е</strong>стабильности<br />

При отсутствии блока catch моя<br />

программа, столкнувшись с исключ<strong>е</strong>ни<strong>е</strong>м,<br />

буд<strong>е</strong>т просто остановл<strong>е</strong>на. Что<br />

ж<strong>е</strong> в этом хорош<strong>е</strong>го?<br />

^ I Основным пр<strong>е</strong>имущ<strong>е</strong>ством исключ<strong>е</strong>ний<br />

явл<strong>е</strong>тся то, что они н<strong>е</strong> дают пройти<br />

мимо пробл<strong>е</strong>мы, в больших прилож<strong>е</strong>ниях<br />

сложно сл<strong>е</strong>дить за вс<strong>е</strong>ми объ<strong>е</strong>ктами,<br />

с которыми в<strong>е</strong>д<strong>е</strong>тся работа. Исключ<strong>е</strong>ния<br />

привл<strong>е</strong>кают внимани<strong>е</strong> к пробл<strong>е</strong>мам и помогают<br />

понять причины их возникнов<strong>е</strong>ния.<br />

Появл<strong>е</strong>ни<strong>е</strong> исключ<strong>е</strong>ния в ваш<strong>е</strong>й программ<strong>е</strong><br />

пр<strong>е</strong>дупр<strong>е</strong>жда<strong>е</strong>т — что что-то ид<strong>е</strong>т<br />

н<strong>е</strong> так, как было запланировано. Мож<strong>е</strong>т<br />

быть, ссылка указыва<strong>е</strong>т н<strong>е</strong> на тот объ<strong>е</strong>кт,<br />

на который нужно, или пользоват<strong>е</strong>ль вв<strong>е</strong>л<br />

совс<strong>е</strong>м н<strong>е</strong> то знач<strong>е</strong>ни<strong>е</strong>, которо<strong>е</strong> тр<strong>е</strong>бовалось,<br />

или даж<strong>е</strong> файл, с которым в<strong>е</strong>д<strong>е</strong>тся<br />

работа, вдруг стал н<strong>е</strong>доступ<strong>е</strong>н. Подобны<strong>е</strong><br />

в<strong>е</strong>щи м<strong>е</strong>няют р<strong>е</strong>зультат работы ваш<strong>е</strong>й<br />

программы.<br />

А т<strong>е</strong>п<strong>е</strong>рь пр<strong>е</strong>дставьт<strong>е</strong>, что вы даж<strong>е</strong> н<strong>е</strong><br />

зна<strong>е</strong>т<strong>е</strong> обо вс<strong>е</strong>х этих ошибках. Пользоват<strong>е</strong>ль<br />

ж<strong>е</strong> вводит н<strong>е</strong>корр<strong>е</strong>ктны<strong>е</strong> данны<strong>е</strong><br />

и начина<strong>е</strong>т жаловаться, что прилож<strong>е</strong>ни<strong>е</strong><br />

н<strong>е</strong>стабильно. Нарушающи<strong>е</strong> работу ваш<strong>е</strong>й<br />

программы исключ<strong>е</strong>ния позволяют узнать<br />

о пробл<strong>е</strong>м<strong>е</strong> на том этап<strong>е</strong>, когда <strong>е</strong><strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

<strong>е</strong>щ<strong>е</strong> можно пров<strong>е</strong>сти относит<strong>е</strong>льно<br />

л<strong>е</strong>гко и б<strong>е</strong>збол<strong>е</strong>зн<strong>е</strong>нно.<br />

Ч<strong>е</strong>м обработанно<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong><br />

отлича<strong>е</strong>тся от н<strong>е</strong>обработанного?<br />

Ql При появл<strong>е</strong>нии исключ<strong>е</strong>ний программа<br />

начина<strong>е</strong>т искать блок catch,<br />

занимающийся обработкой. При наличии<br />

такого блока будут выполн<strong>е</strong>ны вс<strong>е</strong> полагающи<strong>е</strong>ся<br />

в случа<strong>е</strong> конкр<strong>е</strong>тного исключ<strong>е</strong>ния<br />

д<strong>е</strong>йствия. Фактич<strong>е</strong>ски, написани<strong>е</strong>м блока<br />

catch вы проводит<strong>е</strong> пр<strong>е</strong>дварит<strong>е</strong>льную<br />

работу над ошибками. Если ж<strong>е</strong> такой блок<br />

отсутству<strong>е</strong>т, программа просто пр<strong>е</strong>краща<strong>е</strong>т<br />

работу, выбрасывая окно с сообщ<strong>е</strong>ни<strong>е</strong>м.<br />

В этом случа<strong>е</strong> р<strong>е</strong>чь ид<strong>е</strong>т о н<strong>е</strong>обработанном<br />

исключ<strong>е</strong>нии.<br />

Часвдо<br />

З а д а в а <strong>е</strong> м ы <strong>е</strong><br />

Б о ц р о с ь !<br />

Зач<strong>е</strong>м указывать в блок<strong>е</strong> catch тип<br />

обрабатыва<strong>е</strong>мого исключ<strong>е</strong>ния? Разв<strong>е</strong><br />

н<strong>е</strong> б<strong>е</strong>зопасн<strong>е</strong><strong>е</strong> использовать унив<strong>е</strong>рсальный<br />

код?<br />

^ ! Б<strong>е</strong>зопасн<strong>е</strong>й вс<strong>е</strong>го вообщ<strong>е</strong> изб<strong>е</strong>гать<br />

ситуаций, в которых возникают объ<strong>е</strong>кты<br />

E x c e p tio n . Лучш<strong>е</strong> пров<strong>е</strong>сти профилактику,<br />

ч<strong>е</strong>м употр<strong>е</strong>блять л<strong>е</strong>карство.<br />

Это правило работа<strong>е</strong>т и с исключ<strong>е</strong>ниями.<br />

Попытка обработать вс<strong>е</strong> исключ<strong>е</strong>ния<br />

сразу указыва<strong>е</strong>т на плохо<strong>е</strong> программировани<strong>е</strong>.<br />

Наприм<strong>е</strong>р, лучш<strong>е</strong> воспользоваться<br />

м<strong>е</strong>тодом File .Exists () для пров<strong>е</strong>рки<br />

наличия файла, а н<strong>е</strong> обрабатывать исключ<strong>е</strong>ни<strong>е</strong><br />

FileNotFoundException.<br />

Хотя бывают исключ<strong>е</strong>ния, которых просто<br />

н<strong>е</strong> изб<strong>е</strong>жать, но большинство из них н<strong>е</strong><br />

им<strong>е</strong><strong>е</strong>т приорит<strong>е</strong>та.<br />

Иногда им<strong>е</strong><strong>е</strong>т смысл оставлять исключ<strong>е</strong>ния<br />

н<strong>е</strong>обработанными. Логика р<strong>е</strong>альных<br />

программ зачастую крайн<strong>е</strong> сложна и корр<strong>е</strong>ктно<br />

обойти ошибку н<strong>е</strong> вс<strong>е</strong>гда уда<strong>е</strong>тся,<br />

особ<strong>е</strong>нно <strong>е</strong>сли пробл<strong>е</strong>ма возника<strong>е</strong>т гд<strong>е</strong>-то<br />

там в нижн<strong>е</strong>й части кода. Обрабатывая<br />

конкр<strong>е</strong>тны<strong>е</strong> исключ<strong>е</strong>ния, изб<strong>е</strong>гая слишком<br />

общих подходов и попыток р<strong>е</strong>шить вс<strong>е</strong><br />

пробл<strong>е</strong>мы сразу, позволяя исключ<strong>е</strong>ниям<br />

всплывать, чтобы обработать их на<br />

в<strong>е</strong>рхн<strong>е</strong>м уровн<strong>е</strong>, вы сд<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> свой код<br />

намного бол<strong>е</strong><strong>е</strong> стабильным.<br />

Что произойд<strong>е</strong>т, <strong>е</strong>сли н<strong>е</strong> указать<br />

тип исключ<strong>е</strong>ния рядом с ключ<strong>е</strong>вым<br />

словом c a tc h ?<br />

О! Блок catch буд<strong>е</strong>т работать с люи<br />

исключ<strong>е</strong>ни<strong>е</strong>м, которо<strong>е</strong> появится<br />

в блок<strong>е</strong> try.<br />

Но <strong>е</strong>сли блок c a t c h мож<strong>е</strong>т обрабатывать<br />

исключ<strong>е</strong>ния любых типов,<br />

зач<strong>е</strong>м мн<strong>е</strong> указывать конкр<strong>е</strong>тный тип?<br />

^ S К сожал<strong>е</strong>нию, н<strong>е</strong> сущ<strong>е</strong>ству<strong>е</strong>т<br />

унив<strong>е</strong>рсального способа обработки вс<strong>е</strong>х<br />

исключ<strong>е</strong>ний. Для устран<strong>е</strong>ния пробл<strong>е</strong>мы<br />

с д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong>м на ноль в блок<strong>е</strong> catch нужно<br />

изм<strong>е</strong>нить знач<strong>е</strong>ния н<strong>е</strong>которых п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

и сохранить н<strong>е</strong>которы<strong>е</strong> данны<strong>е</strong>.<br />

А чтобы убрать ссылку на знач<strong>е</strong>ни<strong>е</strong> null<br />

мож<strong>е</strong>т потр<strong>е</strong>боваться создани<strong>е</strong> нового<br />

экз<strong>е</strong>мпляра.<br />

Обработка ошибок происходит<br />

только в посл<strong>е</strong>доват<strong>е</strong>льности t r y /<br />

c a t c h / f i n a l l y ?<br />

й! Н<strong>е</strong>т. Можно воспользоваться набором<br />

жов c a tc h , <strong>е</strong>сли вы хотит<strong>е</strong> уч<strong>е</strong>сть<br />

различны<strong>е</strong> виды ошибок. Этого блока мож<strong>е</strong>т<br />

и н<strong>е</strong> быть вовс<strong>е</strong>. В этом случа<strong>е</strong> исключ<strong>е</strong>ния<br />

обрабатывать н<strong>е</strong> будут, просто код блока<br />

f ina 11у начн<strong>е</strong>т выполняться даж<strong>е</strong> при<br />

остановк<strong>е</strong> из-за появл<strong>е</strong>ния исключ<strong>е</strong>ния<br />

в блок<strong>е</strong> try.<br />

Н<strong>е</strong>обработанно<strong>е</strong><br />

исключ<strong>е</strong>ни<strong>е</strong> означа<strong>е</strong>т<br />

н<strong>е</strong>пр<strong>е</strong>дсказу<strong>е</strong>мую<br />

работу программы.<br />

Им<strong>е</strong>нно<br />

поэтому программа<br />

п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т работать<br />

при их появл<strong>е</strong>нии.<br />

472 глава 10


c l a s s K a n g a r o o {<br />

______________ fs;<br />

обработка исключ<strong>е</strong>ний<br />

Р<strong>е</strong>зультат:<br />

Пом<strong>е</strong>стит<strong>е</strong> фрагм<strong>е</strong>нты кода из<br />

басс<strong>е</strong>йна на пусты<strong>е</strong> строчки<br />

программы. Каждый фрагм<strong>е</strong>нт<br />

мож<strong>е</strong>т использоваться<br />

н<strong>е</strong>сколько раз. Им<strong>е</strong>ются и<br />

лишни<strong>е</strong> фрагм<strong>е</strong>нты. Нужно<br />

получить сл<strong>е</strong>дующую строку.<br />

u s i n g System.lO;<br />

p u b l i c s t a t i c v o i d M a i n O {<br />

. }<br />

G'day Mate!<br />

K a n g a r o o j o e y = n e w K a n g a r o o ();<br />

int k o a l a = j o e y . W o m b a t (<br />

t r y {<br />

j o e y .W o m b a t {j o e y .W o m b a t (1))),<br />

C o n s o l e . W r i t e L i n e ((15 / koala)<br />

+ " e g g s p e r p o u n d " );<br />

}<br />

c a t c h (________________________) {<br />

К аж ды й ф р агм <strong>е</strong>нт<br />

м ож <strong>е</strong>т бы ть использо<br />

ван н <strong>е</strong>сколько<br />

раз!<br />

C o n s o l e .W r i t e L i n e (" G ' D a y M a t e !" !<br />

int croc;<br />

int d i n g o = 0;<br />

p u b l i c int W o m b a t ( i n t wallaby) {<br />

t r y {<br />

if {<br />

c r o c = о ;<br />

} e l s e if (_<br />

croc = з ;<br />

} e l s e {<br />

}<br />

croc = 1;<br />

> 0 ) {<br />

c a t c h (lOException) {<br />

}<br />

c a t c h {<br />

}<br />

f i n a l l y {<br />

} J<br />

c r o c = -3 ;<br />

c r o c = 4 ;<br />

if (_______ > 2) {<br />

c r o c ___ dingo;<br />

_.O p e n W r i t e {"wobbiegong" ) ;<br />

_________ < 0 ) {<br />

.O p e n R e a d (" w o b b i e g o n g " );<br />

Р<strong>е</strong>бусы становятся вс<strong>е</strong> бол<strong>е</strong><strong>е</strong> сложны ми, а им<strong>е</strong>на п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нны х вс<strong>е</strong> м<strong>е</strong>н<strong>е</strong><strong>е</strong> оч<strong>е</strong>видны ми. Н ад р<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong>м приходится<br />

много думать! Но р<strong>е</strong>бусы р<strong>е</strong>ш ать н<strong>е</strong> обязат<strong>е</strong>льно, вы мож<strong>е</strong>т<strong>е</strong> просто п<strong>е</strong>р<strong>е</strong>в<strong>е</strong>рнуть страницу и продолжить<br />

чт<strong>е</strong>ни<strong>е</strong>... это для лю бит<strong>е</strong>л<strong>е</strong>й головоломок!<br />

дальш<strong>е</strong> > 473


что мусор для одного — сокровищ<strong>е</strong> для другого<br />

Объ<strong>е</strong>кт FiieStiream<br />

им<strong>е</strong><strong>е</strong>т м<strong>е</strong>тод<br />

OpenReadQ и ст а­<br />

новится причиной<br />

появл<strong>е</strong>ния исключ<strong>е</strong>ния<br />

lOException.<br />

Этот код открыва<strong>е</strong>т<br />

файл wobbiegong. Зат<strong>е</strong>м он<br />

открыва<strong>е</strong>т <strong>е</strong>го повторно.<br />

Но файл н<strong>е</strong> закрыва<strong>е</strong>тся<br />

что приводит к исключ<strong>е</strong>нию<br />

lOException.<br />

Помнит<strong>е</strong>, что ж<strong>е</strong>лат<strong>е</strong>льно<br />

обрабатывать<br />

исключ<strong>е</strong>ния конкр<strong>е</strong>тного<br />

типа. Впроч<strong>е</strong>м, в р<strong>е</strong>бусах<br />

мы д<strong>е</strong>ла<strong>е</strong>м и други<strong>е</strong> в<strong>е</strong>ш,и,<br />

которых нужно изб<strong>е</strong>гать<br />

при написании р<strong>е</strong>альных<br />

программ. Наприм<strong>е</strong>р, мы<br />

выбира<strong>е</strong>м для п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

н<strong>е</strong>значимы<strong>е</strong> им<strong>е</strong>на.<br />

<strong>е</strong> Ш <strong>е</strong> н и <strong>е</strong> ]= » <strong>е</strong> ^ с а Б б а с с <strong>е</strong> й н <strong>е</strong><br />

public static void MainO {<br />

}<br />

Kangaroo joey = new Kangaroo{);<br />

М<strong>е</strong>тод ио<strong>е</strong>у.\А1отЬа±0 вызывался<br />

три раза и на тр<strong>е</strong>тий раз<br />

о<strong>е</strong>рнул ноль. Поэтому м<strong>е</strong>тод<br />

WпteL/neQ вызвал исключ<strong>е</strong>ни<strong>е</strong><br />

Р/У/авВуг<strong>е</strong>гоЕхс<strong>е</strong>рИоп.<br />

int koala = joey.Wombat(joey.Wombat(joey.Wombat(1))); ■^<br />

try {<br />

Console.WriteLine((15 / koala) + " eggs per pound")<br />

}<br />

catch (DivideByZeroException) {<br />

Console.WriteLine("G'Day Mate!");<br />

}<br />

class Kangaroo {<br />

FileStream fs;<br />

int croc;<br />

int dingo = 0 ;<br />

public int Wombat(int wallaby)<br />

dingo ++;<br />

try {<br />

- Этот catch, работа<strong>е</strong>т<br />

только с исключ<strong>е</strong>ниями,<br />

возникшими в р<strong>е</strong>зультат<strong>е</strong><br />

д<strong>е</strong>л<strong>е</strong>ния на ноль.<br />

if (wallaby > 0) {<br />

fs = File.OpenWrite ("wobbiegong");<br />

croc = 0 ;<br />

} else if (wallaby < 0) {<br />

croc = 3 ;<br />

else {<br />

fs = File.OpenRead ("wobbiegong" );<br />

croc = 1;<br />

catch (lOException) {<br />

croc = -3<br />

}<br />

}<br />

return CrOC;<br />

2 ) {<br />

croc -= dingo;<br />

{<br />

^ Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что посл<strong>е</strong> за-<br />

\ в<strong>е</strong>рш<strong>е</strong>ния работы с файлом<br />

\ <strong>е</strong>го тр<strong>е</strong>бу<strong>е</strong>тся закрыть, инач<strong>е</strong><br />

^ файл окаж<strong>е</strong>тся заблокированным.<br />

Попытка снова <strong>е</strong>го открыть<br />

стан<strong>е</strong>т причиной исключ<strong>е</strong>ния<br />

lOException.<br />

474 глава 10


обработка исключ<strong>е</strong>ний<br />

Получ<strong>е</strong>ния информации о пробл<strong>е</strong>м<strong>е</strong><br />

Мы уж<strong>е</strong> н<strong>е</strong>сколько раз повторили, что при появл<strong>е</strong>нии исключ<strong>е</strong>ния .NET<br />

созда<strong>е</strong>т объ<strong>е</strong>кт E x cep tio n . Доступ к н<strong>е</strong>му вы получа<strong>е</strong>т<strong>е</strong> ч<strong>е</strong>р<strong>е</strong>з код блока<br />

c a tc h . Вот как это работа<strong>е</strong>т;<br />

Н<strong>е</strong>кий объ<strong>е</strong>кт выполня<strong>е</strong>т н<strong>е</strong>ки<strong>е</strong> функции, и вдруг н<strong>е</strong>штатная<br />

ситуация приводит к появл<strong>е</strong>нию исключ<strong>е</strong>ния.<br />

Что за <strong>е</strong>рунда<br />

происходит?<br />

О К счастью, срабатыва<strong>е</strong>т блок t r y / c a t c h . Внутри блока c a tc h<br />

исключ<strong>е</strong>нию присваива<strong>е</strong>тся имя ex.<br />

г<br />

i<br />

В<strong>е</strong>ли рядом с объявл<strong>е</strong>ни<strong>е</strong>м<br />

типа исключ<strong>е</strong>ния в блок<strong>е</strong><br />

DoSomethingRisky () ;<br />

__ catch указать имя п<strong>е</strong>р<strong>е</strong>-<br />

------ ------------MCHHOUj эту п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

} можно буд<strong>е</strong>т использоf<br />

catch (RiskyThingException(«^l<br />

вать для доступа к объ -<br />

<strong>е</strong>кту Exception.<br />

}<br />

string message = ex.Message;<br />

MessageBox.Show(message, "Я сильно рисковал!");<br />

e Посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния работы блока c a tc h ссылка ex исч<strong>е</strong>за<strong>е</strong>т,<br />

и объ<strong>е</strong>кт отправля<strong>е</strong>тся в мусорную корзину.<br />

message = ex.Message;<br />

дальш<strong>е</strong> > 475


наборы блоков catch<br />

Обработка исключ<strong>е</strong>ний разных типоб<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, как работать с исключ<strong>е</strong>ни<strong>е</strong>м опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нного типа... но что д<strong>е</strong>лать,<br />

<strong>е</strong>сли код им<strong>е</strong><strong>е</strong>т н<strong>е</strong>сколько пробл<strong>е</strong>мных м<strong>е</strong>ст? Вам мож<strong>е</strong>т потр<strong>е</strong>боваться<br />

обработать набор различных исключ<strong>е</strong>ний. В этом случа<strong>е</strong> н<strong>е</strong> обойтись б<strong>е</strong>з набора<br />

блоков c a tc h . Вот прим<strong>е</strong>р кода для завода по п<strong>е</strong>р<strong>е</strong>работк<strong>е</strong> н<strong>е</strong>ктара, в котором<br />

обрабатываются исключ<strong>е</strong>ния различных типов. В н<strong>е</strong>которых случаях<br />

используются свойства объ<strong>е</strong>кта E x c e p tio n , наприм<strong>е</strong>р, свойство M essage, сод<strong>е</strong>ржащ<strong>е</strong><strong>е</strong><br />

информацию об исключ<strong>е</strong>нии. Можно такж<strong>е</strong> приб<strong>е</strong>гнуть к оп<strong>е</strong>ратору<br />

th ro w для сообщ<strong>е</strong>ний об аномальных ситуациях.<br />

М<strong>е</strong>мод ToStrii^O<br />

исключ<strong>е</strong>ния<br />

позволя<strong>е</strong>т выв<strong>е</strong>сти<br />

в окно MessageBox<br />

относящи<strong>е</strong>ся к д<strong>е</strong>лу<br />

данны<strong>е</strong>.<br />

public void ProcessNectar(NectarVat vat. Bee worker, HiveLog log) {<br />

Иногда {<br />

NectarUnit[] units - worker .EmptyVat (vat) ;<br />

HO вызвать for (int count = 0; count < worker. UnitsExpected, count-ь-н) {<br />

п<strong>е</strong>р<strong>е</strong>хвач<strong>е</strong>нно<strong>е</strong> , . ^<br />

исключ<strong>е</strong>ни<strong>е</strong>. stream hiveLogFile = log.OpenLogFile () ;<br />

ucnolTslfm - worker.AddLogEntry (hiveLogFile) ;<br />

СЯ оп<strong>е</strong>ратор } Если вы н<strong>е</strong> собира<strong>е</strong>т<strong>е</strong>сь испольthrow.<br />

, зовать объ<strong>е</strong>кт Exception, объяв- Набор блоков catch обрабатыва<strong>е</strong>тся по<br />

} лять <strong>е</strong>го н<strong>е</strong> нужно. ^ ^ оч<strong>е</strong>р<strong>е</strong>ди. г, „ В наш<strong>е</strong>м ............. случа<strong>е</strong> сначала рассм а<br />

т рива<strong>е</strong>т ся V atE m ptyE xception, а м т о М<br />

catch (VatEmptyException)^{<br />

HiveLoqException. Посл<strong>е</strong>дний олок eaten оо<br />

vat.Emptied = true;<br />

рабат ы ва<strong>е</strong>т lOException. Это базовый класс<br />

для различных исключ<strong>е</strong>ний, в т ом числ<strong>е</strong><br />

}<br />

для FileNotFoundException (файл н<strong>е</strong> найд<strong>е</strong>н)<br />

^ и E ndO fStream E xception (К о н <strong>е</strong> ц потока).<br />

catch (HiveLogException ex)<br />

throw;<br />

В блок<strong>е</strong> catch объ<strong>е</strong>кту exception сопоставляют п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

<strong>е</strong> х , которая зат<strong>е</strong>м мож<strong>е</strong>т использоваться для<br />

получ<strong>е</strong>ния информации об объ<strong>е</strong>кт<strong>е</strong>.<br />

catch (lOException ex) {<br />

Р^^ЛЯ объ<strong>е</strong>кта worker .AlertQueen ("Ап unspecified file error happened-<br />

Exception 6 различных<br />

блоках + ■ "Message: " -i- ex.Message -i- "\r\n"<br />

можно использовать<br />

одно и то ж<strong>е</strong> "Stack trace: " -ь ex.StackTrace -н "\r\n"<br />

+<br />

имя (<strong>е</strong>х).<br />

+ "Data: " 4- ex.Data -i- "\r\n");<br />

}<br />

finally {<br />

}<br />

v a t .S e a l ();<br />

worker.FinishedJob()<br />

476 глава 10


Один класс созда<strong>е</strong>т исключ<strong>е</strong>ни<strong>е</strong>, другой <strong>е</strong>го обрабатыва<strong>е</strong>т<br />

в мом<strong>е</strong>нт создания класса н<strong>е</strong>изв<strong>е</strong>стно, как с ним будут работать. Иногда<br />

д<strong>е</strong>йствия пользоват<strong>е</strong>л<strong>е</strong>й становятся источником пробл<strong>е</strong>мы. Им<strong>е</strong>нно в этих<br />

сиутациях возникают исключ<strong>е</strong>ния.<br />

обработка исключ<strong>е</strong>ний<br />

- Разум<strong>е</strong><strong>е</strong>тся, дыва<strong>е</strong>т и<br />

тако<strong>е</strong>, что один м<strong>е</strong>тод<br />

мож<strong>е</strong>т формировать исключ<strong>е</strong>ни<strong>е</strong>,<br />

которо<strong>е</strong> ликвидиру<strong>е</strong>тся<br />

другим м<strong>е</strong>тодом<br />

этого ж<strong>е</strong> класса.<br />

Вам нужно заран<strong>е</strong><strong>е</strong> понять, что мож<strong>е</strong>т пойти н<strong>е</strong> так, и пр<strong>е</strong>дусмотр<strong>е</strong>ть план<br />

п<strong>е</strong>р<strong>е</strong>хвата. Вы обычно н<strong>е</strong> видит<strong>е</strong>, какой м<strong>е</strong>тод созда<strong>е</strong>т исключ<strong>е</strong>ни<strong>е</strong>, а какой<br />

устраня<strong>е</strong>т <strong>е</strong>го. Это, как правило, различны<strong>е</strong> м<strong>е</strong>тоды, принадл<strong>е</strong>жащи<strong>е</strong> различным<br />

объ<strong>е</strong>ктам.<br />

Конструктор обь<strong>е</strong>кта BeeProfile<br />

Вм<strong>е</strong>сто того, чтобы...<br />

Б<strong>е</strong>з обработки исключ<strong>е</strong>ний программа п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т<br />

работать. Вот что происходит в программ<strong>е</strong><br />

управл<strong>е</strong>ния профилями пч<strong>е</strong>л.<br />

ожида<strong>е</strong>т имя сод<strong>е</strong>ржащ<strong>е</strong>го<br />

профиль пч<strong>е</strong>лы, чтобы открыть <strong>е</strong>го<br />

м<strong>е</strong>тодом File.OpenQ. Если файл н<strong>е</strong><br />

открыва<strong>е</strong>тся, программа п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т<br />

работать.<br />

stream = File.Open(profile);<br />

FilelMotFoundException was unhandled<br />

Unable to find the specified Я<strong>е</strong>.<br />

^ HW® Обь<strong>е</strong>кт BeeProfile пы т а<strong>е</strong>т - ^<br />

С Я читать от сут ст вую и^и<strong>е</strong>ы .^ " У \<br />

файл, поэтому м<strong>е</strong>тод File.<br />

OpenQ информиру<strong>е</strong>т об исключ<strong>е</strong>нии.<br />

В программ<strong>е</strong> о т ­<br />

внимани<strong>е</strong>, как обь<strong>е</strong>кт<br />

сутству<strong>е</strong>т блок catch, поэтому<br />

исключ<strong>е</strong>ни<strong>е</strong> оста<strong>е</strong>тся<br />

н<strong>е</strong>обработанным.<br />

Y / 1^<strong>е</strong>р<strong>е</strong>дачи в ул<strong>е</strong>й.<br />

...мы мож<strong>е</strong>м поступить так.<br />

Объ<strong>е</strong>кт В<strong>е</strong><strong>е</strong>Рго£11<strong>е</strong> мож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>хватить исключ<strong>е</strong>ни<strong>е</strong><br />

и добавить запись об этом в журнал.<br />

Зат<strong>е</strong>м исключ<strong>е</strong>ни<strong>е</strong> вызыва<strong>е</strong>тся повторно и п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся<br />

в ул<strong>е</strong>й для обработки.<br />

try {<br />

prof = new BeeProfile("prof.dat")<br />

} catch (FileNotFoundException) {<br />

Hive.RecreateBeeProfile("prof.dat<br />

}<br />

■<br />

^ ^ n f i le ( " p r o f .d a t " 4 ^<br />

О<br />

Т<strong>е</strong>п<strong>е</strong>рь<br />

try {<br />

stream = File.Open(profile);<br />

} catch (FileNotFoundException ex) {<br />

WriteLogEntry("unable to find " +<br />

profile + ": " + ex.Message0;<br />

throw;<br />

}<br />

при попытк<strong>е</strong> улья<br />

создать обь<strong>е</strong>кт 8<strong>е</strong><strong>е</strong>РгоР((<strong>е</strong>,<br />

п<strong>е</strong>р<strong>е</strong>дав н<strong>е</strong>в<strong>е</strong>рно<strong>е</strong> имя файла,<br />

бцд<strong>е</strong>т сд<strong>е</strong>лана запись об<br />

ошибк<strong>е</strong> и появится моби^<strong>е</strong>ни<strong>е</strong><br />

об исключ<strong>е</strong>нии. Ул<strong>е</strong>й смож<strong>е</strong>т<br />

обработать исключ<strong>е</strong>ни<strong>е</strong>, на<br />

прим<strong>е</strong>р, пут <strong>е</strong>м<br />

. создания файла с профил<strong>е</strong>м<br />

пч<strong>е</strong>лы.<br />

дальш<strong>е</strong> > 477


ваш<strong>е</strong> собств<strong>е</strong>нно<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong><br />

исключ<strong>е</strong>ни<strong>е</strong> OutOfHoney для пч<strong>е</strong>л<br />

М<strong>е</strong>тоды показывают таков<br />

исключ<strong>е</strong>ни<strong>е</strong> при н<strong>е</strong>корр<strong>е</strong>ктных<br />

знач<strong>е</strong>ниях парам<strong>е</strong>тров.<br />

Ваши классы могут формировать собств<strong>е</strong>нны<strong>е</strong> исключ<strong>е</strong>ния. Наприм<strong>е</strong>р, при получ<strong>е</strong>нии<br />

внутри м<strong>е</strong>тода парам<strong>е</strong>тра null вм<strong>е</strong>сто ожида<strong>е</strong>мого знач<strong>е</strong>ния им<strong>е</strong><strong>е</strong>т смысл использовать<br />

исключ<strong>е</strong>ни<strong>е</strong>, которо<strong>е</strong> вызыва<strong>е</strong>т в такой ситуации .NET:<br />

Message<br />

StackTrace<br />

Exception<br />

GetBaseExceptionO<br />

ToStringO<br />

throw new ArgumentException(); ^<br />

Ho иногда исключ<strong>е</strong>ни<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся из-за особых обстоят<strong>е</strong>льств, возникающих в проц<strong>е</strong>сс<strong>е</strong><br />

работы программы. Наприм<strong>е</strong>р, колич<strong>е</strong>ство м<strong>е</strong>да, потр<strong>е</strong>бля<strong>е</strong>мого пч<strong>е</strong>лой, зависит<br />

от <strong>е</strong><strong>е</strong> в<strong>е</strong>са. Но для ситуации, когда м<strong>е</strong>да в уль<strong>е</strong> н<strong>е</strong> осталось, им<strong>е</strong><strong>е</strong>т смысл создать<br />

собств<strong>е</strong>нно<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong>. Для этого потр<strong>е</strong>бу<strong>е</strong>тся класс, насл<strong>е</strong>дующий от класса<br />

Exception.<br />

c l a s s O u tO fH o n ey E x cep tio n : S y s t e m .E x c e p t io n {<br />

your Exception<br />

StackTrace<br />

GetBaseExceptionO<br />

ToStringO<br />

p i i b l i c O u t O fH o n e y E x c e p tio n ( s tr in g m e s s a g e ) : b a s e ( m e s s a g e ) { }<br />

} Для ваш<strong>е</strong>го исключ<strong>е</strong>ния потр<strong>е</strong>бу<strong>е</strong>тся класс,<br />

c l a s s H o n e y D e liv e r y S y s te m { который долж<strong>е</strong>н быть производным по от -<br />

^ нош<strong>е</strong>нию к классу System.Exception. Обратит<strong>е</strong><br />

внимани<strong>е</strong>, каким образом п<strong>е</strong>р<strong>е</strong>гружа<strong>е</strong>тся<br />

, конструктор, чтобы п<strong>е</strong>р<strong>е</strong>дать соотц<strong>е</strong>ни<strong>е</strong> об<br />

p u b l i c v o i d F eedH oneyT oE ggs О { исключ<strong>е</strong>нии.<br />

}<br />

i f (h o n e y L e v e l ==0) {<br />

th r o w new O u tO fH o n e y E x c e p tio n ( "The h i v e i s o u t o f h o n e y ." ) ;<br />

) . 1 . . ( ,— Вызыва<strong>е</strong>тся новый экз<strong>е</strong>мпляр обьf<br />

o r e a c h (E gg e g g i n E g g s) { “ ) При наличии в ульТ '^"' except/on.<br />

p u b l i c p a r t i a l c l a s s F orm l : Form {<br />

С ‘исключ<strong>е</strong>ни<strong>е</strong> н<strong>е</strong><br />

J ‘появля<strong>е</strong>тся и управл<strong>е</strong>ни<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся<br />

этому коду.<br />

p r i v a t e v o i d c o n s u m e H o n e y _ C lic k (o b je c t s e n d e r , E v e n tA r g s e ) {<br />

H o n e y D e liv e r y S y s te m d e l i v e r y = new H o n e y D e liv e r y S y s te m ( ) ;<br />

t r y {<br />

}<br />

d e l i v e r y . F eedH oneyT oE ggs () илля пользоват&льского


обработка исключ<strong>е</strong>ний<br />

public static void MainO {<br />

Console.Write("when it<br />

ExTestDrive.Zero{"yes")<br />

Console.Write(" it ");<br />

ExTestDrive.Zero("no");<br />

Console.WriteLine(".");<br />

I Ц с Ю П о Ч и ш <strong>е</strong> Л ь Н ы <strong>е</strong> М а Г н и т ь !<br />

Расположит<strong>е</strong> магниты с кодом таким образом,<br />

чтобы на консоль был выв<strong>е</strong>д<strong>е</strong>н<br />

сл<strong>е</strong>дующий р<strong>е</strong>зультат.<br />

Р<strong>е</strong>зультат:<br />

► when it thaws it throws.<br />

class MyException : Exception { }<br />

P u b l j ^ ^ ^ a t i c v o id Z ero ( s t r i n g t e s t ) {<br />

s t a t i c v o i d D o R is k y ( S t r in g t ) {<br />

C o n s o le .W r it e ( " h " ) ;<br />

дальш<strong>е</strong> ► 479


н<strong>е</strong>большой обзор<br />

public static void MainO {<br />

Console.Write{"when it ");<br />

ExTestDrive.Zero("yes");<br />

Console.Write(" it ");<br />

ExTestDrive.Zero("no");<br />

Console.WriteLine("."); ><br />

}<br />

class MyException : Exception { }<br />

Задачи с МаГнищаМи<br />

Расположит<strong>е</strong> магниты с кодом таким образом,<br />

чтобы на консоль был выв<strong>е</strong>д<strong>е</strong>н сл<strong>е</strong>дующий р<strong>е</strong>зультат.<br />

Р<strong>е</strong>зультат:<br />

— ► when it thaws it throws.<br />

Эта строчка опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

пользоват<strong>е</strong>льско<strong>е</strong><br />

исключ<strong>е</strong>ни<strong>е</strong> МцЕнс<strong>е</strong>рНоп,<br />

которо<strong>е</strong> обрабатыва<strong>е</strong>тся<br />

в блок<strong>е</strong> catch.<br />

c l a s s E x T e s tD r iv e {<br />

p u b l i c s t a t i c v o i d Z e r o ( s t r i n g t e s t ) {<br />

C o n s o le . W r it e ( " t " ) ;<br />

D o R i s k y ( t e s t ) ;<br />

C onsole.W rite ( " о " ) ;<br />

} c a t c h ( M y E x c e p t i o n ) {<br />

8 зависимости от. mozoj<br />

какой парам<strong>е</strong>тр test<br />

был п<strong>е</strong>р<strong>е</strong>дан м<strong>е</strong>тоду<br />

ZeroQ (строка yes или<br />

чт о-т о друго<strong>е</strong>), выводится<br />

строка thaws или<br />

throws.<br />

Эта строчка выполня<strong>е</strong>тся<br />

только в случа<strong>е</strong>,<br />

когда м<strong>е</strong>тод doRiskyQ<br />

н<strong>е</strong> становится причиной<br />

появл<strong>е</strong>ния исключ<strong>е</strong>ния.<br />

I<br />

} f i n a l l y {<br />

1<br />

C o n so le .W rite (" W " ) ;<br />

C o n s o le . W r it e ( " s " ) ;<br />

G J<br />

s t a t i c v o i d D o R is k y ( S t r in g t ) {<br />

C o n s o le .W r i t e ( "h") ;<br />

i f ( t = " y e s" ) {<br />

I<br />

th r o w new M y E x c e p tio n ( ) ;<br />

}<br />

t o n s o le .W r it e ( " r " ) ;<br />

□<br />

/ 5лок finally гарантирц<strong>е</strong>т,<br />

[ что м<strong>е</strong>тод вс<strong>е</strong>гда выоо-<br />

1 I дит символ W . А так как<br />

ф f символ S выводится вн<strong>е</strong><br />

1 обработчика исключ<strong>е</strong>ний,<br />

\ он так ж<strong>е</strong> вс<strong>е</strong>гда попада<strong>е</strong>т<br />

в список вывода.<br />

]<br />

М<strong>е</strong>тод doRiskyO вы-<br />

п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> <strong>е</strong>му строки'^<br />

480 глава 10


КЛЮЧЕВЫЕ<br />

МОМЕНТЫ<br />

Причиной исключ<strong>е</strong>ния мож<strong>е</strong>т стать любой оп<strong>е</strong>ратор.<br />

Для обработки исключ<strong>е</strong>ний пользуйт<strong>е</strong>сь блоком<br />

try/catch. Н<strong>е</strong>обработанны<strong>е</strong> исключ<strong>е</strong>ния приводят<br />

к пр<strong>е</strong>кращ<strong>е</strong>нию работы программы.<br />

Обнаруж<strong>е</strong>ни<strong>е</strong> исключ<strong>е</strong>ния в блок<strong>е</strong> try приводит<br />

к н<strong>е</strong>м<strong>е</strong>дл<strong>е</strong>нной п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> управл<strong>е</strong>ния п<strong>е</strong>рвому оп<strong>е</strong>ратору<br />

блока catch.<br />

Объ<strong>е</strong>кт Exception сод<strong>е</strong>ржит информацию об<br />

исключ<strong>е</strong>нии. Объявив п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную Exception<br />

в оп<strong>е</strong>ратор<strong>е</strong> catch, вы получа<strong>е</strong>т<strong>е</strong> доступ к информации<br />

об исключ<strong>е</strong>нии, появивш<strong>е</strong>мся в блок<strong>е</strong> try:<br />

try {<br />

// оп<strong>е</strong>раторы, которы<strong>е</strong> могут<br />

// вызвать исключ<strong>е</strong>ни<strong>е</strong><br />

} catch (lOException ex) {<br />

// информация об исключ<strong>е</strong>нии<br />

// сод<strong>е</strong>ржится в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной <strong>е</strong>х<br />

}<br />

Сущ<strong>е</strong>ствуют различны<strong>е</strong> типы исключ<strong>е</strong>ний. Каждому<br />

соотв<strong>е</strong>тству<strong>е</strong>т объ<strong>е</strong>кт, унасл<strong>е</strong>дованный от класса<br />

Exception. Старайт<strong>е</strong>сь изб<strong>е</strong>гать обнаруж<strong>е</strong>ния<br />

исключ<strong>е</strong>ний «вообщ<strong>е</strong>», работайт<strong>е</strong> с исключ<strong>е</strong>ниями<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нного типа.<br />

обработка исключ<strong>е</strong>ний<br />

Каждому оп<strong>е</strong>ратору try мож<strong>е</strong>т соотв<strong>е</strong>тствовать<br />

н<strong>е</strong>сколько оп<strong>е</strong>раторов catch:<br />

try { ... }<br />

catch (NullReferenceException ex) {<br />

// эти оп<strong>е</strong>раторы срабатывают при<br />

// NullReferenceException<br />

}<br />

catch (OverflowException ex) { ... }<br />

catch (FileNotFoundException) { ... }<br />

catch (ArgumentException) { ... }<br />

Для сообщ<strong>е</strong>ния об анамальных ситуациях использу<strong>е</strong>тся<br />

оп<strong>е</strong>ратор throw:<br />

throw new Exception ("Сообщ<strong>е</strong>ни<strong>е</strong>");<br />

Оп<strong>е</strong>ратор throw позволя<strong>е</strong>т повторно вызвать п<strong>е</strong>р<strong>е</strong>хвач<strong>е</strong>нно<strong>е</strong><br />

искпюч<strong>е</strong>ни<strong>е</strong>, но только внутри блока catch.<br />

Насл<strong>е</strong>довани<strong>е</strong>м от класса Exception можно<br />

создать пользоват<strong>е</strong>льско<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong>.<br />

class CustomException : Exception;<br />

В большинств<strong>е</strong> случа<strong>е</strong>в достаточно встро<strong>е</strong>нных<br />

исключ<strong>е</strong>ний .NET. Приб<strong>е</strong>гая к различным типам<br />

исключ<strong>е</strong>ний, вы пр<strong>е</strong>доставля<strong>е</strong>т<strong>е</strong> больш<strong>е</strong> информации<br />

пользоват<strong>е</strong>лю.<br />

Оп<strong>е</strong>ратор using как комбинация<br />

оп<strong>е</strong>раторов try и finally<br />

Объявляя ссылку внутри оп<strong>е</strong>ратора<br />

usin^j вы автоматич<strong>е</strong>ски вызыва<strong>е</strong>т<strong>е</strong><br />

в конц<strong>е</strong> блока оп<strong>е</strong>раторов м<strong>е</strong>тод<br />

DisposeQ.<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что оп<strong>е</strong>ратор u s in g гарантиру<strong>е</strong>т<br />

закрыти<strong>е</strong> ваших файлов. 1^1ногда он мож<strong>е</strong>т использоваться<br />

и как б ы с т р ы й в ы з о в для оп<strong>е</strong>раторов<br />

try и finally!<br />

u s i n g<br />

( Y o u r C l a s s с<br />

/ / код<br />

= n e w Y o u r C l a s s 0 ) {<br />

аналогично ^<br />

Y o u r C la ss с = new Y o u r C la s s О ;<br />

t r y {<br />

При вызов<strong>е</strong> м <strong>е</strong>т о-<br />

T>.,-NT (j/2 Г)/СЬолглА й S . ^ . .<br />

/ / и илок<strong>е</strong><br />

rinaliy можно ис-<br />

} f i n a l l y { j пользовать сокра-<br />

'/ц<strong>е</strong>нную запись с<br />

с .D is p o s e 0 ; ^оп<strong>е</strong>ратором using.<br />

}<br />

}<br />

дальш<strong>е</strong> > 481


н<strong>е</strong>большо<strong>е</strong> пр<strong>е</strong>дупр<strong>е</strong>жд<strong>е</strong>ни<strong>е</strong><br />

11зб<strong>е</strong>га<strong>е</strong>м исключ<strong>е</strong>ний при помощи инт<strong>е</strong>рф<strong>е</strong>йса<br />

IDisposable<br />

.Инт<strong>е</strong>рф<strong>е</strong>йс IDisposable позволя<strong>е</strong> т<br />

изб<strong>е</strong>жать распростран<strong>е</strong>нных исключ<strong>е</strong>нии.<br />

Используйт<strong>е</strong> оп<strong>е</strong>ратор<br />

исusing<br />

при работ<strong>е</strong> с р<strong>е</strong>ализующими<br />

эт от инт<strong>е</strong>рф<strong>е</strong>йс классами.<br />

Потоки снабж<strong>е</strong>ны кодом для их закрытия посл<strong>е</strong> удал<strong>е</strong>ния объ<strong>е</strong>кта. Но что д<strong>е</strong>лать с пользоват<strong>е</strong>льским<br />

объ<strong>е</strong>ктом, посл<strong>е</strong> удал<strong>е</strong>ния которого тр<strong>е</strong>бу<strong>е</strong>тся произв<strong>е</strong>сти н<strong>е</strong>ки<strong>е</strong> д<strong>е</strong>йствия? Им<strong>е</strong><strong>е</strong>т смысл написать свой<br />

код для случая, когда объ<strong>е</strong>кт использу<strong>е</strong>тся внутри оп<strong>е</strong>ратора u sin g .<br />

В <strong>C#</strong> это можно сд<strong>е</strong>лать при помощи инт<strong>е</strong>рф<strong>е</strong>йса<br />

ID isp o s a b le . Р<strong>е</strong>ализуйт<strong>е</strong> <strong>е</strong>го и вставьт<strong>е</strong> освобождающий<br />

р<strong>е</strong>сурсы код в м<strong>е</strong>тод D isp o se (),<br />

как показано ниж<strong>е</strong>:<br />

c l a s s N e c t a r :<br />

I D i s p o s a b l e<br />

p r i v a t e d o u b l e a m o u n t;<br />

p r i v a t e B e e H i v e h i v e ;<br />

p r i v a t e S t r e a m h i v e L o g ;<br />

p u b l i c N e c t a r ( d o u b l e a m o u n t ,<br />

t h i s . a m o u n t = a m o u n t;<br />

t h i s . h i v e = h i v e ;<br />

t h i s . h i v e L o g = h i v e L o g ;<br />

}<br />

p i i b l i c v o i d D i s p o s e О<br />

У<br />

i f (a m o x m t > 0 ) {<br />

}<br />

h i v e . A d d ( a m o u n t ) ;<br />

h i v e . W r i t e L o g ( h i v e L o g ,<br />

a m o u n t = 0 ;<br />

{<br />

{<br />

®оп<strong>е</strong>ратор<strong>е</strong> using<br />

— можно только при условии р<strong>е</strong>ализации<br />

им инт<strong>е</strong>рф<strong>е</strong>йса IDisposable^ Ъ противном<br />

SyTeZ<br />

компилироваться н<strong>е</strong><br />

Объ<strong>е</strong>кт, который пр<strong>е</strong>дполага<strong>е</strong>тся использовать вм<strong>е</strong>ст<strong>е</strong><br />

^DisposablT^^ долж<strong>е</strong>н р<strong>е</strong>ализовывать инт<strong>е</strong>рф<strong>е</strong>йс<br />

B e e H i v e h i v e . S t r e a m h i v e L o g ) {<br />

Sudem выполн<strong>е</strong>но в конц<strong>е</strong> оп<strong>е</strong>ратора using.<br />

sL-<br />

М<strong>е</strong>тод<br />

DisposeQ<br />

уж<strong>е</strong> написан,<br />

так что он<br />

мож<strong>е</strong>т быть<br />

a m o u n t + " mg n e c t a r a d d e d t o t h e h i v e " ) ; вызван произ-<br />

/ вольно<strong>е</strong> коли-<br />

^ ч<strong>е</strong>ство раз.<br />

В руководств<strong>е</strong> по р<strong>е</strong>ализации инт<strong>е</strong>рф <strong>е</strong>йса<br />

i D i s p o s e сказано, что м<strong>е</strong>тод D is p o s e О<br />

можно вызы вать много раз. Вы понима<strong>е</strong>т<strong>е</strong><br />

важность этого обстоят<strong>е</strong>льства?<br />

Т<strong>е</strong>п<strong>е</strong>рь можно н<strong>е</strong>сколько раз воспользоваться оп<strong>е</strong>ратором<br />

u sin g . Возьм<strong>е</strong>м встро<strong>е</strong>нный объ<strong>е</strong>кт Stream , р<strong>е</strong>ализующий<br />

ID isp o s a b le , как и наш обновл<strong>е</strong>нный объ<strong>е</strong>кт N ectar:<br />

Влож<strong>е</strong>нны<strong>е</strong> оп<strong>е</strong>раторы using используются<br />

при н<strong>е</strong>обходимости объявить<br />

дб<strong>е</strong> ссылки на инт<strong>е</strong>рф<strong>е</strong>йс IDisposable<br />

о одном блок<strong>е</strong> кода.<br />

u s in g (S tream lo g = new F i l e .W r i t e ( " l o g . t x t " ))<br />

u s in g (N e c ta r n e c ta r = new N e c ta r ( 1 6 .3 , h iv e , lo g )) {<br />

B e e .F ly T o (flo w e r) ;<br />

Объ<strong>е</strong>кт Nectar использу<strong>е</strong>т поток<br />

B ee. H a rv e st (n e c ta r) ; j автоматич<strong>е</strong>ски закрываюи^иися<br />

Bee. FlyTo (h iv e) ; у S к о н ц <strong>е</strong> вн<strong>е</strong>илн<strong>е</strong>го оп<strong>е</strong>ратора using.<br />

482 глава 10


я правильно понимаю, что<br />

объ<strong>е</strong>кты, р<strong>е</strong>ализующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс<br />

I D is p o s a b le , используются только<br />

внутри оп<strong>е</strong>ратора u s in g ?<br />

^ ! Да. Инт<strong>е</strong>рф<strong>е</strong>йс ID is p o s a b le<br />

пр<strong>е</strong>дназнач<strong>е</strong>н для работы с оп<strong>е</strong>ратором<br />

u s in g , и добавл<strong>е</strong>ни<strong>е</strong> этого оп<strong>е</strong>ратора<br />

эквивал<strong>е</strong>нтно созданию экз<strong>е</strong>мпляра класса,<br />

только тут вс<strong>е</strong>гда вызыва<strong>е</strong>тся м<strong>е</strong>тод<br />

Dispose{).<br />

Любой ли оп<strong>е</strong>ратор мож<strong>е</strong>т быть<br />

Iом<strong>е</strong>щ<strong>е</strong>н в блок u s in g ?<br />

^ ! Разум<strong>е</strong><strong>е</strong>тся. Оп<strong>е</strong>ратор u s in g вс<strong>е</strong>го<br />

лишь гарантиру<strong>е</strong>т уничтож<strong>е</strong>ни<strong>е</strong> любого<br />

созданного вами объ<strong>е</strong>кга. Но использовать<br />

эти объ<strong>е</strong>кгы вы мож<strong>е</strong>т<strong>е</strong> на сво<strong>е</strong> усмотр<strong>е</strong>ни<strong>е</strong>.<br />

Можно даж<strong>е</strong> создать объ<strong>е</strong>кт при<br />

помощи оп<strong>е</strong>ратора u s in g и н<strong>е</strong> упоминать<br />

<strong>е</strong>го внутри блока. Впроч<strong>е</strong>м, это н<strong>е</strong> им<strong>е</strong><strong>е</strong>т<br />

практич<strong>е</strong>ского смысла.<br />

часацо<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Б о ц р о с ь !<br />

Мож<strong>е</strong>т ли м<strong>е</strong>тод быть вызван<br />

D is p o s e О вн<strong>е</strong> оп<strong>е</strong>ратора u s in g ?<br />

Q ; Кон<strong>е</strong>чно. На самом д<strong>е</strong>л<strong>е</strong> в этом<br />

случа<strong>е</strong> оп<strong>е</strong>ратор using вообщ<strong>е</strong> н<strong>е</strong> нуж<strong>е</strong>н.<br />

Вызывайт<strong>е</strong> м<strong>е</strong>тод Dispose (), зав<strong>е</strong>ршив<br />

работу с объ<strong>е</strong>ктом. Он высвободит<br />

указанны<strong>е</strong> р<strong>е</strong>сурсы, как и при вызов<strong>е</strong><br />

вручную м<strong>е</strong>тода Close {) для потока.<br />

Оп<strong>е</strong>ратор using вс<strong>е</strong>го лишь обл<strong>е</strong>та<strong>е</strong>т<br />

чт<strong>е</strong>ни<strong>е</strong> и понимани<strong>е</strong> кода и пр<strong>е</strong>дотвраща<strong>е</strong>т<br />

пробл<strong>е</strong>мы, которы<strong>е</strong> могуг возникнуть, <strong>е</strong>сли<br />

н<strong>е</strong> удалить объ<strong>е</strong>кт.<br />

!)• Вы упомянули блок t r y / f i n a l l y ,<br />

знача<strong>е</strong>т ли это, что оп<strong>е</strong>раторы t r y<br />

и f i n a l l y могут фигурировать б<strong>е</strong>з<br />

оп<strong>е</strong>ратора c a tc h ?<br />

О! Да! Вы мож<strong>е</strong>т<strong>е</strong> скомбинировать<br />

ж try н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно с блоком<br />

finally, как показано зд<strong>е</strong>сь:<br />

обработка исключ<strong>е</strong>ний<br />

try {<br />

DoSomethingRiskyО ;<br />

SomethingElseRisky();<br />

}<br />

finally {<br />

AlwaysExecuteThis{);<br />

}<br />

При обнаруж<strong>е</strong>нии исключ<strong>е</strong>ния в м<strong>е</strong>тод<strong>е</strong><br />

DoSomethingRisky О н<strong>е</strong>м<strong>е</strong>дл<strong>е</strong>нно<br />

буд<strong>е</strong>т запущ<strong>е</strong>н блок f inal 1у.<br />

Правда ли, что м<strong>е</strong>тод D is p o s e О<br />

работа<strong>е</strong>т только с файлами и потоками?<br />

О<br />

; Н<strong>е</strong>т, многи<strong>е</strong> классы р<strong>е</strong>ализуют<br />

инт<strong>е</strong>рф<strong>е</strong>йс IDisposable, и при<br />

работ<strong>е</strong> с ними вс<strong>е</strong>гда нужно использовать<br />

оп<strong>е</strong>ратор using. (С н<strong>е</strong>которыми из этих<br />

классов вы познакомит<strong>е</strong>сь в сл<strong>е</strong>дующ<strong>е</strong>й<br />

глав<strong>е</strong>.) Если вы пиш<strong>е</strong>т<strong>е</strong> класс, который<br />

нужно утилизировать опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным<br />

способом, таюк<strong>е</strong> р<strong>е</strong>ализуйт<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс<br />

IDisposable.<br />

Если блоки try/catch — это такой<br />

пол<strong>е</strong>зный инструм<strong>е</strong>нт, поч<strong>е</strong>му он н<strong>е</strong><br />

использу<strong>е</strong>тся по умолчанию, а нам<br />

приходится вводить код вручную?<br />

Сначала нужно опр<strong>е</strong>д<strong>е</strong>лить тип появляющ<strong>е</strong>гося<br />

исключ<strong>е</strong>ния, чтобы правильно <strong>е</strong>го обработать.<br />

В<strong>е</strong>дь обработка исключ<strong>е</strong>ний н<strong>е</strong> сводится к выводу стандартного<br />

сообщ<strong>е</strong>ния об ошибк<strong>е</strong>. Скаж<strong>е</strong>м, в программ<strong>е</strong><br />

для поиска оправданий, зная о появл<strong>е</strong>нии исключ<strong>е</strong>ния<br />

FileNotFoundException, можно выв<strong>е</strong>сти сообщ<strong>е</strong>ни<strong>е</strong><br />

с сов<strong>е</strong>том, гд<strong>е</strong> искать нужны<strong>е</strong> файлы. А в случа<strong>е</strong> исключ<strong>е</strong>ний,<br />

связанных с базами данных, можно по эл<strong>е</strong>ктронной<br />

почт<strong>е</strong> отправить сообщ<strong>е</strong>ни<strong>е</strong> администратору. Так<br />

что вс<strong>е</strong> ваши д<strong>е</strong>йствия зависят от типа обнаруж<strong>е</strong>нного<br />

исключ<strong>е</strong>ния.<br />

Им<strong>е</strong>нно поэтому так<br />

много классов насл<strong>е</strong>дуют<br />

от^класса Exception. Порой<br />

вам даж<strong>е</strong> приходится<br />

писать таки<strong>е</strong> классы<br />

самостоят<strong>е</strong>льно.<br />

дальш<strong>е</strong> * 483


упущ<strong>е</strong>нны<strong>е</strong> возможности<br />

Hauxyguiuu бариант блока catch<br />

Блок c a tc h позволя<strong>е</strong>т программ<strong>е</strong> продолжить работу.<br />

Появивш<strong>е</strong><strong>е</strong>ся исключ<strong>е</strong>ни<strong>е</strong> обрабатыва<strong>е</strong>тся и вм<strong>е</strong>сто аварийной<br />

остановки и сообщ<strong>е</strong>ния об ошибк<strong>е</strong> вы двига<strong>е</strong>т<strong>е</strong>сь<br />

дальш<strong>е</strong>. Но это н<strong>е</strong> вс<strong>е</strong>гда хорошо.<br />

Рассмотрим странно работающий класс C a lc u la to r .<br />

Что ж<strong>е</strong> происходит?<br />

c l a s s C a lc u la t o r {<br />

p i i b l i c v o id D iv id e ( i n t d iv i d e n d , i n t d i v i s o r ) {<br />

t r y {<br />

Если д<strong>е</strong>лит<strong>е</strong>ль<br />

рав<strong>е</strong>н нулю, появля<strong>е</strong>тся<br />

исключ<strong>е</strong>ни<strong>е</strong>^<br />

- pivdeB yZeroE xception.<br />

t h i s . q u o t i e n t = d iv id e n d / d i v i s o r ;<br />

} catch { — "■<br />

I I Прим<strong>е</strong>чани<strong>е</strong> <strong>Дж</strong>има: нужно п о н я т ь , как п р <strong>е</strong>д о т в р а т и т ь в в од<br />

Поч<strong>е</strong>му н<strong>е</strong>смот ря на наличи<strong>е</strong><br />

олока catch мы получа<strong>е</strong>м с о -<br />

оощ<strong>е</strong>ни<strong>е</strong> об ошибк<strong>е</strong>?<br />

/ / п ол ь зоват<strong>е</strong>л я ош н у л <strong>е</strong> в о г о зн а ч <strong>е</strong>н и я в д <strong>е</strong> л и т <strong>е</strong> л ь .<br />

11сЬюч<strong>е</strong>ния дод)кны обрабатываться,<br />

а н<strong>е</strong> скрываться<br />

П рограм м ист подум ал,<br />

что смож <strong>е</strong>т скрыть<br />

исключ<strong>е</strong>ния при помощи<br />

пуст ого блока catch,<br />

но вс<strong>е</strong>го лишь создал<br />

пробл<strong>е</strong>м у пользоват <strong>е</strong>лям<br />

програм м ы .<br />

Тот факт, что программа продолжа<strong>е</strong>т работу, н<strong>е</strong> означа<strong>е</strong>т обработки исключ<strong>е</strong>ний.<br />

Написанный выш<strong>е</strong> код н<strong>е</strong> буд<strong>е</strong>т аварийно остановл<strong>е</strong>н... по<br />

крайн<strong>е</strong>й м<strong>е</strong>р<strong>е</strong>, н<strong>е</strong> в м<strong>е</strong>тод<strong>е</strong> D iv id e (). Но что <strong>е</strong>сли этот м<strong>е</strong>тод вызыва<strong>е</strong>тся<br />

другим м<strong>е</strong>тодом, который пыта<strong>е</strong>тся выв<strong>е</strong>сти р<strong>е</strong>зультат? При рав<strong>е</strong>нств<strong>е</strong><br />

д<strong>е</strong>лит<strong>е</strong>ля нулю, м<strong>е</strong>тод, скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го, в<strong>е</strong>рн<strong>е</strong>т н<strong>е</strong>правильно<strong>е</strong> (и н<strong>е</strong>ожиданно<strong>е</strong>)<br />

знач<strong>е</strong>ни<strong>е</strong>.<br />

Нужно н<strong>е</strong> просто добавить комм<strong>е</strong>нтарий, а обработать исключ<strong>е</strong>ни<strong>е</strong>.<br />

Даж<strong>е</strong> <strong>е</strong>сли вы н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что д<strong>е</strong>лать, н<strong>е</strong> оста<strong>е</strong>ляйт<strong>е</strong> блок catch пустым или<br />

закомм<strong>е</strong>нтированным! Это лишь усложня<strong>е</strong>т пользовани<strong>е</strong> программой.<br />

Лучш<strong>е</strong> пусть появится сообщ<strong>е</strong>ни<strong>е</strong> об исключ<strong>е</strong>нии, это хотя бы позволя<strong>е</strong>т<br />

понять, что им<strong>е</strong>нно работа<strong>е</strong>т н<strong>е</strong> так.<br />

Помнит<strong>е</strong>, что <strong>е</strong>сли<br />

исключ<strong>е</strong>ни<strong>е</strong> н<strong>е</strong> обрабатыва<strong>е</strong>тся,,<br />

оно поднима<strong>е</strong>тся<br />

вв<strong>е</strong>рк в ст<strong>е</strong>к<strong>е</strong><br />

вызовов. Это тож<strong>е</strong><br />

сво<strong>е</strong>го рода обработка.<br />

484 глава 10


обработка исключ<strong>е</strong>ний<br />

Вр<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ния<br />

Иногда, столкнувшись с пробл<strong>е</strong>мой, вы н<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, что д<strong>е</strong>лать.<br />

В этом случа<strong>е</strong> им<strong>е</strong><strong>е</strong>т смысл вн<strong>е</strong>сти запись в журнал,<br />

снабдив <strong>е</strong><strong>е</strong> прим<strong>е</strong>чани<strong>е</strong>м. Это н<strong>е</strong> так хорошо, как обработка<br />

исключ<strong>е</strong>ния, но лучш<strong>е</strong>, ч<strong>е</strong>м нич<strong>е</strong>го.<br />

Вот вр<strong>е</strong>м<strong>е</strong>нно<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> для калькулятора:<br />

-К сожал<strong>е</strong>нию, в р<strong>е</strong>альной жизни «вр<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>»<br />

р<strong>е</strong>ш<strong>е</strong>ния зачастую становятся постоянными.<br />

c l a s s C a lc u la t o r {<br />

p x ib llc v o i d D iv id e ( i n t d iv i d e n d , i n t d i v i s o r ) {<br />

t r y {<br />

t h i s . q u o t i e n t = d iv id e n d / d i v i s o r ;<br />

} c a t c h ( E x c e p tio n e x ) {<br />

u s i n g (S tr e a m W r ite r sw = new S t r e a m W r it e r ( @ " C : \L o g s \e r r o r s .t x t " ) ;<br />

s w .W r it e L in e ( e x .g e t M e s s a g e ( ) ) ;<br />

}<br />

-----------^<br />

Я понял! М ы использу<strong>е</strong>м<br />

обработку исключ<strong>е</strong>ний, чтобы<br />

пом<strong>е</strong>тить пробл<strong>е</strong>мную область.<br />

Пробл<strong>е</strong>ма никуда н<strong>е</strong> исч<strong>е</strong>зла,<br />

но по крайн<strong>е</strong>й м<strong>е</strong>р<strong>е</strong>, стало<br />

Т с и о гд<strong>е</strong> она возникла. Лучш<strong>е</strong><br />

вс<strong>е</strong>го разобраться, поч<strong>е</strong>му<br />

ваш м<strong>е</strong>тод р Ш <strong>е</strong> вызыва<strong>е</strong>т<br />

ся при нул<strong>е</strong>вом знйМ<strong>е</strong>нйт<strong>е</strong>м<br />

м устранить эту возмож<br />

ность.<br />

Обработка исключ<strong>е</strong>ния дал<strong>е</strong>ко н<strong>е</strong> вс<strong>е</strong>гда<br />

означа<strong>е</strong>т УСТРАНЕНИЕ исключ<strong>е</strong>ния.<br />

Возможность аварийной остановки программы<br />

—это плохо. Но н<strong>е</strong>понимани<strong>е</strong> причин такого<br />

пов<strong>е</strong>д<strong>е</strong>ния намного хуж<strong>е</strong>. Поэтому вс<strong>е</strong>гда нужно<br />

обрабатывать ошибки, которы<strong>е</strong> вы мож<strong>е</strong>т<strong>е</strong> пр<strong>е</strong>дсказать,<br />

и записывать в журнал информацию<br />

об ошибках, с которыми вы н<strong>е</strong> ум<strong>е</strong><strong>е</strong>т<strong>е</strong> бороться.<br />

дальш<strong>е</strong> у 485


н<strong>е</strong>сколько пр<strong>е</strong>длож<strong>е</strong>ний<br />

кратки<strong>е</strong> принципы обработки исключ<strong>е</strong>ний<br />

Красиво оформляйт<strong>е</strong> коВ обработки ошибок.<br />

Пр<strong>е</strong>доставляйт<strong>е</strong> ИНФОРМАТИВНЫЕ сообщ<strong>е</strong>ния<br />

об ошибках.<br />

Старайт<strong>е</strong>сь приб<strong>е</strong>гать к встро<strong>е</strong>нным исключ<strong>е</strong>ниям<br />

.НЕТ^ а н<strong>е</strong> создавать собств<strong>е</strong>нны<strong>е</strong>.<br />

Думайт<strong>е</strong> о том, как можно сократить код<br />

блок<strong>е</strong> ігу.<br />

...и само<strong>е</strong> главно<strong>е</strong>...<br />

Изб<strong>е</strong>гайт<strong>е</strong> ошибок, связанных с файлами... вс<strong>е</strong>гда I другими<br />

эл<strong>е</strong>уи<strong>е</strong>нтйл1к,<br />

I польЩйт<strong>е</strong>сь блоком работая с потоками! I<br />

Ш Ж 1 т А .<br />

486 глава 10


обработка исключ<strong>е</strong>ний<br />

^ п^р пар жа жн ( н ш <strong>е</strong><br />

О<br />

В осп ользуй т<strong>е</strong> сь блоком try/catch/finally д ля обработки исклю ч<strong>е</strong>ний<br />

в програм м <strong>е</strong> E x c u se M a n a g e r Б райана.<br />

Добавьт<strong>е</strong> к обработчику события Click кнопки Open обработку исключ<strong>е</strong>ния. Достаточно<br />

блока try/catch, вызывающ<strong>е</strong>го окно с сообщ<strong>е</strong>ни<strong>е</strong>м. Оно должно появляться при попытк<strong>е</strong><br />

открыть файл н<strong>е</strong>в<strong>е</strong>рного формата:<br />

О<br />

Но это <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> вс<strong>е</strong>. Создадим отд<strong>е</strong>льный н<strong>е</strong>корр<strong>е</strong>ктный файл с объясн<strong>е</strong>ни<strong>е</strong>м. Пом<strong>е</strong>стит<strong>е</strong><br />

точку останова в п<strong>е</strong>рвую строчку м<strong>е</strong>тода E x c u s e . S a v e (), запустит<strong>е</strong> программу и сохранит<strong>е</strong><br />

оправдани<strong>е</strong>. Когда программа пр<strong>е</strong>рв<strong>е</strong>т работу, добавьт<strong>е</strong> контрольно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> к свойству<br />

L a s t U s e d . В окн<strong>е</strong> Watch присвойт<strong>е</strong> <strong>е</strong>му знач<strong>е</strong>ни<strong>е</strong> D a t e T i m e .P a r s e ( " O c t o b e r 14,<br />

1066"). Нажмит<strong>е</strong> клавишу F5, чтобы продолжить отладку. Должно появиться исключ<strong>е</strong>ни<strong>е</strong><br />

A r g u m e n tO u tO fR a n g e :<br />

t Argumi^otOutOtRrtii^ctKceptk)« was unhandled<br />

Valued '10Я4ДШ12Ш00 AM' Ъ not veftd for ’Value'. ‘Value' shoufd be between ‘Mm0ate‘ and 'М^Ой<strong>е</strong>'.<br />

ParameSer name Vatue<br />

f r o u t > t € s t o o t k i g 1^ : ___________<br />

Maice sure the arQum ents to this have vaftd values, j<br />

If you are working wfth a coHectbf>, make sure th e index is less than the size of the coHection.<br />

W hen using the overloaded tw a-argum ent FmdStnng or FbdExactString m ethods with a ComboBox or UstBox, check the rtsrtlndex parameter.<br />

Get general help for thfs exceptsor^,<br />

О<br />

O h o появилось потому, что свойство Value эл<strong>е</strong>м<strong>е</strong>нта DateTimePicker получило знач<strong>е</strong>ни<strong>е</strong><br />

м<strong>е</strong>ньш<strong>е</strong><strong>е</strong>, ч<strong>е</strong>м MinDate. Но п<strong>е</strong>р<strong>е</strong>д этим класс Excuse записал файл. Это о ч <strong>е</strong> н ь п о л <strong>е</strong> з н а я<br />

т <strong>е</strong> х н и к а : г<strong>е</strong>н<strong>е</strong>рация файлов с заран<strong>е</strong><strong>е</strong> изв<strong>е</strong>стными н<strong>е</strong>в<strong>е</strong>рными данными. Потом эти файлы<br />

можно использовать для т<strong>е</strong>стирования программы.<br />

Загрузит<strong>е</strong> только что созданый файл, и вы получит<strong>е</strong> то ж<strong>е</strong> само<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong>. Для получ<strong>е</strong>ния<br />

другого исключ<strong>е</strong>ния нужно попытаться открыть файл, который н<strong>е</strong> сод<strong>е</strong>ржит оправдания.<br />

Добавьт<strong>е</strong> блок обработки исключ<strong>е</strong>ния, влож<strong>е</strong>нный внутрь добавл<strong>е</strong>нного на шаг<strong>е</strong> 2 , чтобы<br />

загрузить файл, н<strong>е</strong> сод<strong>е</strong>ржащий оправдания:<br />

1. Объявит<strong>е</strong> бул<strong>е</strong>ву п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную clearForm п<strong>е</strong>р<strong>е</strong>д блоком try/catch. Она должна им<strong>е</strong>ть<br />

знач<strong>е</strong>ни<strong>е</strong> true при наличии исключ<strong>е</strong>ния и использоваться при пров<strong>е</strong>рк<strong>е</strong> н<strong>е</strong>обходимости<br />

очистки формы.<br />

2. Добавьт<strong>е</strong> <strong>е</strong>щ<strong>е</strong> один блок try/catch внутрь блока кнопки Open.<br />

3. Добавьт<strong>е</strong> блок finally к вн<strong>е</strong>шн<strong>е</strong>й конструкции try/catch, чтобы в<strong>е</strong>рнуть форму<br />

в исходно<strong>е</strong>, пусто<strong>е</strong> состояни<strong>е</strong>. Если п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная clearForm им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true,<br />

присвойт<strong>е</strong> LastUsed.Value свойство DateTime.Now (оно возвраща<strong>е</strong>т т<strong>е</strong>кущую дату).<br />

дальш<strong>е</strong> ► 487


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

_<br />

а ж н ш <strong>е</strong><br />

р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong><br />

Вот каким образом ваши знания о конструкции try/catch/finally помогли улучшить<br />

программу Брайана.<br />

p r i v a t e v o i d o p e n _ C l i c k ( o b j e c t sender, E v e n t A r g s e) {<br />

if ( C h e c k C h a n g e d 0 ) {<br />

o p e n F i l e D i a l o g l .I n i t i a l D i r e c t o r y = s e l e c t e d F o l d e r ;<br />

o p e n F i l e D i a l o g l .F i l t e r =<br />

" E x cuse files (*.excuse) I* .excuse IA l l files (*.*)|*.*";<br />

o p e n F i l e D i a l o g l .F i l e N a m e = d e s c r i p t i o n . T e x t + ".excuse";<br />

D i a l o g R e s u l t r e s u l t = o p e n F i l e D i a l o g l .S h o w D i a l o g ();<br />

^ В этом блок<strong>е</strong> try/catch block созда<strong>е</strong>тся окно<br />

i ^ сообщ<strong>е</strong>ни<strong>е</strong>м об оилибк<strong>е</strong>, на сличай возникг<br />

' ^ нов<strong>е</strong>ния пробл<strong>е</strong>мы при вызов<strong>е</strong> формой конi<br />

структора Excuse для загрузки оправдания.<br />

if (result == D i a l o g R e s u l t .OK) {<br />

b o o l c l e a r F o r m = false-<br />

c u r r e n t E x c u s e = n e w E x c u s e ( o p e n F i l e D i a l o g l .F i l e N a m e ) ;<br />

8 данном случа<strong>е</strong> U p d a t e F o r m (false) ;<br />

н<strong>е</strong> использу<strong>е</strong>тся } <strong>е</strong>слй данны<strong>е</strong> в загрцжа<strong>е</strong>мплА<br />

объ<strong>е</strong>кт, exceptionj ( A r g u m e n t O u t O f R a n g e E x c e p t i o n ) { ‘^Р^д<strong>е</strong>лы заданнопоэтому<br />

в оп<strong>е</strong>ра- , , ^ го диапазона.<br />

mojpe catch ука-<br />

M e s s a g e B o x . s h o w ("The e x c u s e f i l e '"<br />

зыва<strong>е</strong>тся только<br />

+ o p e n F i l e D i a l o g l . F i l e N a m e + "' h a d a i n v a l i d data",<br />

т ип исключ<strong>е</strong>ния,^ " U n able to o p e n the e x c u s e " ) ;<br />

опуска<strong>е</strong>тся. ^<br />

C l e a r F o r m = true;<br />

О К Н О с сообщ<strong>е</strong>ни<strong>е</strong>м, созданно<strong>е</strong> вн<strong>е</strong>ш-<br />

блоком try/catch block. Оно сод<strong>е</strong>ржит<br />

I ^ — информацию об исключ<strong>е</strong>нии.<br />

c a t c h ( S e r i a l i z a t i o n E x c e p t i o n ex) {<br />

}<br />

M e s s a g e B o x . S h o w ( " A n e r r o r o c c u r r e d w h i l e o p e n i n g the e x c u s e '"<br />

+ o p e n F i l e D i a l o g l .F i l e N a m e + ” '\n" + ex.Message,<br />

" U n able to o p e n the excuse", M e s s a g e B o x B u t t o n s .OK,<br />

M e s s a g e B o x I c o n . E r r o r ) ;<br />

C l e a r F o r m = true;<br />

npuc6au8aH^m<br />

if (ClearForm) {<br />

d e s c r i p t i o n . T e x t = "";<br />

r e s u l t s . T e x t =<br />

l a s t U s e d . V a l u e = D a t e T i m e . N o w ;<br />

finally 4>opMa nepesaepyTi^<br />

488 глава 10


обработка исключ<strong>е</strong>ний<br />

Након<strong>е</strong>ц Брайан получил<br />

сбой отдых...<br />

Т<strong>е</strong>п<strong>е</strong>рь, посл<strong>е</strong> того как Брайан<br />

позаботился об исключ<strong>е</strong>ниях,<br />

он получил свой заслуж<strong>е</strong>нный (и<br />

одобр<strong>е</strong>нный ш<strong>е</strong>фом!) выходной.<br />

...и полозк<strong>е</strong>ни<strong>е</strong> д<strong>е</strong>л улучшилось!<br />

Ваш<strong>е</strong> ум<strong>е</strong>ни<strong>е</strong> работать с исключ<strong>е</strong>ниями<br />

н<strong>е</strong> просто пр<strong>е</strong>дотвратило пробл<strong>е</strong>му. Оно<br />

пр<strong>е</strong>жд<strong>е</strong> вс<strong>е</strong>го гарантировало, что ш<strong>е</strong>ф<br />

Брайана н<strong>е</strong> узна<strong>е</strong>т о <strong>е</strong>го прогулах!<br />

Старина Брайан никогда<br />

н<strong>е</strong> уходит с работы б<strong>е</strong>з<br />

уважит<strong>е</strong>льной причины.<br />

Правильная обработка<br />

исключ<strong>е</strong>ний<br />

н<strong>е</strong>зам<strong>е</strong>тна пользоват<strong>е</strong>лям.<br />

Программа<br />

н<strong>е</strong> останавлива<strong>е</strong>т<br />

работу, а пробл<strong>е</strong>мы<br />

обрабатываются аккуратно,<br />

б<strong>е</strong>з сообщ<strong>е</strong>ний<br />

об ошибках.<br />

дальш<strong>е</strong> ► 489


11 с о б ь Ш 1и я и д <strong>е</strong> Л <strong>е</strong> Г а ш ы<br />

Что д<strong>е</strong>ла<strong>е</strong>т ваш код, когда вы ^<br />

на н<strong>е</strong>го н<strong>е</strong> смотрит<strong>е</strong><br />

Н<strong>е</strong>возможно вс<strong>е</strong> вр<strong>е</strong>для контролировать созданны<strong>е</strong> объ<strong>е</strong>кты.<br />

Иногда что-то... происходит. И хот<strong>е</strong>лось бы, чтобы объ<strong>е</strong>кты ум<strong>е</strong>ли р <strong>е</strong> ­<br />

а г и р о в а т ь н а п р о и с х о д я щ <strong>е</strong> <strong>е</strong> . Зд<strong>е</strong>сь вам на помощь приходят события.<br />

Один объ<strong>е</strong>кт их публику<strong>е</strong>т, други<strong>е</strong> объ<strong>е</strong>кты на них подписываются,<br />

и сист<strong>е</strong>ма работа<strong>е</strong>т. А для контроля подписчиков вам пригодится м<strong>е</strong>тод<br />

о б р а т н о г о в ы з о в а .


издат<strong>е</strong>ль, встр<strong>е</strong>чай подписчика<br />

Х о ти т<strong>е</strong> , что объ<strong>е</strong>кты научились думать сами?<br />

Пр<strong>е</strong>дположим, вы пишит<strong>е</strong> симулятор игры в б<strong>е</strong>йсбол. Вы собира<strong>е</strong>т<strong>е</strong>сь про-<br />

повс<strong>е</strong>м<strong>е</strong>стно^<br />

гт ^ ^ ^ юаспростран<strong>е</strong>нныи<br />

дать это прилож<strong>е</strong>ни<strong>е</strong> команд<strong>е</strong> «Янки» и заработать миллион долларов. Вы способ им<strong>е</strong>нования<br />

создали объ<strong>е</strong>кты B a ll (Мяч), P itc h e r (Подающий), Umpire (Судья), Fan м<strong>е</strong>тодов. Мы<br />

(Фанат) и многи<strong>е</strong> други<strong>е</strong>. Вы даж<strong>е</strong> написали код, мод<strong>е</strong>лирующий п<strong>е</strong>р<strong>е</strong>брасывани<strong>е</strong><br />

мяча объ<strong>е</strong>ктом P itc h e r .<br />

обсудим <strong>е</strong>го чуть<br />

позж<strong>е</strong>.<br />

Осталось собрать вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong>. Вы добавля<strong>е</strong>т<strong>е</strong> мячу м<strong>е</strong>тод O n B a llln P la y ()<br />

(Мяч в игр<strong>е</strong>), и т<strong>е</strong>п<strong>е</strong>рь нужно, чтобы объ<strong>е</strong>кт P i tc h e r отв<strong>е</strong>тил м<strong>е</strong>тодом сво<strong>е</strong>го<br />

обработчика событий. М<strong>е</strong>тоды уж<strong>е</strong> написаны, их тр<strong>е</strong>бу<strong>е</strong>тся только связать<br />

друг с другом:<br />

посль э—т<br />

вызыва<strong>е</strong>т^<br />

^ B a l l . O n B a l l l n P l a y (70, 82<br />

Мяч л<strong>е</strong>т ит по 70-градцсиой<br />

^^ра<strong>е</strong>ктории и y n a d e m Z<br />

расстоянии 8Z ф у ^ а от базы.<br />

Подаю1ций долж<strong>е</strong>н<br />

бросить этот<br />

мяч.<br />

Подающий мож<strong>е</strong>т<br />

мяч под<br />

'^^ким углом и на<br />

^ако<strong>е</strong> расстояни<strong>е</strong><br />

больш<strong>е</strong>, ч<strong>е</strong>м 82)<br />

Как объ<strong>е</strong>кты узнают, что произошло?<br />

P i t c h e r .C a t c h B a l l (70<br />

90)<br />

Сформулиру<strong>е</strong>м пробл<strong>е</strong>му. Вы хотит<strong>е</strong>, чтобы объ<strong>е</strong>кт B a ll б<strong>е</strong>спокоился<br />

об отправляющ<strong>е</strong>м <strong>е</strong>го в пол<strong>е</strong>т удар<strong>е</strong>, а объ<strong>е</strong>кт P i tc h e r —<br />

о поимк<strong>е</strong> л<strong>е</strong>тящих на н<strong>е</strong>го мяч<strong>е</strong>й. При этом н<strong>е</strong> нужно, чтобы объ<strong>е</strong>кт<br />

B a ll сообщал объ<strong>е</strong>кту P itc h e r , «Я л<strong>е</strong>чу».<br />

Scooting и оч<strong>е</strong>нь быстро б<strong>е</strong>гающий.<br />

Г<br />

Объ<strong>е</strong>кты должны<br />

заботиты;я о с<strong>е</strong>б<strong>е</strong>,<br />

а н<strong>е</strong> о других.<br />

Мы за разд<strong>е</strong>л<strong>е</strong>ни<strong>е</strong><br />

сф<strong>е</strong>ры влияния<br />

0№Ь<strong>е</strong>1 !КТОВ.<br />

^<br />

492 глава 11<br />

м ы говорам<br />

что<br />

опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

кидать. Это н<strong>е</strong><br />

о « « » * « “ “ '


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

События<br />

Посл<strong>е</strong> удара по мячу вам потр<strong>е</strong>бу<strong>е</strong>тся с о б ы т и <strong>е</strong> (e v e n t). Этим т<strong>е</strong>рмином<br />

называ<strong>е</strong>тся что-то происходящ<strong>е</strong><strong>е</strong> в ваш<strong>е</strong>й программ<strong>е</strong>. На<br />

событи<strong>е</strong> могут прор<strong>е</strong>агировать объ<strong>е</strong>кты, наприм<strong>е</strong>р. Pitcher.<br />

Разум<strong>е</strong><strong>е</strong>тся, это могут быть и объ<strong>е</strong>кты Catcher, ThirdBaseman,<br />

Umpire и даж<strong>е</strong> Fan. При этом р<strong>е</strong>акция для каждого объ<strong>е</strong>кта буд<strong>е</strong>т<br />

своя.<br />

То <strong>е</strong>сть объ<strong>е</strong>кт Ball долж<strong>е</strong>н в ы з ы в а т ь с о б ы т и <strong>е</strong> . Остальны<strong>е</strong> ж<strong>е</strong><br />

объ<strong>е</strong>кты будут п о д п и с ы в а т ь с я н а с о б ы т и <strong>е</strong> э т о г о т и п а ... и р<strong>е</strong>агировать<br />

на <strong>е</strong>го возникнов<strong>е</strong>ни<strong>е</strong>. На это .<br />

- ° событи<strong>е</strong>, мож<strong>е</strong>т<br />

пО<br />

Тпй<br />

ииной<br />

13д|[|1л.р!йУ-<br />

>^ри этом объ<strong>е</strong>к -<br />

подписчи-<br />

^ ков н<strong>е</strong>изв<strong>е</strong>ст<strong>е</strong>н.<br />

Вызвано событи<strong>е</strong> BalllnPlay<br />

С О -б Ы “Т И -<strong>е</strong> , с у щ .<br />

то, что случа<strong>е</strong>тся.<br />

Солн<strong>е</strong>чно<strong>е</strong> затм<strong>е</strong>ни<strong>е</strong> -<br />

это событи<strong>е</strong>, которо<strong>е</strong><br />

н<strong>е</strong>льзя пропустить.<br />

Ва\'<br />

В ИСР события<br />

пом<strong>е</strong>чаются значком<br />

6 вид<strong>е</strong> м олнии.<br />

Вы уж<strong>е</strong> могли<br />

<strong>е</strong>го вид<strong>е</strong>ть рядом<br />

с событиями<br />

в окнах IntelliSense<br />

и Properties.<br />

Обработчик событий<br />

НапаЭдкзьцмй<br />

м други<strong>е</strong> и гроки<br />

ст араю т ся<br />

noAy4wt^f мям.<br />

Судья пров<strong>е</strong>ря<strong>е</strong>т, по прабмлйм<br />

ли обрабатыва<strong>е</strong>тся<br />

каждый мяч, и от сл<strong>е</strong>жива<strong>е</strong>т<br />

происходящ<strong>е</strong><strong>е</strong><br />

на пол<strong>е</strong>.<br />

Логичным р<strong>е</strong>зультатом опов<strong>е</strong>щ<strong>е</strong>ния объ<strong>е</strong>ктов о событии долж<strong>е</strong>н<br />

быть запуск н<strong>е</strong>ко<strong>е</strong>го кода. Этот код называют о б р а б о т ч и к о м с о б ы ­<br />

т и й (e v e n t h a n d le r ).<br />

Вс<strong>е</strong> это происходит во вр<strong>е</strong>мя работы программы б<strong>е</strong>з ваш<strong>е</strong>го вм<strong>е</strong>шат<strong>е</strong>льства.<br />

Вы пиш<strong>е</strong>т<strong>е</strong> код, вызывающий событи<strong>е</strong>, зат<strong>е</strong>м код для <strong>е</strong>го<br />

обработки и запуска<strong>е</strong>т<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong>. При возникнов<strong>е</strong>нии события,<br />

обработчик начина<strong>е</strong>т свою д<strong>е</strong>ят<strong>е</strong>льность... вы при этом н<strong>е</strong> д<strong>е</strong>ла<strong>е</strong>т<strong>е</strong> нич<strong>е</strong>го.<br />

И лучш<strong>е</strong> вс<strong>е</strong>го то, что объ<strong>е</strong>кты при этом заботятся только о с<strong>е</strong>б<strong>е</strong>,<br />

а н<strong>е</strong> о других объ<strong>е</strong>ктах.<br />

Фанаты подписываются<br />

на случай, <strong>е</strong>сли<br />

мяч попад<strong>е</strong>т на три -<br />

буны.<br />

3(71<br />

одного р uwon^A<br />

ил<strong>е</strong>лиок н« к<br />

с1ллаиоби ^om ofo^<br />

образом<br />

дальш<strong>е</strong> > 493


<strong>е</strong>сли в л<strong>е</strong>су упад<strong>е</strong>т д<strong>е</strong>р<strong>е</strong>во<br />

Один объ<strong>е</strong>кт иницииру<strong>е</strong>т событи<strong>е</strong>, другой р<strong>е</strong>агиру<strong>е</strong>т на н<strong>е</strong>го<br />

Посмотрим, как в С# функционируют события, их обработчики<br />

и подписки:<br />

1^ом Ball.<br />

494 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Обработка события<br />

Посл<strong>е</strong> возникнов<strong>е</strong>ния события вс<strong>е</strong> подписанны<strong>е</strong> на н<strong>е</strong>го объ<strong>е</strong>кты<br />

получают ув<strong>е</strong>домл<strong>е</strong>ния и могут сов<strong>е</strong>ршать различны<strong>е</strong> д<strong>е</strong>йствия.<br />

П о д п и с ч и к и п о л у ч а ю т у в <strong>е</strong> д о м л <strong>е</strong> н и <strong>е</strong><br />

Так как объ<strong>е</strong>кты Pitcher, Umpire и Fan подписаны на событи<strong>е</strong> BalllnPlay<br />

объ<strong>е</strong>кта Ball, они получают ув<strong>е</strong>домл<strong>е</strong>ни<strong>е</strong>, и их пр<strong>е</strong>дназнач<strong>е</strong>нны<strong>е</strong> для обработки<br />

событий м<strong>е</strong>тоды вызываются один за другим.<br />

Событи<strong>е</strong><br />

BalllnPlay<br />

®<br />

V .<br />

событий называ<strong>е</strong>тся<br />

м<strong>е</strong>тод запуска<strong>е</strong>мый подписчиком<br />

посл<strong>е</strong> возникнов<strong>е</strong>ния события.<br />

Вызванно<strong>е</strong> мячом событи<strong>е</strong><br />

- объ<strong>е</strong>кт BaiІEventArqs,<br />

сод<strong>е</strong>ржащий информацию<br />

,0 тра<strong>е</strong>ктории и дальности<br />

пол<strong>е</strong>та мяча. Эта информа- Обр аботчики<br />

ция . п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся г ' -------'^'^и'^чипгхчикам обработчикам собь оидытий записобытии.<br />

^ ^ скаются в порядк<strong>е</strong><br />

оч<strong>е</strong>р<strong>е</strong>ди.<br />

Камадый о б ъ <strong>е</strong> к т о б р а б а т ы в а <strong>е</strong> т с о б ы т и <strong>е</strong><br />

Т<strong>е</strong>п<strong>е</strong>рь объ<strong>е</strong>кты Pitcher, Umpire и Fan начинают каждый по-сво<strong>е</strong>му р<strong>е</strong>агировать<br />

на событи<strong>е</strong> BalllnPlay. Их обработчики событий вызываются в порядк<strong>е</strong> оч<strong>е</strong>р<strong>е</strong>ди<br />

пут<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>дачи им в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра ссылки на объ<strong>е</strong>кт Ball EventArgs.<br />

Вот с ч<strong>е</strong>м им<strong>е</strong>ют д<strong>е</strong>ло вс<strong>е</strong> обрабатывающи<strong>е</strong><br />

событи<strong>е</strong> объ<strong>е</strong>кты. Кром<strong>е</strong><br />

того, они получают ссылку на объ<strong>е</strong>кт,<br />

ставший причиной события.<br />

объ<strong>е</strong>кт Рап с помощь<br />

аргум<strong>е</strong>нта Ва11Еу<strong>е</strong>п±Агд$<br />

пров<strong>е</strong>ря<strong>е</strong>т, достаточно<br />

ли близко подл<strong>е</strong>т<strong>е</strong>л мяч,<br />

чтобы <strong>е</strong>го поймать.<br />

Объ<strong>е</strong>кт Umpire наблюда<strong>е</strong>т. Он м о ж <strong>е</strong> . т быть подписан<br />

и на други<strong>е</strong> события, скаж<strong>е</strong>м, BallFietded (П<strong>е</strong>р<strong>е</strong>дача<br />

мяча) или BallThrown (бросок мяча), чтобы р<strong>е</strong>агировать<br />

на происходящ<strong>е</strong><strong>е</strong>.<br />

дальш<strong>е</strong> ► 495


мн<strong>е</strong> нужны аргум<strong>е</strong>нты<br />

Со<strong>е</strong>диним Вс<strong>е</strong> бм<strong>е</strong>ст<strong>е</strong><br />

EventArgs<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда вы им<strong>е</strong><strong>е</strong>т общ<strong>е</strong><strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> о том, что происходит,<br />

рассмотрим бол<strong>е</strong><strong>е</strong> подробно проц<strong>е</strong>сс со<strong>е</strong>дин<strong>е</strong>ния разкласса<br />

EventArgs.<br />

^ Нам нуж<strong>е</strong>н объ<strong>е</strong>кт для аргум<strong>е</strong>нтов события<br />

Помнит<strong>е</strong>, что событи<strong>е</strong> BalllnPlay им<strong>е</strong><strong>е</strong>т н<strong>е</strong>сколько аргум<strong>е</strong>нтов?<br />

Для них нам потр<strong>е</strong>бу<strong>е</strong>тся объ<strong>е</strong>кт. В .NET для<br />

этой ц<strong>е</strong>ли сущ<strong>е</strong>ству<strong>е</strong>т стандартный класс E v e n t A r g s , но<br />

он н <strong>е</strong> и м <strong>е</strong> <strong>е</strong> т ч л <strong>е</strong> н о в . Он пр<strong>е</strong>дназнач<strong>е</strong>н исключит<strong>е</strong>льно<br />

для п<strong>е</strong>р<strong>е</strong>дачи аргум<strong>е</strong>нтов объ<strong>е</strong>кта обработчикам события.<br />

Вот объявл<strong>е</strong>ни<strong>е</strong> этого класса:<br />

class BallEventArgs : EventArgs<br />

Это означа<strong>е</strong>т возможность<br />

восходящ<strong>е</strong>го<br />

прив<strong>е</strong>д<strong>е</strong>ния<br />

объ<strong>е</strong>кта EventArgs<br />

в случа<strong>е</strong>, когда <strong>е</strong>го<br />

нужно п<strong>е</strong>р<strong>е</strong>слать<br />

событию, н<strong>е</strong> ум <strong>е</strong>-<br />

ющ<strong>е</strong>му <strong>е</strong>го обрабатывать.<br />

Эти свойства позвомячу<br />

п<strong>е</strong>р<strong>е</strong>дать<br />

обработчикам событий<br />

информацию о м<strong>е</strong>ст<strong>е</strong><br />

вброса в игру.<br />

BallEventArgs<br />

Trajectory<br />

Distance<br />

Нужно объявить событи<strong>е</strong> внутри вызвавш<strong>е</strong>го <strong>е</strong>го класса<br />

В класс<strong>е</strong> Ball присутству<strong>е</strong>т строчка с к л ю ч <strong>е</strong> в ы м с л о в о м e v e n t . Она мож<strong>е</strong>т располагаться в произвольном<br />

м<strong>е</strong>ст<strong>е</strong> класса, обычно <strong>е</strong><strong>е</strong> пом<strong>е</strong>щают рядом с объявл<strong>е</strong>ни<strong>е</strong>м свойств. Благодаря этому други<strong>е</strong><br />

объ<strong>е</strong>кты могут подписываться на событи<strong>е</strong>. Вот как это выглядит:<br />

p u b lic e ve n t E v e n tH a n d le r B a l l l n P l a y ;<br />

Дост уп к событиям обыч- \<br />

но открыт. Наш<strong>е</strong> событи<strong>е</strong> \<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>но в класс<strong>е</strong> Ball, но<br />

нужно, чтобы на н<strong>е</strong>го могли<br />

ссылаться объ<strong>е</strong>кты Pitcher,<br />

Umpire и т. п. Если вы хот<br />

ит <strong>е</strong> ограничить доступ<br />

к событию экз<strong>е</strong>мплярами<br />

из <strong>е</strong>го класса, событи<strong>е</strong> можно<br />

закрыть.<br />

посл<strong>е</strong> ключ<strong>е</strong>вого слова event клю -<br />

f w T r ссылка на объ<strong>е</strong>кт, вызвав-<br />

E v e n tfr g r " ^<br />

496 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

©<br />

Классам-подписчикам нужны обработчики событий<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, как функционируют обработчики событий. Каждый раз, когда<br />

вы создавали, к прим<strong>е</strong>ру, м<strong>е</strong>тод для обработки события Click, ИСР добавляла<br />

<strong>е</strong>го в класс. Ровно то ж<strong>е</strong> само<strong>е</strong> произойд<strong>е</strong>т с событи<strong>е</strong>м BalllnPlay объ<strong>е</strong>кта<br />

Ball. Его обработчик событий буд<strong>е</strong>т им<strong>е</strong>ть уж<strong>е</strong> знакомый вам вид;<br />

void ball_BallInPlay(object sender, EventArgs e)<br />

В C=^ н <strong>е</strong> т правила им<strong>е</strong>нования<br />

обработчиков событий, но обычно<br />

им<strong>е</strong>на формируются сл<strong>е</strong>дующим<br />

образом: имя обь<strong>е</strong>кта, нижн<strong>е</strong><strong>е</strong><br />

подч<strong>е</strong>ркивани<strong>е</strong>, имя события.<br />

Клйсс^ которому принадл<strong>е</strong>жит<br />

данный обработчик события, им<strong>е</strong><strong>е</strong>т<br />

ссылочную п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную bail на объ<strong>е</strong>кт<br />

Ball поэтому имя обработчика события<br />

BalllnPlay начина<strong>е</strong>тся со слаба<br />

balL за которым сл<strong>е</strong>ду<strong>е</strong>т имя обрабатыва<strong>е</strong>мого<br />

события BalllnPlay.<br />

В объявл<strong>е</strong>нии события<br />

BalllnPlay <strong>е</strong>го тип указан<br />

как EventHandler, что<br />

означа<strong>е</strong>т присутстви<strong>е</strong><br />

двух парам<strong>е</strong>тров: объ<strong>е</strong>кта<br />

sender и ссылки EventArgs<br />

с им<strong>е</strong>н<strong>е</strong>м <strong>е</strong>, а такж<strong>е</strong> то,<br />

что это событи<strong>е</strong> н<strong>е</strong> возвраща<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong>.<br />

®<br />

На событи<strong>е</strong> подписываются объ<strong>е</strong>кты<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда обработчик события задан, объ<strong>е</strong>ктам Pitcher, Umpire,<br />

ThirdBaseman и Fan нужно подключить свои обработчики событий. Каждый из<br />

них буд<strong>е</strong>т им<strong>е</strong>ть собств<strong>е</strong>нный м<strong>е</strong>тод Ьа11_Ва11 InPlay. Так что при наличии у вас<br />

ссылочной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной на объ<strong>е</strong>кт Ball или поля ball, оп<strong>е</strong>ратор -*-= привяж<strong>е</strong>т к ним<br />

обработчик события:<br />

ball.BalllnPlay += new EventHandler(ballBalllnPlay);<br />

Мы связыва<strong>е</strong>м обработчик<br />

с событи<strong>е</strong>м BalllnPlay<br />

объ<strong>е</strong>кта, на который<br />

указыва<strong>е</strong>т ссылка ball.<br />

^<br />

-------У<br />

\ Эта часть опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т,<br />

\ какой м<strong>е</strong>тод обработчика<br />

5уЭ<strong>е</strong>т подписан на событи<strong>е</strong>.<br />

програм м а н<strong>е</strong> буд<strong>е</strong>т компилироваться.<br />

IJepeBepHuine стран и ц у и л|=оДоЛжиМ<br />

дальш<strong>е</strong> ► 497


Объ<strong>е</strong>кт B a l l опов<strong>е</strong>ща<strong>е</strong>т подписчиков, что он в игр<strong>е</strong>, с помощью события<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда вс<strong>е</strong> настро<strong>е</strong>но, объ<strong>е</strong>кт B a l l мож<strong>е</strong>т в ы з в а т ь с в о <strong>е</strong> с о б ы т и <strong>е</strong> в отв<strong>е</strong>т на<br />

опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нны<strong>е</strong> д<strong>е</strong>йствия симулятора. Вызвать событи<strong>е</strong> л<strong>е</strong>гко.<br />

EventHandler balllnPlay . BalllnPlay,<br />

if (balllnPlay != null)<br />

balllnPlay(this, e);<br />

e — ЭИЛО<br />

новый объ<strong>е</strong>кт<br />

BallEventArgs.<br />

По мячу наносится<br />

удар, tA обь<strong>е</strong>кт<br />

Bal начина<strong>е</strong>т<br />

д<strong>е</strong>йствовать...<br />

Prtc<br />

Событи<strong>е</strong>, н<strong>е</strong> им<strong>е</strong>ющ<strong>е</strong><strong>е</strong><br />

обработчика, становит-<br />

,Ы п<strong>е</strong>р<strong>е</strong>давая 5 и д ы п <strong>е</strong> I ся причиной<br />

<strong>е</strong>го возиикм<strong>е</strong>- « с щ о р о ^ к н ы ! исключ<strong>е</strong>ния.<br />

длу c o o b im u h o . : J<br />

Г Событи<strong>е</strong> акт ивно.<br />

Кто на н<strong>е</strong>го<br />

подписан?<br />

Обь<strong>е</strong>кт Pitcher связыва<strong>е</strong>т<br />

свой обработчик<br />

с событи<strong>е</strong>м BalllnPlay.<br />

Поэтому м<strong>е</strong>тод<br />

обь<strong>е</strong>кта Pitcher<br />

вызыва<strong>е</strong>тся с правильными<br />

данными<br />

и мож<strong>е</strong>т работат<br />

ь с событи<strong>е</strong>м.<br />

Если други<strong>е</strong> объ<strong>е</strong>кты н<strong>е</strong><br />

добавят событию свои<br />

обработчики, оно получа<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> null, и<br />

появля<strong>е</strong>тся исключ<strong>е</strong>ни<strong>е</strong><br />

NullReferenceException.<br />

Им<strong>е</strong>нно поэтому нужно<br />

копировать событи<strong>е</strong> в<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную п<strong>е</strong>р<strong>е</strong>д пров<strong>е</strong>ркой<br />

на рав<strong>е</strong>нство null.<br />

В крайн<strong>е</strong> р<strong>е</strong>дких случаях<br />

событи<strong>е</strong> усп<strong>е</strong>ва<strong>е</strong>т приобр<strong>е</strong>сти<br />

это знач<strong>е</strong>ни<strong>е</strong> уж<strong>е</strong><br />

посл<strong>е</strong> пров<strong>е</strong>рки.<br />

Стандартны <strong>е</strong> им<strong>е</strong>на м<strong>е</strong>тодоВ, бызыВаюи^их событи<strong>е</strong><br />

Откройт<strong>е</strong> код любой ф о р м ы и вв<strong>е</strong>дит<strong>е</strong> слово o v e r r i d e в строку объявл<strong>е</strong>ния м<strong>е</strong>тода. Посл<strong>е</strong><br />

проб<strong>е</strong>ла появится окно IntelliSense;<br />

override<br />

4* OnCursorChanged(EventArgs <strong>е</strong>)<br />

OnPeactivate (EventArgs <strong>е</strong>)<br />

OnDockChanged(EventArgs <strong>е</strong>)<br />

’ OnDoubleClick(EventArgs <strong>е</strong>)<br />

4^ OnDragProppragEvent^rgs drgevent)<br />

нажатия<br />

Обратили внимани<strong>е</strong>, что каждый<br />

из м<strong>е</strong>тодов использу<strong>е</strong>т в<br />

кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра EventArgs?<br />

Вызывая событи<strong>е</strong>, вс<strong>е</strong> м<strong>е</strong>тоды<br />

п<strong>е</strong>р<strong>е</strong>дают <strong>е</strong>му данный парам<strong>е</strong>тр.<br />

Объ<strong>е</strong>кт Form вызыва<strong>е</strong>т множ<strong>е</strong>ство событий, а каждо<strong>е</strong> событи<strong>е</strong> им<strong>е</strong><strong>е</strong>т набор вызывающих <strong>е</strong>го м<strong>е</strong>тодов.<br />

М<strong>е</strong>тод ф о р м ы OnDoubleClick () вызыва<strong>е</strong>т событи<strong>е</strong> Doubleclick, и это выглядит логично. Поэтому<br />

объ<strong>е</strong>кт Ball и м <strong>е</strong> <strong>е</strong> т м <strong>е</strong> т о д O n B a l l l n P l a y , использующий в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра объ<strong>е</strong>кт BallEventArgs.<br />

Симулятор вызыва<strong>е</strong>т этот м<strong>е</strong>тод каждый раз, когда для мяча тр<strong>е</strong>бу<strong>е</strong>тся событи<strong>е</strong> BalllnPlay, так что<br />

когда симулятор обнаружива<strong>е</strong>т удар биты по мячу, он созда<strong>е</strong>т экз<strong>е</strong>мпляр BallEventArgs, сод<strong>е</strong>ржащий<br />

информацию о тра<strong>е</strong>ктории и дальности пол<strong>е</strong>та, который и п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся м<strong>е</strong>тоду OnBalllnPlay ().<br />

498 глава 11


Часто<br />

З а д а в а <strong>е</strong> м ы <strong>е</strong><br />

В о п р о с ы<br />

события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Зач<strong>е</strong>м в объявл<strong>е</strong>нии события<br />

писать слово E v e n tH a n d le r ? Я<br />

думал, что обработчиками называют<br />

способ других объ<strong>е</strong>ктов подписаться<br />

на событи<strong>е</strong>.<br />

; Это в<strong>е</strong>рно, для подписки на соjbiTMe<br />

пиш<strong>е</strong>тся м<strong>е</strong>тод, называ<strong>е</strong>мый<br />

обработчиком событий. Но вы зам<strong>е</strong>тили,<br />

каким им<strong>е</strong>нно образом E v e n t H a n d l e r<br />

использовался в объявл<strong>е</strong>нии события<br />

(на шаг<strong>е</strong> #2) и в строчк<strong>е</strong> подписки (на<br />

шаг<strong>е</strong> #4)? E v e n t H a n d l e r опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

сигнатуру события, он сообща<strong>е</strong>т объ<strong>е</strong>ктам,<br />

подписывающимся на событи<strong>е</strong>,<br />

каким им<strong>е</strong>нно образом они должны<br />

опр<strong>е</strong>д<strong>е</strong>лить м<strong>е</strong>тоды-обработчики. А для<br />

подписки м<strong>е</strong>тода на события он долж<strong>е</strong>н<br />

им<strong>е</strong>ть два парам<strong>е</strong>тра ( obj ect и ссылку<br />

EventArgs) И н<strong>е</strong> возвращать знач<strong>е</strong>ний.<br />

Что произойд<strong>е</strong>т при попытк<strong>е</strong><br />

воспользоваться м<strong>е</strong>тодом, н<strong>е</strong> совпадающим<br />

с опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нным при помощи<br />

E v en tH a n d ler?<br />

Q ; Программа н<strong>е</strong> буд<strong>е</strong>т компилироваться.<br />

Компилятор сл<strong>е</strong>дит за т<strong>е</strong>м, чтобы вы<br />

случайно н<strong>е</strong> подписались на м<strong>е</strong>тод-обработчик,<br />

н<strong>е</strong>совм<strong>е</strong>стимый с событи<strong>е</strong>м.<br />

Стандартный обработчик событий<br />

E v e n t H a n d l e r показыва<strong>е</strong>т, как им<strong>е</strong>нно<br />

должны выгляд<strong>е</strong>ть ваши м<strong>е</strong>тоды.<br />

!)'• Что значит «стандартный» обраотчик<br />

событий? Разв<strong>е</strong> <strong>е</strong>сть и други<strong>е</strong>?<br />

^ I Да! Ваши события вм<strong>е</strong>сто объ<strong>е</strong>кта<br />

и ссылки E v e n t A r g s могуг<br />

отправлять что угодно или вообщ<strong>е</strong> нич<strong>е</strong>го!<br />

Посмотрит<strong>е</strong> на посл<strong>е</strong>днюю строчку, пр<strong>е</strong>длага<strong>е</strong>мую<br />

функци<strong>е</strong>й IntelliSense. Обратили<br />

внимани<strong>е</strong>, как м<strong>е</strong>тод o n D r a g O r o p<br />

принима<strong>е</strong>т ссылку D r a g E v e n t A r g s<br />

вм<strong>е</strong>сто E v e n t A r g s ? D r a g E v e n t A r g s<br />

насл<strong>е</strong>ду<strong>е</strong>т от E v e n t A r g s точно так<br />

ж<strong>е</strong>, как и BallEventArgs. Событи<strong>е</strong><br />

формы D r a g D r o p н<strong>е</strong> ИСпользу<strong>е</strong>т<br />

EventHandler. Он б<strong>е</strong>р<strong>е</strong>т<br />

DragEventArgs, И ДЛЯ <strong>е</strong>го обработки<br />

ваш м<strong>е</strong>тод долж<strong>е</strong>н брать объ<strong>е</strong>кг и ссылку<br />

DragEventArgs.<br />

Парам<strong>е</strong>тры события опр<strong>е</strong>д<strong>е</strong>ляются<br />

д<strong>е</strong>л<strong>е</strong>гатами. Прим<strong>е</strong>ры д<strong>е</strong>л<strong>е</strong>гатов —<br />

E v e n t H a n d l e r и D r a g E v e n t A r g s .<br />

О том, ЧТО это тако<strong>е</strong>, мы поговорим чуть<br />

позж<strong>е</strong>,<br />

:) • Можно ли сд<strong>е</strong>лать так, чтобы обраотчик<br />

событий возвращал знач<strong>е</strong>ни<strong>е</strong>?<br />

П ; Можно, но д<strong>е</strong>лать этого н<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т.<br />

В<strong>е</strong>дь им<strong>е</strong>нно отсутстви<strong>е</strong> возвраща<strong>е</strong>мых<br />

знач<strong>е</strong>ний позволя<strong>е</strong>т со<strong>е</strong>динять обработчики<br />

событий в ц<strong>е</strong>почки, присо<strong>е</strong>диняя к одному<br />

событию н<strong>е</strong>сколько обработчиков.<br />

Б<br />

! Зач<strong>е</strong>м нужны ц<strong>е</strong>почки?<br />

0; Они позволяют подписать на одно соги<strong>е</strong><br />

н<strong>е</strong>сколько обработчиков. Эта проц<strong>е</strong>дура<br />

буд<strong>е</strong>т рассмотр<strong>е</strong>на чуть поздн<strong>е</strong><strong>е</strong>.<br />

И поэтому для добавл<strong>е</strong>ния обработчика<br />

события я использовал оп<strong>е</strong>ратор<br />

+=? Как будто добавляя новый<br />

обработчик к уж<strong>е</strong> сущ<strong>е</strong>ствующим.<br />

^ : Им<strong>е</strong>нно так! Благодаря оп<strong>е</strong>ратору +=<br />

ваш обработчик событий н<strong>е</strong> зам<strong>е</strong>ща<strong>е</strong>т<br />

пр<strong>е</strong>дыдущий. Он становится <strong>е</strong>щ<strong>е</strong> одним<br />

в ц<strong>е</strong>почк<strong>е</strong> обработчиков одного и того ж<strong>е</strong><br />

события.<br />

Поч<strong>е</strong>му при вызов<strong>е</strong> события<br />

B a l l l n P l a y о использовалось<br />

слово this?<br />

I 1; Это п<strong>е</strong>рвый парам<strong>е</strong>тр стандартного<br />

о6|эаботчика событий. Вы зам<strong>е</strong>тили, что<br />

любой обработчик события C l i c k им<strong>е</strong><strong>е</strong>т<br />

парам<strong>е</strong>тр object sender? Это ссылка<br />

на вызывающий событи<strong>е</strong> объ<strong>е</strong>кт. То<br />

<strong>е</strong>сть когда вы обрабатыва<strong>е</strong>т<strong>е</strong> щ<strong>е</strong>лчок<br />

на кнопк<strong>е</strong>, объ<strong>е</strong>кт s e n d e r указыва<strong>е</strong>т<br />

на эту кнопку. При обработк<strong>е</strong> события<br />

B a l l l n P l a y парам<strong>е</strong>тр s e n d e r буд<strong>е</strong>т<br />

указывать на объ<strong>е</strong>кт Ball, а мяч при<br />

вызов<strong>е</strong> события обозначит этот парам<strong>е</strong>тр<br />

ключ<strong>е</strong>вым словом this.<br />

ОДНО событи<strong>е</strong><br />

вс<strong>е</strong>гда вызыва<strong>е</strong>тся<br />

ОДНИМ объ<strong>е</strong>ктом.<br />

Но отв<strong>е</strong>чать<br />

на н<strong>е</strong>го M O iy r<br />

МНОГИЕ объ<strong>е</strong>кты.<br />

дальш<strong>е</strong> ► 499


это сэкономит вам вр<strong>е</strong>мя<br />

Абтоматич<strong>е</strong>ско<strong>е</strong> создани<strong>е</strong> обработчиков событий<br />

Большинство программистов присваивают обработчикам событий им<strong>е</strong>на по одному и тому ж<strong>е</strong> принципу.<br />

Скаж<strong>е</strong>м, <strong>е</strong>сли объ<strong>е</strong>кт Ball вызыва<strong>е</strong>т событи<strong>е</strong> BalllnPlay, а п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная, ссылающаяся на этот<br />

объ<strong>е</strong>кт, называ<strong>е</strong>тся ball, обработчику события присваива<strong>е</strong>тся имя ball_BallInPlay (). Соблюдать<br />

это правило н<strong>е</strong> обязат<strong>е</strong>льно, но сл<strong>е</strong>довани<strong>е</strong> <strong>е</strong>му обл<strong>е</strong>гча<strong>е</strong>т чт<strong>е</strong>ни<strong>е</strong> кода другими пользоват<strong>е</strong>лями.<br />

К счастью ИСР позволя<strong>е</strong>т б<strong>е</strong>з пробл<strong>е</strong>м сл<strong>е</strong>довать этому написанному<br />

правилу. В<strong>е</strong>дь она ум<strong>е</strong><strong>е</strong>т автоматич<strong>е</strong>ски добавлять обработчики событий.<br />

Вы уж<strong>е</strong> сталкивались с этой функци<strong>е</strong>й, но давайт<strong>е</strong> рассмотрим <strong>е</strong><strong>е</strong><br />

<strong>е</strong>щ<strong>е</strong> раз.<br />

^ У п р а ж н <strong>е</strong> н и <strong>е</strong> !<br />

Создайт<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong> Windows Form и добавьт<strong>е</strong> Ball и BallEventArgs<br />

Вот код для класса Ball:<br />

class Ball {<br />

}<br />

public event EventHandler BalllnPlay;<br />

public void OnBalllnPlay(BallEventArgs e) {<br />

EventHandler balllnPlay = BalllnPlay;<br />

if (balllnPlay != null)<br />

balllnPlay(this, e ) ;<br />

}<br />

A это класс BallEventArgs:<br />

class BallEventArgs : EventArgs {<br />

public int Trajectory { get; private set; }<br />

public int Distance { get; private set; }<br />

public BallEventArgs(int trajectory, int distance)<br />

this.Trajectory = trajectory;<br />

this.Distance = distance;<br />

}<br />

О Добавим конструктор для класса Pitcher<br />

Конструктор класса Pitcher буд<strong>е</strong>т сод<strong>е</strong>ржать одну строчку, добавляющую обработчик<br />

событий к ball.BalllnPlay. Начнит<strong>е</strong> вводить оп<strong>е</strong>ратор, но пока н<strong>е</strong> набирайт<strong>е</strong> +=.<br />

public Pitcher(Ball ball) {<br />

ball.BalllnPlay<br />

500 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

^ ИСР помож<strong>е</strong>т вам сэкономить вр<strong>е</strong>мя<br />

Как только вы вв<strong>е</strong>д<strong>е</strong>т<strong>е</strong> оп<strong>е</strong>ратор +=, появится окно:<br />

p u b l i c P i t c h e r ( B a l l ball) {<br />

ball. B a l l l n P l a y +=<br />

_ _ _ _ _ _ _ _ _ _ _<br />

} new EventHandler(ball_BallInPlay); (Press TAB to insert)<br />

Нажмит<strong>е</strong> tab для зав<strong>е</strong>рш<strong>е</strong>ния ввода оп<strong>е</strong>ратора. Вот как он выглядит:<br />

p u b l i c P i t c h e r ( B a l l ball) {<br />

b a l l . B a l l l n P l a y += n e w E v e n t H a n d l e r ( b a l l _ B a l l I n P l a y ) ;<br />

^<br />

Двойной щ<strong>е</strong>лчок на кнопк<strong>е</strong> в конструктор<strong>е</strong> форм приводит к авт оматич<strong>е</strong>скому<br />

добавл<strong>е</strong>нию обработчика события, но в данном случа<strong>е</strong> код<br />

добавля<strong>е</strong>тся к м<strong>е</strong>тоду InitializeComponentO в файл<strong>е</strong> F orm l.Pesigner.cs,<br />

а н<strong>е</strong> в кон<strong>е</strong>ц файла класса.<br />

Обработчик событий тож<strong>е</strong> буд<strong>е</strong>т добавл<strong>е</strong>н автоматич<strong>е</strong>ски<br />

Нужно добавить <strong>е</strong>щ<strong>е</strong> один м<strong>е</strong>тод в ц<strong>е</strong>почку события, к счастью, это тож<strong>е</strong> можно сд<strong>е</strong>лать<br />

ср<strong>е</strong>дствами ИСР.<br />

n e w E v e n t H a n d l e r<br />

Press TAB to generate handler ■ball_BallInPlay* in this class<br />

Нажмит<strong>е</strong> клавишу tab, чтобы добавить этот обработчик событий в класс Pitcher. Выбор<br />

им<strong>е</strong>ни буд<strong>е</strong>т пров<strong>е</strong>д<strong>е</strong>н по сх<strong>е</strong>м<strong>е</strong> objectName_HandlerName ():<br />

v o i d b a l l _ B a l l I n P l a y { o b j e c t sender, E v e n t A r g s e) {<br />

^<br />

t h r o w n e w N o t l m p l e m e n t e d E x c e p t i o n ();<br />

/ " i/icp no цмолчанию вставля<strong>е</strong>т исключ<strong>е</strong>ни<strong>е</strong><br />

^ — / MotlmplementedExceptionQ в кач<strong>е</strong>ств<strong>е</strong><br />

t i н<strong>е</strong> hedem e сюда нужный код и<br />

появится сообщ<strong>е</strong>ни<strong>е</strong> о том, что м<strong>е</strong>тод н<strong>е</strong>р<strong>е</strong>ализобан.<br />

Зав<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> обработчика событий для класса pitcher<br />

Вы добавили ск<strong>е</strong>л<strong>е</strong>т, т<strong>е</strong>п<strong>е</strong>рь нужно нарастить на н<strong>е</strong>го мышцы. Нападающий пода<strong>е</strong>т низко<br />

л<strong>е</strong>тящи<strong>е</strong> мячи или защища<strong>е</strong>т п<strong>е</strong>рвую базу.<br />

v o i d b a l l _ B a l l I n P l a y ( o b j e c t sender, E v e n t A r g s e) {<br />

if (e is B a l l E v e n t A r g s ) {<br />

B a l l E v e n t A r g s b a l l E v e n t A r g s = e a s B a llE v e n t A r g s ;<br />

if { ( b a l l E v e n t A r g s . D i s t a n c e < 95) & & f ^ ( b a l l E v e n t A r g s . T r a j e c t o r y < 60))<br />

C a t c h B a l l ();<br />

„звоЗииО<br />

EventArgs,<br />

»“ З <strong>е</strong> г и <strong>е</strong> м к нисхо-<br />

^pu помощи<br />

добавл<strong>е</strong>ны ч<strong>е</strong>р<strong>е</strong>з минуту.<br />

доступа к <strong>е</strong>го сбоистб<br />

дальш<strong>е</strong> > 501


со<strong>е</strong>диним вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong><br />

пражн<strong>е</strong>ни<strong>е</strong><br />

П р и ш л о вр<strong>е</strong>м я прим <strong>е</strong>нить получ<strong>е</strong>нны <strong>е</strong> знания на практик<strong>е</strong>. В а м нужно<br />

закончить классы Ball и Pitcher, д о б ави ть класс Fan и уб<strong>е</strong>диться, что<br />

они р аб о таю т правильно.<br />

Зав<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> класса Pitcher.<br />

М<strong>е</strong>тоды CatchBall () и CoverFirstBase () должны выводить информацию<br />

о том, что защитник или ловит мяч или б<strong>е</strong>жит на п<strong>е</strong>рвую базу.<br />

class Pitcher {<br />

public Pitcher(Ball ball) {<br />

ball.BalllnPlay += new EventHandler(ball_BallInPlay);<br />

void ball_BallInPlay(object sender, EventArgs e) {<br />

if (e is BallEventArgs){<br />

BallEventArgs ballEventArgs = e as BallEventArgs;<br />

if ((ballEventArgs.Distance < 95) && (ballEventArgs.Trajectory < 60))<br />

CatchBall{);<br />

else<br />

CoverFirstBase0 ;<br />

^<br />

Эти два м<strong>е</strong>тода должны<br />

1 выводить р<strong>е</strong>зульт ат на<br />

консоль.<br />

О<br />

Создани<strong>е</strong> класса Fan.<br />

Конструктор класса Fan долж<strong>е</strong>н быть подписан на событи<strong>е</strong><br />

BalllnPlay. Его обработчик событий долж<strong>е</strong>н пров<strong>е</strong>рять, н<strong>е</strong><br />

пр<strong>е</strong>выша<strong>е</strong>т ли расстояни<strong>е</strong> 400 футов, а тра<strong>е</strong>ктория 30 (хоум-ран),<br />

и при пр<strong>е</strong>выш<strong>е</strong>нии знач<strong>е</strong>ний пытаться поймать мяч. В противном<br />

случа<strong>е</strong> бол<strong>е</strong>льщик кричит. Выв<strong>е</strong>дит<strong>е</strong> р<strong>е</strong>зультат на консоль.<br />

Хоум-ран — удар, при<br />

котором мяч прол<strong>е</strong>т а­<br />

<strong>е</strong>т вс<strong>е</strong> пол<strong>е</strong> и выл<strong>е</strong>та<strong>е</strong>т<br />

за <strong>е</strong>го пр<strong>е</strong>д<strong>е</strong>лы.<br />

Точный список вывода вы увидит<strong>е</strong><br />

на рисунк<strong>е</strong> на сл<strong>е</strong>дующ<strong>е</strong>й страниц<strong>е</strong>.<br />

Fan<br />

502 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Q<br />

Постро<strong>е</strong>ни<strong>е</strong> простого симулятора.<br />

Создайт<strong>е</strong> новую форму с двумя эл<strong>е</strong>м<strong>е</strong>нтами NumericUpDown: один<br />

для расстояния, другой для тра<strong>е</strong>ктории. Добавьт<strong>е</strong> кнопку Play ball!<br />

Щ<strong>е</strong>лчок на н<strong>е</strong>й соотв<strong>е</strong>тству<strong>е</strong>т удару по мячу, посл<strong>е</strong> ч<strong>е</strong>го мяч л<strong>е</strong>тит<br />

с указанными в сч<strong>е</strong>тчиках парам<strong>е</strong>трами. Форма должна выгляд<strong>е</strong>ть<br />

прим<strong>е</strong>рно вот так;<br />

диапазон эшого знач<strong>е</strong><br />

т ия м о ж <strong>е</strong>т м<strong>е</strong>няться<br />

отОдо ХО О .поэт о- '<br />

М9 свойству M inim um<br />

(л-рисбоиил<strong>е</strong> Зн 503


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

la’w u e u M o<br />

1с1ЖН<strong>е</strong>пп<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

вы глядит код с написанны м и классам и Ball и Pitcher и добавл <strong>е</strong>нны м<br />

классом Fan.<br />

c l a s s B a l l<br />

{<br />

}<br />

public event EventHandler BalllnPlay;<br />

public void OnBalllnPlay(BallEventArgs e) {<br />

EventHandler balllnPlay = BalllnPlay;<br />

if (balllnPlay 1= null)<br />

balllnPlay(this, e)<br />

В кач<strong>е</strong>ств<strong>е</strong> аргу- c l a s s B a llE v e n t A r g s : E v e n tA r g s<br />

м<strong>е</strong>нтов события (<br />

пр<strong>е</strong>красно подходят<br />

авт омат и­<br />

ч<strong>е</strong>ски добавля<strong>е</strong>мы<strong>е</strong><br />

пр<strong>е</strong>дназнач<strong>е</strong>нны<strong>е</strong><br />

только для чт <strong>е</strong>­<br />

ния свойства.<br />

В<strong>е</strong>дь обработчики<br />

событий только<br />

читают п<strong>е</strong>р<strong>е</strong>дава<strong>е</strong>мый<br />

им данны<strong>е</strong>. }<br />

public int Trajectory { get; private set; }<br />

public int Distance { get; private set; }<br />

public BallEventArgs(int trajectory, int distance)<br />

c l a s s Fan {<br />

this.Trajectory = trajectory;<br />

this.Distance = distance;<br />

public Fan(Ball ball!<br />

М<strong>е</strong>тод ОпВаШпР1ау() вызыва<strong>е</strong>т<br />

событи<strong>е</strong> ВаШпР(аи. Н<strong>е</strong><br />

забудьт<strong>е</strong> пров<strong>е</strong>рить, н<strong>е</strong> равно<br />

ли <strong>е</strong>го знач<strong>е</strong>ни<strong>е</strong> пиЦ инач<strong>е</strong> он<br />

стан<strong>е</strong>т причиной исключ<strong>е</strong>ния<br />

Конструктор объ<strong>е</strong>кта<br />

Fan привязыва<strong>е</strong>т свой<br />

обработчик события<br />

к событию BalllnPlay.<br />

ball.BalllnPlay += new EventHandler(ball_BallInPlay);<br />

Обработчик собы- void ball_BallInPlay(object sender, EventArgs e)<br />

тия BaJllnPlay клас- {<br />

ca fan высматрива if (e is BallEventArgs) {<br />

em высоко л<strong>е</strong>тящи<strong>е</strong><br />

мячи, брош<strong>е</strong>нны<strong>е</strong><br />

BallEventArgs ballEventArgs = e as BallEventArgs;<br />

на слишком длинную<br />

if (ballEventArgs.Distance > 400 && ballEventArgs.Trajectory > 30)<br />

дистанцию.<br />

Console.WriteLine("Fan: Home run! I'm going for the ball!");<br />

else<br />

}<br />

}<br />

Console.WriteLine("Fan: Woo-hoo! Yeah!");<br />

504 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

c l a s s P i t c h e r {<br />

}<br />

p u b l i c P i t c h e r ( B a l l ball) {<br />

}<br />

b a l l . B a l l l n P l a y += n e w E v e n t H a n d l e r ( b a l l _ B a l l I n P l a y ) ;<br />

v o i d b a l l _ B a l l I n P l a y ( o b j e c t sender, E v e n t A r g s e)<br />

}<br />

if (e is B a l l E v e n t A r g s ) {<br />

}<br />

B a l l E v e n t A r g s b a l l E v e n t A r g s = e as B a l l E v e n t A r g s ;<br />

В класс<strong>е</strong> pitcher уж<strong>е</strong> им <strong>е</strong>-<br />

—s <strong>е</strong>тся обработчик события<br />

dC BalllnPlay. Он пров<strong>е</strong>ря<strong>е</strong>т<br />

низко л<strong>е</strong>тящ,и<strong>е</strong> мячи.<br />

if ( ( b a l l E v e n t A r g s . D i s t a n c e < 95) S=& ( b a l l E v e n t A r g s . T r a j e c t o r y < 60))<br />

else<br />

C a t c h B a l l ();<br />

C o v e r F i r s t B a s e ();<br />

p r i v a t e v o i d C a t c h B a ll0 {<br />

}<br />

C o n s o l e . W r i t e L i n e ( " P i t c h e r : I c a u g h t the ball");<br />

p r i v a t e v o i d C o v e r F ir s t B a s e () {<br />

}<br />

C o n s o l e . W r i t e L i n e ( " P i t c h e r : I c o v e r e d first base");<br />

p u b l i c p a r t i a l c l a s s F orm l : Form {<br />

B a l l b a l l = n e w B a l l O ;<br />

P i t c h e r p i t cher;<br />

F a n fan;<br />

p u b l i c F o r m l 0 {<br />

I n i t i a l i z e C o m p o n e n t ();<br />

p i t c h e r = n e w P i t c h e r ( b a l l<br />

fan = n e w F a n (ball);<br />

}<br />

Форм<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся один мяч,<br />

один бол<strong>е</strong>льщик и один нападающий.<br />

В сво<strong>е</strong>м конструктор<strong>е</strong><br />

она связыва<strong>е</strong>т<br />

бол<strong>е</strong>льщика и нападающ<strong>е</strong>го<br />

с мячом.<br />

Щ<strong>е</strong>лчок Нй кнопк<strong>е</strong> заставля<strong>е</strong>т нападающ<strong>е</strong>го<br />

выполнить подачу, в р<strong>е</strong>зультат<strong>е</strong> ч<strong>е</strong>го<br />

мяч вызыва<strong>е</strong>т сво<strong>е</strong> событи<strong>е</strong> BalllnPlay. Это,<br />

в свою оч<strong>е</strong>р<strong>е</strong>дь, вызыва<strong>е</strong>т обработчики событий<br />

объ<strong>е</strong>ктов Pitcher и Fan.<br />

p r i v a t e v o i d p l a y B a l l B u t t o n _ C l i c k ( o b j e c t sender, E v e n t A r g s e) {<br />

B a l l E v e n t A r g s b a l l E v e n t A r g s = n e w B a l l E v e n t A r g s (<br />

( i n t ) t r a j e c t o r y . V a l u e , (int)distance.Value)<br />

b a l l .O n B a l l l n P l a y ( b a l l E v e n t A r g s ) ;<br />

Мяч 1:<br />

Тра<strong>е</strong>ктория:......7.5^........<br />

Расстояни<strong>е</strong>:......%OS- ■<br />

Мяч 2:<br />

Тра<strong>е</strong>ктория:....... 4-.S..<br />

Расстояни<strong>е</strong>:....... 2>0-<br />

МячЗ:<br />

Тра<strong>е</strong>ктория:......<br />

Расстояни<strong>е</strong>;..........<br />

дальш<strong>е</strong> *■ 505


пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> страницы событий<br />

Обобщ<strong>е</strong>нный EventHandler<br />

Посмотрим на объявл<strong>е</strong>ни<strong>е</strong> события в класс<strong>е</strong> Ball:<br />

p u b l i c e v e n t E v e n tH a n d le r B a l l l n P l a y ;<br />

A т <strong>е</strong> п <strong>е</strong> р ь р а с с м о т р и м о б ъ я в л <strong>е</strong> н и <strong>е</strong> с о б ы т и я C l i c k д л я к н о п к и ф о р м ы :<br />

p u b l i c e v e n t E v e n tH a n d le r Click;<br />

Они называются по-разному, но объявляются одним и т<strong>е</strong>м ж<strong>е</strong> способом. А так<br />

как вс<strong>е</strong> это пр<strong>е</strong>красно работа<strong>е</strong>т, постронни<strong>е</strong> могут и н<strong>е</strong> знать, что обработчик<br />

BallEventHandler п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т BallEventArgs при возникнов<strong>е</strong>нии события. К счастью,<br />

.NET им<strong>е</strong><strong>е</strong>тся инструм<strong>е</strong>нт, позволяющий л<strong>е</strong>гко сообщить эту информацию, —<br />

обобщ<strong>е</strong>нный EventHandler. Изм<strong>е</strong>нит<strong>е</strong> обработчик события BalllnPlay вот таким<br />

образом:<br />

Обобщ<strong>е</strong>нный<br />

аргум<strong>е</strong>нт<br />

EventHandler<br />

долж<strong>е</strong>н быть<br />

производным<br />

от EventArgs.<br />

public event EventHandler B^lInPlay;<br />

Вам понадобиться отр<strong>е</strong>дактировать и м<strong>е</strong>тод OnBalllnPlay, зам<strong>е</strong>нив EventHandler на Event-<br />

Handler. Но при попытк<strong>е</strong> построить код в окн<strong>е</strong> Error List появится сообщ<strong>е</strong>ни<strong>е</strong><br />

о двух ошибках:<br />

Error List П X "<br />

O 2 Errors i A 0 Warnings 1 0 Messages<br />

Description File Line Column ■<br />

Q 1<br />

O 2<br />

Cannot implicit^ convert type ‘System.EventHandler' to<br />

' System.EventHandlef < Baseball. Bat[Ever^tArgs>'<br />

Cannot implicitly convert type 'System.EventHandler' to<br />

'System.EventHandler< Baseball,BsllEventArgs>'<br />

Pitcher.cs 12 32 1<br />

Fan.cs 12 32 I<br />

Д<strong>е</strong>ло в том, что посл<strong>е</strong> изм<strong>е</strong>н<strong>е</strong>ний в объявл<strong>е</strong>нии события нужно обновить классы Pitcher и Fan, заставив<br />

их п<strong>е</strong>р<strong>е</strong>давать обработчику обобщ<strong>е</strong>нный аргум<strong>е</strong>нт:<br />

b a l l .B a l l l n P l a y += n e w E v e n tH a n d le r < B a llE v e n tA r g s > ( b a l l _ B a l l I n P l a y ) ;<br />

Н<strong>е</strong>яВно<strong>е</strong> пр<strong>е</strong>образовани<strong>е</strong><br />

Автоматич<strong>е</strong>ски созданный обработчик событий буд<strong>е</strong>т обязат<strong>е</strong>льно сод<strong>е</strong>ржать ключ<strong>е</strong>во<strong>е</strong> слово new, за<br />

которым сл<strong>е</strong>ду<strong>е</strong>т <strong>е</strong>го тип. Если ж<strong>е</strong> убрать это ключ<strong>е</strong>во<strong>е</strong> слово и тип обработчика, <strong>C#</strong> осущ<strong>е</strong>ствит н <strong>е</strong> я в ­<br />

н о <strong>е</strong> п р <strong>е</strong> о б р а з о в а н и <strong>е</strong> и опр<strong>е</strong>д<strong>е</strong>лит тип за вас:<br />

b a l l . B a l l l n P l a y += b a l 1 _ В а 1 1 I n P l a y ;<br />

Зам<strong>е</strong>нит<strong>е</strong> код в конструкторах классов Pitcher и Fan указанным выш<strong>е</strong> способом. Вы увидит<strong>е</strong>, что на<br />

работ<strong>е</strong> программы это н<strong>е</strong> отразится.<br />

506 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Вс<strong>е</strong> формы используют события<br />

Создавая кнопку, дважды щ<strong>е</strong>лкая на н<strong>е</strong>й в конструктор<strong>е</strong> формы<br />

и прописывая код для м<strong>е</strong>тода b u tto n l_ C lic k ; (), вы работа<strong>е</strong>т<strong>е</strong><br />

с событиями.<br />

Q<br />

У г 1 |^ а ж н <strong>е</strong> н и <strong>е</strong><br />

Создайт<strong>е</strong> про<strong>е</strong>кт Windows Application. Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> Events (она пом<strong>е</strong>ч<strong>е</strong>на<br />

значком молнии) в окн<strong>е</strong> Properties формы. Откро<strong>е</strong>тся список событий:<br />

а ^<br />

просмотра событий,<br />

язаннш с эл<strong>е</strong>м<strong>е</strong>нтом<br />

управл<strong>е</strong>ния, выд<strong>е</strong>лит<strong>е</strong><br />

эт от эл<strong>е</strong>м<strong>е</strong>нт и щ<strong>е</strong>лкнит<strong>е</strong><br />

на кнопк<strong>е</strong> со значком<br />

молнии.<br />

Чтобы создать событи<strong>е</strong>,<br />

возникающ<strong>е</strong><strong>е</strong><br />

при щ<strong>е</strong>лчк<strong>е</strong> на фор<br />

м<strong>е</strong>, нужно выбрать<br />

в раскрывающ<strong>е</strong>мся<br />

списк<strong>е</strong> в строчк<strong>е</strong><br />

Click вариант<br />

Forml^Click.<br />

Properties<br />

F o n n l '''5 y ^ m . W i n d o w s . F o r m s . F o r m<br />

C h a n q eU ICues<br />

ClientSizeChanged<br />

С ontextMenuStripC<br />

_________<br />

FormI.Ctick<br />

Ctick<br />

Occurs when the component is dkkerf.<br />

П X<br />

І<br />

Найдит<strong>е</strong> строчку Click<br />

и дважды щ<strong>е</strong>лкнит<strong>е</strong> на<br />

н<strong>е</strong>й. ^уд<strong>е</strong>т добавл<strong>е</strong>н новый<br />

обработчик события,<br />

который активизиру<strong>е</strong>тся<br />

при любом щ<strong>е</strong>лчк<strong>е</strong><br />

на форм<strong>е</strong>. В файл<strong>е</strong><br />

formX.Designer.cs появится<br />

новая строка,<br />

связывающая обработчик<br />

и событи<strong>е</strong>.<br />

О<br />

Посл<strong>е</strong> двойного щ<strong>е</strong>лчка на строчк<strong>е</strong> Click к форм<strong>е</strong> буд<strong>е</strong>т автоматич<strong>е</strong>ски добавл<strong>е</strong>н обработчик<br />

события Forml_Click. Вв<strong>е</strong>дит<strong>е</strong> для н<strong>е</strong>го код:<br />

p r i v a t e v o i d F o r m l _ C l i c k ( o b j e c t sender, E v e n t A r g s e) {<br />

}<br />

M essa g eB o x .S h o w (" Y o u j u s t c l i c k e d on t h e fo r m " );<br />

© Visual Studio н<strong>е</strong> только пиш<strong>е</strong>т за вас объявл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода, но и связыва<strong>е</strong>т обработчик с событи<strong>е</strong>м<br />

Click формы. Откройт<strong>е</strong> файл Forml .Designer .cs и воспользуйт<strong>е</strong>сь функци<strong>е</strong>й<br />

Quick Find (Edit » Find and Replace » Quick Find) для поиска т<strong>е</strong>кста Forml_Click. Вы<br />

найд<strong>е</strong>т<strong>е</strong> строчку:<br />

t h i s . C l i c k += n e w S y s t e m . E v e n t H a n d l e r ( t h i s . F o r m l _ C l i c k ) ;<br />

Запустит<strong>е</strong> программу и уб<strong>е</strong>дит<strong>е</strong>сь, что код работа<strong>е</strong>т!<br />

страниїзу u продолжим<br />

дальш<strong>е</strong> > 507


пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> страницы событий<br />

Н<strong>е</strong>сколько обработчиков одного события<br />

События можно со<strong>е</strong>динять в ц<strong>е</strong>почки, чтобы одно событи<strong>е</strong> вызывало<br />

один за другим н<strong>е</strong>сколько м<strong>е</strong>тодов. Добавим к ваш<strong>е</strong>й форм<strong>е</strong> н<strong>е</strong>сколько<br />

кнопок, чтобы посмотр<strong>е</strong>ть, как это работа<strong>е</strong>т.<br />

Добавьт<strong>е</strong> к форм<strong>е</strong> два м<strong>е</strong>тода:<br />

private void SaySomething(object sender, EventArgs e) {<br />

}<br />

MessageBox.Show("Something");<br />

private void SaySomethingElse(object sender, EventArgs e ) {<br />

}<br />

MessageBox.Show("Something else");<br />

Добавьт<strong>е</strong> к форм<strong>е</strong> дв<strong>е</strong> кнопки и двойным ш;<strong>е</strong>лчком на каждой из них<br />

добавьт<strong>е</strong> обработчики событий:<br />

private void buttonl_Click(object sender, EventArgs e) {<br />

}<br />

this.Click += new EventHandler(SaySomething);<br />

private void button2_Click(object sender, EventArgs i<br />

}<br />

this.Click += new EventHandler(SaySomethingElse)<br />

{<br />

_ 'lacsno<br />

^ а д а Б а <strong>е</strong> М ы <strong>е</strong><br />

БоЛ|Эо


Запустит<strong>е</strong> программу и выполнит<strong>е</strong> сл<strong>е</strong>дующи<strong>е</strong> д<strong>е</strong>йствия:<br />

★ Щ<strong>е</strong>лкнит<strong>е</strong> на форм<strong>е</strong>. Появится окно с т<strong>е</strong>кстом «You just clicked on the form».<br />

события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Обработчик события<br />

^ ___ Click формы вызвал<br />

■— окно с сообщ<strong>е</strong>ни<strong>е</strong>м<br />

«Вы только что<br />

щ<strong>е</strong>лкнули на форм<strong>е</strong>».<br />

★<br />

Т<strong>е</strong>п<strong>е</strong>рь щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> buttonl, а зат<strong>е</strong>м снова на форм<strong>е</strong>. Появятся два окна<br />

с т<strong>е</strong>кстом: «Youjust clicked on the form» и «Something». 4:— '<br />

★ Дважды щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> button2, а зат<strong>е</strong>м снова на форм<strong>е</strong>. Появятся ч<strong>е</strong>тыр<strong>е</strong><br />

окна: «Youjust clicked on the form», «Something», «Something else» и «Something else».<br />

Каждый щ <strong>е</strong>лчок<br />

на кнопк<strong>е</strong><br />

приводит к<br />

появл<strong>е</strong>нии:) <strong>е</strong>щ<strong>е</strong><br />

одного окна<br />

диалога.<br />

Так что ж<strong>е</strong> происходит?<br />

Каждый щ<strong>е</strong>лчок на одной из кнопок по ц<strong>е</strong>почк<strong>е</strong> вызыва<strong>е</strong>т другой м<strong>е</strong>тод<br />

—Something () или SomethingElse () в отв<strong>е</strong>т на событи<strong>е</strong> Click формы.<br />

Если продолжить щ<strong>е</strong>лчки на кнопках, продолжится вызов т<strong>е</strong>х ж<strong>е</strong> м<strong>е</strong>то- ^<br />

дов. Событию б<strong>е</strong>зразлично колич<strong>е</strong>ство м<strong>е</strong>тодов в ц<strong>е</strong>почк<strong>е</strong>, вы даж<strong>е</strong> мож<strong>е</strong>т<strong>е</strong><br />

н<strong>е</strong>сколько раз подсо<strong>е</strong>динить один и тот ж<strong>е</strong> м<strong>е</strong>тод. Вс<strong>е</strong> они будут вызываться<br />

в том порядк<strong>е</strong>, в котором были добавл<strong>е</strong>ны, при каждом появл<strong>е</strong>нии события.<br />

Form1_Click()<br />

► SaySomethingO<br />

SaySomethingElseO<br />

I<br />

U<br />

При щ<strong>е</strong>лчк<strong>е</strong> на кнопках<br />

по ц<strong>е</strong>почк<strong>е</strong> вызываются<br />

други<strong>е</strong><br />

обработчики события<br />

Click формы.<br />

Т<br />

Э то означа<strong>е</strong>т, что щ<strong>е</strong>лчок<br />

на кнопках н<strong>е</strong> даст никакого<br />

р<strong>е</strong>зультата! Сначала<br />

нужно щ<strong>е</strong>лкнуть на форм<strong>е</strong>,<br />

так как кнопки м<strong>е</strong>няют <strong>е</strong><strong>е</strong><br />

пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong>, внося изм<strong>е</strong>н<strong>е</strong>ний<br />

в событи<strong>е</strong> Click.<br />

В ц<strong>е</strong>почку можно<br />

н<strong>е</strong>сколько раз<br />

добавить один и<br />

тот ж<strong>е</strong> м<strong>е</strong>тод.<br />

% SaySomethingElseO дальш<strong>е</strong> > 509


дающи<strong>е</strong> и принимающи<strong>е</strong><br />

Сбязь м<strong>е</strong>)кду издат<strong>е</strong>лями и подписчиками<br />

Одним из самых сложных для понимания при изуч<strong>е</strong>нии событий явля<strong>е</strong>тся обстоят<strong>е</strong>льство, что и з д а ­<br />

т <strong>е</strong> л ь ( s e n d e r ) долж<strong>е</strong>н знать, како<strong>е</strong> событи<strong>е</strong> он иницииру<strong>е</strong>т, в том числ<strong>е</strong>, каки<strong>е</strong> аргум<strong>е</strong>нты он <strong>е</strong>му п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т.<br />

И п о д п и с ч и к (r e c e iv e r ) долж<strong>е</strong>н знать, какой тип возвраща<strong>е</strong>мого знач<strong>е</strong>ния и аргум<strong>е</strong>нты сл<strong>е</strong>ду<strong>е</strong>т<br />

использовать для м<strong>е</strong>тодов обработчика событий.<br />

Но связи м<strong>е</strong>жду издат<strong>е</strong>л<strong>е</strong>м и подписчиком н<strong>е</strong>т. Издат<strong>е</strong>ль иницииру<strong>е</strong>т событи<strong>е</strong> и <strong>е</strong>му вс<strong>е</strong> равно, кто на н<strong>е</strong>го<br />

подписан. А подписчику важно, что это за событи<strong>е</strong>, но вс<strong>е</strong> равно, какой объ<strong>е</strong>кт стал <strong>е</strong>го причиной. Получа<strong>е</strong>тся,<br />

что как издат<strong>е</strong>ль, так и подписчик сфокусированы на событии, но н<strong>е</strong> друг на друг<strong>е</strong>.<br />

“*Г н .й<br />

4 У<br />

Событи<strong>е</strong> BalllnPlay<br />

до/<br />

С в<br />

О бь<strong>е</strong>кт Ball н<strong>е</strong> долж<strong>е</strong>н им <strong>е</strong>т ь<br />

связи с объ<strong>е</strong>ктом Pitcher Ему<br />

вс<strong>е</strong> равно, объ<strong>е</strong>кты какого т ипа<br />

работ аю т с событи<strong>е</strong>м: Fan,<br />

Pitcher, Umpire и т. п.<br />

prtcV'®’<br />

«Мой народ хоч<strong>е</strong>т В ступить 6 к он такт с вашим народом».<br />

Вы зна<strong>е</strong>т<strong>е</strong>, что д<strong>е</strong>ла<strong>е</strong>т этот код:<br />

B a l l c u r r e n t B a ll;<br />

Он созда<strong>е</strong>т с с ы л о ч н у ю п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н у ю на любой объ<strong>е</strong>кт B a ll.<br />

Эта п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная мож<strong>е</strong>т указывать даж<strong>е</strong> на знач<strong>е</strong>ни<strong>е</strong> null.<br />

Событиям нужна такая ж<strong>е</strong> ссылка, но указывающая н<strong>е</strong> на объ<strong>е</strong>кт,<br />

а н а м <strong>е</strong> т о д . Событиям нужно отсл<strong>е</strong>живать список подписанных<br />

на них м<strong>е</strong>тодов. Как вы уж<strong>е</strong> вид<strong>е</strong>ли, эти м<strong>е</strong>тоды могут<br />

принадл<strong>е</strong>жать другим классам и даж<strong>е</strong> быть закрытыми. Как ж<strong>е</strong><br />

отсл<strong>е</strong>дить вс<strong>е</strong> обработчики событий, которы<strong>е</strong> будут вызываться?<br />

Для этого используются д <strong>е</strong> л <strong>е</strong> г а т ы (d e le g a te ).<br />

Д<strong>е</strong>-л<strong>е</strong>-гат, сущ.<br />

ч<strong>е</strong>лов<strong>е</strong>к, им<strong>е</strong>ющий<br />

полномочия пр<strong>е</strong>дставлять<br />

других, пр<strong>е</strong>зид<strong>е</strong>нт<br />

отправил д<strong>е</strong>л<strong>е</strong>гата<br />

на саммит.<br />

510 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Д<strong>е</strong>л<strong>е</strong>гат зам<strong>е</strong>ща<strong>е</strong>т м<strong>е</strong>тоды<br />

нужно только указать<br />

Возникающ<strong>е</strong><strong>е</strong> событи<strong>е</strong> н <strong>е</strong> з н а <strong>е</strong> т , м<strong>е</strong>тоды-обработчики событий каких объ<strong>е</strong>ктов сигнатуру м<strong>е</strong>тодов,<br />

будут вызваны. Каким ж<strong>е</strong> образом событи<strong>е</strong> мож<strong>е</strong>т управлять этим проц<strong>е</strong>ссом? на которы<strong>е</strong> он мож<strong>е</strong>т<br />

ссылаться.<br />

Для этого в <strong>C#</strong> сущ<strong>е</strong>ствуют д <strong>е</strong> л <strong>е</strong> г а т ы ( d e le g a te ) . Это ссылочный тип, позволяю- !<br />

щий с с ы л а т ь с я н а м <strong>е</strong> т о д ы в н у т р и к л а с с а ... такж<strong>е</strong> д<strong>е</strong>л<strong>е</strong>гаты являются основой<br />

А<br />

для событий.<br />

Данный д<strong>е</strong>л<strong>е</strong>гат мож<strong>е</strong>т ссылаться<br />

нд любой м<strong>е</strong>тод, ис­<br />

В этой глав<strong>е</strong> вам уж<strong>е</strong> приходилось с ними сталкиваться! При создании<br />

события BalllnPlay вы работали с д<strong>е</strong>л<strong>е</strong>гатом EventHandler. пользующий в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тров<br />

оь<strong>е</strong>кт и EventArgs<br />

Щ<strong>е</strong>лкнит<strong>е</strong> на н<strong>е</strong>м правой кнопкой мыщи и выб<strong>е</strong>рит<strong>е</strong> команду «Go to<br />

definition», и вот что вы увидит<strong>е</strong>.<br />

и н<strong>е</strong> возвращающий знач<strong>е</strong>ния.<br />

public delegate void EventHandler(object sender, EventArgs e) \<br />

Этот эл<strong>е</strong>м<strong>е</strong>нт сигнатуры д<strong>е</strong>л<strong>е</strong>гата<br />

показыва<strong>е</strong>т, что EventHandler мож<strong>е</strong>т<br />

ссылаться только на м<strong>е</strong>тоды, н<strong>е</strong><br />

возвращающи<strong>е</strong> знач<strong>е</strong>ния.<br />

Имя д<strong>е</strong>л<strong>е</strong>гата<br />

EventHandler.<br />

V<br />

^<br />

у п ] ^ а ж н <strong>е</strong> н и <strong>е</strong><br />

Добавля<strong>е</strong>м к про<strong>е</strong>кту ноВый т и п данных<br />

Добавляя к про<strong>е</strong>кту д<strong>е</strong>л<strong>е</strong>гаты, вы добавля<strong>е</strong>т<strong>е</strong> данны<strong>е</strong> нового типа, Используя их для создания поля или<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, вы созда<strong>е</strong>т<strong>е</strong> э к з <strong>е</strong> м п л я р этого типа. О т к р о й т <strong>е</strong> н о в ы й п р о <strong>е</strong> к т C o n s o le A p p lic a t io n и добавьт<strong>е</strong><br />

к н<strong>е</strong>му новый файл классов ConvertsIntToString.cs. Вв<strong>е</strong>дит<strong>е</strong> одну строчку:<br />

d e l e g a t e s t r i n g C o n v e r t s I n t T o S t r i n g ( i n t i ) ;<br />

Добавьт<strong>е</strong> в класс Program м<strong>е</strong>тод HiThere ():<br />

p r i v a t e s t a t i c s t r i n g H i T h e r e ( i n t i)<br />

{ 'F -<br />

r e t u r n "Hi there! #" + (i * 100)<br />

)<br />

Заполнит<strong>е</strong> м<strong>е</strong>тод Main ():<br />

s t a t i c v o i d M a i n ( s t r i n g [] args)<br />

{<br />

Сигнатура этого<br />

м<strong>е</strong>тода совпада<strong>е</strong>т<br />

с ReturnsAString.<br />

Ещ<strong>е</strong> одним добавл<strong>е</strong>нным в про<strong>е</strong>кт<br />

д<strong>е</strong>л<strong>е</strong>гатом явля<strong>е</strong>тся<br />

ConvertsIntToString. Его можно<br />

использовать для объявл<strong>е</strong>ния<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных точно так ж<strong>е</strong>, как<br />

вы д<strong>е</strong>лали бы это для класса или<br />

инт<strong>е</strong>рф<strong>е</strong>йса.<br />

someMetkod — это п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная типа<br />

ConvertsIntToString. От обычной ссылочной<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной она отлича<strong>е</strong>тся т<strong>е</strong>м, что цка-<br />

^ зыва<strong>е</strong>т н<strong>е</strong> на объ<strong>е</strong>кт в куч<strong>е</strong>, а на м<strong>е</strong>т о1<br />

C o n v e r t s I n t T o S t r i n g s o m e M e t h o d = n e w C o n v e r t s I n t T o S t r i n g ( H i T h e r e ) ;<br />

s t r i n g m e s s a g e = s o m e M e t h o d (5);<br />

c o n s o l e . w r i t e L i n e ( m e s s a g e ) ; д П <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й<br />

}<br />

П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная someMethod указыва<strong>е</strong>т на м<strong>е</strong>тод HiThere (). Записью someMethod (5) вызыва<strong>е</strong>тся м<strong>е</strong>тод<br />

HiThere (), которому п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся аргум<strong>е</strong>нт 5. В итог<strong>е</strong> возвраща<strong>е</strong>тся строкаН1 there!#500. Просмотрит<strong>е</strong><br />

программу в р<strong>е</strong>жим<strong>е</strong> отладки, чтобы понять, что им<strong>е</strong>нно происходит.<br />

дальш<strong>е</strong> ► 511


д<strong>е</strong>л<strong>е</strong>гируйт<strong>е</strong> свои полномочия<br />

Д <strong>е</strong>л<strong>е</strong>гаты В geiicmBuu , ,<br />

Работать с д<strong>е</strong>л<strong>е</strong>гатами л<strong>е</strong>гко, они н<strong>е</strong> тр<strong>е</strong>буют большого объ<strong>е</strong>ма кода. По- \ Г '<br />

пробу<strong>е</strong>м с их помош;ью помочь влад<strong>е</strong>льцу р<strong>е</strong>сторана рассортировать с<strong>е</strong>- J Tlj^& yK H 0H U 0,<br />

кр<strong>е</strong>тны<strong>е</strong> ингр<strong>е</strong>ди<strong>е</strong>нты с кухни ш<strong>е</strong>ф-повара.<br />

^<br />

О Добавьт<strong>е</strong> д<strong>е</strong>л<strong>е</strong>гат в новый про<strong>е</strong>кт<br />

Д<strong>е</strong>л<strong>е</strong>гаты обычно располагаются вн<strong>е</strong> классов, поэтому добавьт<strong>е</strong> к про<strong>е</strong>кту новый файл<br />

классов G e tS e c re t I n g r e d i e n t . c s и вв<strong>е</strong>дит<strong>е</strong> в н<strong>е</strong>го строку:<br />

delegate string GetSecretlngredient(int amount);<br />

(Полностью удалит<strong>е</strong> объявл<strong>е</strong>ни<strong>е</strong> класса.) Этот д<strong>е</strong>л<strong>е</strong>гат стан<strong>е</strong>т основой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, указываюш;<strong>е</strong>й<br />

на м<strong>е</strong>тод, который, взяв парам<strong>е</strong>тр типа i n t, возвраш;а<strong>е</strong>т строку.<br />

О Добавьт<strong>е</strong> класс для п<strong>е</strong>рвого ш<strong>е</strong>ф-повара, Сюзанны<br />

Suzanne.cs сод<strong>е</strong>ржит класс, сл<strong>е</strong>дяш;ий за с<strong>е</strong>кр<strong>е</strong>тными ингр<strong>е</strong>ди<strong>е</strong>нтами, которы<strong>е</strong> использу<strong>е</strong>т<br />

Сюзанна. Он снабж<strong>е</strong>н закрытым м<strong>е</strong>тодом SuzannesSecretlngredient () с сигнатурой,<br />

совпадающ<strong>е</strong>й с GetSecretlngredient. Им<strong>е</strong><strong>е</strong>тся и пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong> только для чт<strong>е</strong>ния<br />

свойство, возвращающ<strong>е</strong><strong>е</strong> GetSecretlngredient. С <strong>е</strong>го помощью остальны<strong>е</strong> объ<strong>е</strong>кты<br />

могут получить ссылку на м<strong>е</strong>тод SuzannesIngredientList ().<br />

c l a s s S u z a n n e {<br />

Взяв п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>н- p u b l i c G e t S e c r e t l n g r e d i e n t M y S e c r e t l n g r e d i e n t M e t h o d {<br />

ную am ount g e t {<br />

т о д % т в р ^ а <strong>е</strong> т = f e t u m n e w G e t S e c r e t l n g r e d i e n t ( S u z a n n e s S e c r e t l n g r e d i e n t ) ;<br />

строку, onucbi- ^<br />

бающую ce- J<br />

кр<strong>е</strong>тный ингр<strong>е</strong>- p r i v a t e s t r i n g S u z a n n e s S e c r e t l n g r e d i e n t ( i n t a m o u n t) {<br />

ди<strong>е</strong>нт. — aj, r e t u r n a m o u n t .T o S t r i n g 0 + " o u n c e s o f c l o v e s " ;<br />

}<br />

} Свойство GetSecretlngredient<br />

возвраща<strong>е</strong>т новый экз<strong>е</strong>мпляр<br />

п < _<br />

Добавьт<strong>е</strong> класс для второго ш<strong>е</strong>ф-повара. Эми ^<br />

д<strong>е</strong>л<strong>е</strong>гата GetSecretlngredient,<br />

указывающ<strong>е</strong>го на м<strong>е</strong>тод полу-<br />

М<strong>е</strong>тоды Эми работают так ж<strong>е</strong>, как м<strong>е</strong>тоды Сюзанны: / цтия с<strong>е</strong>кр<strong>е</strong>тных ингр<strong>е</strong>ди<strong>е</strong>нтов.<br />

д c l a s s Amy { М<br />

м<strong>е</strong>тод получ<strong>е</strong>- p u b l i c G e t S e c r e t l n g r e d i e n t A m y s S e c r e t l n g r e d i e n t M e t h o d (<br />

ния с<strong>е</strong>кр<strong>е</strong>тных g e t {<br />

ингр<strong>е</strong>ди<strong>е</strong>нтов, r e t u r n n e w G e t S e c r e t l n g r e d i e n t ( A m y s S e c r e t l n g r e d i e n t ) ;<br />

c которыми }<br />

работа<strong>е</strong>т Эми, }<br />

так ж<strong>е</strong> б<strong>е</strong>р<strong>е</strong>т ( p r i v a t e s t r i n g A m y s S e c r e t l n g r e d i e n t ( i n t a m o u n t) {<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную i f (a m o u n t < Ю ) .<br />

am ount типа < r e t u r n a m o u n t .T o S t r i n g O<br />

int и возвраща- ) ^ I s e " s a r d i n e s - - y o u n e e d m o r e ! " ;<br />

em строку. Ho / r e t u r n a m o u n t .T o S t r i n g O + " c a n s o f s a r d i n e s " ;<br />

это уж<strong>е</strong> другая ч }<br />

строка. }<br />

512 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Добавьт<strong>е</strong> к про<strong>е</strong>кту д<strong>е</strong>л<strong>е</strong>гаты<br />

Постройт<strong>е</strong> форму. —<br />

Это <strong>е</strong><strong>е</strong> код:<br />

G e t S e c r e t l n g r e d i e n t i n g r e d i e n t M e t h o d = null;<br />

S u z a n n e S u z a n n e = n e w S u z a n n e ();<br />

A m y a m y = n e w A m y ();<br />

Secret Ingredients<br />

Gei the ingredient<br />

Get Suzannes delegate<br />

Get Amy's delegate<br />

p r i v a t e v o i d u s e I n g r e d i e n t _ C l i c k (object sender, E v e n t A r g s e) {<br />

}<br />

if ( i n g r e d i e n t M e t h o d != null)<br />

C o n s o l e . W r i t e L i n e ( " I ' 11 a d d " + i n g r e d i e n t M e t h o d ( (int)a m o u n t. V a l u e ) );<br />

else<br />

C o n s o l e . W r i t e L i n e ( " I d o n ' t h a v e a s e c r e t i n g r e d i e n t ! " ) ;<br />

p r i v a t e v o i d g e t S u z a im e _ C lic k (object sender, E v e n t A r g s e) {<br />

}<br />

i n g r e d i e n t M e t h o d = n e w G e t S e c r e t l n g r e d i e n t ( s u z a n n e . M y S e c r e t l n g r e d i e n t M e t h o d ) ;<br />

p r i v a t e v o i d g e t A m y _ C l i c k ( o b j e c t sender, E v e n t A r g s e) {<br />

}<br />

i n g r e d i e n t M e t h o d = n e w G e t S e c r e t l n g r e d i e n t ( a m y . A m y s S e c r e t l n g r e d i e n t M e t h o d ) ;<br />

О Посмотрит<strong>е</strong> на работу д<strong>е</strong>л<strong>е</strong>гатов при помощи отладчика<br />

Воспользуйт<strong>е</strong>сь отладчиком, чтобы понять принцип работы д<strong>е</strong>л<strong>е</strong>гатов:<br />

★<br />

Запустит<strong>е</strong> программу. Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> «Get the ingredient», на консоль буд<strong>е</strong>т выв<strong>е</strong>д<strong>е</strong>на<br />

строка «I don’t have а secret ingredient!»<br />

★ Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> «Get Suzanne’s delegate», которая присваива<strong>е</strong>т полю in g r e d ie n t- ,<br />

M ethod формы (являющ<strong>е</strong>муся д<strong>е</strong>л<strong>е</strong>гатом G e tS e c re tln g r e d ie n t) знач<strong>е</strong>ни<strong>е</strong>, возвраща<strong>е</strong>мо<strong>е</strong><br />

свойством G e tS e c re tln g r e d ie n t. Это новый экз<strong>е</strong>мпляр типа G e tS e c re tln g r e d ie n t,<br />

указывающий на м<strong>е</strong>тод S u z a n n e s S e c re tln g re d ie n t ().<br />

★<br />

Снова щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> «Get the ingredient». Т<strong>е</strong>п<strong>е</strong>рь, когда пол<strong>е</strong> in g re d ie n tM e th o d<br />

указыва<strong>е</strong>т на S u z a n n e s S e c re tln g re d ie n t (), произойд<strong>е</strong>т вызов этого м<strong>е</strong>тода, и <strong>е</strong>го знач<strong>е</strong>ни<strong>е</strong><br />

буд<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>дано numericUpDown (уб<strong>е</strong>дит<strong>е</strong>сь, что он называ<strong>е</strong>тся am ount), а зат<strong>е</strong>м<br />

выв<strong>е</strong>д<strong>е</strong>но на консоль.<br />

★ Щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> «Get Amy’s delegate». Она использу<strong>е</strong>т свойство А ту.G e t­<br />

S e c r e tln g r e d ie n t, чтобы присвоить полю in g re d ie n tM e th o d знач<strong>е</strong>ни<strong>е</strong> A m ysS ecretln<br />

g r e d ie n t ().<br />

★<br />

★<br />

Снова щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> «Get the ingredient». Буд<strong>е</strong>т вызван м<strong>е</strong>тод Эми.<br />

Пом<strong>е</strong>стит<strong>е</strong> точки останова в п<strong>е</strong>рвы<strong>е</strong> строчки каждого из тр<strong>е</strong>х м<strong>е</strong>тодов формы. П<strong>е</strong>р<strong>е</strong>запустит<strong>е</strong><br />

программу (чтобы м<strong>е</strong>тод in g re d ie n tM e th o d стал рав<strong>е</strong>н null) и снова выполнит<strong>е</strong><br />

вс<strong>е</strong> выш<strong>е</strong>указанны<strong>е</strong> шаги. Используйт<strong>е</strong> функцию Step Into (F ll). Отсл<strong>е</strong>живайт<strong>е</strong>, что происходит<br />

при щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> «Get the ingredient».<br />

%<br />

дальш<strong>е</strong> > 513


ч<strong>е</strong>р<strong>е</strong>счур открыты<strong>е</strong> события<br />

Б б а с с <strong>е</strong> й н <strong>е</strong><br />

p u b l i c F o r m l О {<br />

I n i t i a l i z e C o m p o n e n t O ;<br />

}<br />

t h i s . ________ += n e w E v e n t H a n d l e r (Mini van) ;<br />

t h i s . ________ += n e w E v e n t H a n d l e r {___________<br />

v o i d T o w t r u c k ( o b j e c t sender, E v e n t A r g s e) {<br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна<br />

и заполнит<strong>е</strong> пропуски. Каждый<br />

фрагм<strong>е</strong>нт мож<strong>е</strong>т быть использован н<strong>е</strong>сколько<br />

раз. В басс<strong>е</strong>йн<strong>е</strong> <strong>е</strong>сть лишни<strong>е</strong><br />

фрагм<strong>е</strong>нты. Вам нужно, чтобы при<br />

щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> b u t t o n l на консоль<br />

выводился сл<strong>е</strong>дующий р<strong>е</strong>зультат:<br />

Р<strong>е</strong>зультат:<br />

F i n g e r s i s c o in in g t o g e t y o u !<br />

}<br />

C o n s o l e . W r i t e ( " i s c o m i n g ");<br />

v o i d M o t o r c y c l e ( o b j e c t sender, E v e n t A r g s e) {<br />

b u t t o n l . ________ += n e w E v e n t H a n d l e r (________________) ;<br />

}<br />

v o i d B i c y c l e ( o b j e c t sender, E v e n t A r g s e) {<br />

C o n s o l e . W r i t e L i n e ("to g et you!");<br />

}<br />

v o i d ________________(object sender, E v e n t A r g s e) {<br />

b u t t o n l .________ += n e w E v e n t H a n d l e r (Dumptruck) ;<br />

b u t t o n l . ________ += n e w E v e n t H a n d l e r (________________);<br />

}<br />

v o i d ________________(object sender, E v e n t A r g s e) {<br />

Каждый фрагм<strong>е</strong>нт<br />

мож<strong>е</strong>т быть использован<br />

н<strong>е</strong>сколько<br />

раз.<br />

C o n s o l e . W r i t e (" Fingers ");<br />

514 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Объ<strong>е</strong>кт мо)к<strong>е</strong>т подписаться на событи<strong>е</strong>...<br />

Пр<strong>е</strong>дположим, для симулятора был создан класс Bat (Бита), который добавля<strong>е</strong>т событи<strong>е</strong> HitTheBall.<br />

Обнаружив, что игрок ударил по мячу, симулятор вызыва<strong>е</strong>т м<strong>е</strong>тод OnHitTheBall {) объ<strong>е</strong>кта Bat, который<br />

вызыва<strong>е</strong>т событи<strong>е</strong> HitTheBall.<br />

Поэтому к классу Ball можно добавить м<strong>е</strong>тод bat_HitTheBall, который подпиш<strong>е</strong>тся на событи<strong>е</strong><br />

HitTheBall. При удар<strong>е</strong> по мячу уж<strong>е</strong> <strong>е</strong>го собств<strong>е</strong>нный обработчик вызов<strong>е</strong>т м<strong>е</strong>тод OnBalllnPlay () для<br />

уж<strong>е</strong> <strong>е</strong>го собств<strong>е</strong>нного события BalllnPlay, и ц<strong>е</strong>почка начн<strong>е</strong>т работу. Игроки играют, бол<strong>е</strong>льщики визжат,<br />

судьи кричат... всё как на р<strong>е</strong>альном матч<strong>е</strong>.<br />

Симулят ор обнаружил<br />

столкнов<strong>е</strong>ни<strong>е</strong> м я ч а<br />

с Зитой, поэтому<br />

был бызбан м<strong>е</strong>тод<br />

ОпНИТк<strong>е</strong>ВаЮ биты.<br />

О бш кт Ball подписан<br />

на событи<strong>е</strong> HitTheBall.<br />

Обработчик получа<strong>е</strong>т<br />

информацию о сил<strong>е</strong> удара,<br />

опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т расстояни<strong>е</strong><br />

и тра<strong>е</strong>кторию и вызыва<strong>е</strong>т<br />

событи<strong>е</strong> BalllnPlay.<br />

Вал<br />

...НО э т о н<strong>е</strong> Вс<strong>е</strong>гда х о р о ш о !<br />

в & ^<br />

Событи<strong>е</strong> HitTheBall<br />

в игр<strong>е</strong> мож<strong>е</strong>т присутствовать только один мяч. Но <strong>е</strong>сли объ<strong>е</strong>кт<br />

Bat при помощи события п<strong>е</strong>р<strong>е</strong>даст информацию об удар<strong>е</strong> по<br />

мячу, подписаться на н<strong>е</strong>го смож<strong>е</strong>т любой объ<strong>е</strong>кт Ball. Пр<strong>е</strong>дставьт<strong>е</strong>,<br />

что программист случайно добавил <strong>е</strong>щ<strong>е</strong> три объ<strong>е</strong>кта<br />

Ball. Что произойд<strong>е</strong>т в этом случа<strong>е</strong>? Посл<strong>е</strong> удара битой по полю<br />

разл<strong>е</strong>тятся ч<strong>е</strong>ты р<strong>е</strong> мяча!<br />

О й ' Э т о ж <strong>е</strong> были р<strong>е</strong>з<strong>е</strong>р<br />

вит<br />

мячи, добавл<strong>е</strong>нны<strong>е</strong> на вс '1СЯКий<br />

случаи.<br />

i<br />

Н о б<strong>е</strong>ззаботный програм м ист<br />

Тодписал и х б<strong>е</strong><strong>е</strong> н а событи<strong>е</strong><br />

H itTheBall- поэт ому посл<strong>е</strong><br />

идаюа битой по МЯчу,<br />

f r r a c Ä — -<br />

мяча! ^<br />

дальш<strong>е</strong> > 515


обратный вызов<br />

Обратный Вызов<br />

События в сист<strong>е</strong>м<strong>е</strong> работают корр<strong>е</strong>ктно, <strong>е</strong>сли объ<strong>е</strong>кты Ball и Bat им<strong>е</strong>ются в <strong>е</strong>динств<strong>е</strong>нном числ<strong>е</strong>. В ситуации,<br />

когда мяч<strong>е</strong>й больш<strong>е</strong> одного, вс<strong>е</strong> они оказываются подписаны на событи<strong>е</strong> HitTheBall и при <strong>е</strong>го<br />

возникнов<strong>е</strong>нии вбрасываются в игру, что н<strong>е</strong> им<strong>е</strong><strong>е</strong>т никакого смысла. Другими словами, нам нужно связать<br />

с битой вс<strong>е</strong>го один мяч, исключив возможность привязки других мяч<strong>е</strong>й.<br />

в этом нам помож<strong>е</strong>т о б р а т н ы й в ы з о в (c a llb a c k ). Так называ<strong>е</strong>тся т<strong>е</strong>хника работы с д<strong>е</strong>л<strong>е</strong>гатами, при<br />

которой вм<strong>е</strong>сто события, доступного для подписки любым объ<strong>е</strong>ктам, использу<strong>е</strong>тся м<strong>е</strong>тод (часто конструктор),<br />

с хранящимся в закрытом пол<strong>е</strong> д<strong>е</strong>л<strong>е</strong>гатом в кач<strong>е</strong>ств<strong>е</strong> аргум<strong>е</strong>нта. Обратный вызов позволит<br />

нам гарантировать, что объ<strong>е</strong>кт Bat опов<strong>е</strong>ща<strong>е</strong>т вс<strong>е</strong>го один объ<strong>е</strong>кт Ball:<br />

О Объ<strong>е</strong>кт B a t сохраня<strong>е</strong>т пол<strong>е</strong> д<strong>е</strong>л<strong>е</strong>гата закрытым<br />

Пр<strong>е</strong>дотвратить возможность создания ц<strong>е</strong>поч<strong>е</strong>к из объ<strong>е</strong>ктов Ball помож<strong>е</strong>т закрыти<strong>е</strong> хранящ<strong>е</strong>го<br />

эту информацию поля. В этом случа<strong>е</strong> объ<strong>е</strong>кт Bat управля<strong>е</strong>т вызовом нужного м<strong>е</strong>тода<br />

объ<strong>е</strong>кта Ball.<br />

О<br />

О<br />

Конструктор объ<strong>е</strong>кта B a t<br />

Когда мяч оказыва<strong>е</strong>тся в игр<strong>е</strong>, конструктор созда<strong>е</strong>т экз<strong>е</strong>мпляр биты и п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т указат<strong>е</strong>ль<br />

на н<strong>е</strong>го м<strong>е</strong>тоду OnBalllnPlay ( ). Это м <strong>е</strong> т о д о б р а т н о г о в ы з о в а , так как объ<strong>е</strong>кт Bat использу<strong>е</strong>т<br />

<strong>е</strong>го для вызовы объ<strong>е</strong>кта, который <strong>е</strong>го создал.<br />

Объ<strong>е</strong>кт Ball п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т<br />

сш лку на д<strong>е</strong>л<strong>е</strong>гат сво<strong>е</strong>-<br />

_ му собств<strong>е</strong>нномц м<strong>е</strong>тоди<br />

ОпВаІІІпРІауО в конструк-<br />

1 \^ ^ тор<strong>е</strong> объ<strong>е</strong>кта Bat. Посл<strong>е</strong>дний<br />

сохраня<strong>е</strong>т данный<br />

д<strong>е</strong>л<strong>е</strong>гат в закрытом пол<strong>е</strong><br />

hitriaeBallCallback.<br />

Когдо Bat ударя<strong>е</strong>т по мячу, он использу<strong>е</strong>т м<strong>е</strong>тод обратного вызова<br />

Но пока Bat скрыва<strong>е</strong>т д<strong>е</strong>л<strong>е</strong>гат, можно быть полностью ув<strong>е</strong>р<strong>е</strong>нным в том, что ни<br />

один другой мяч в игру н<strong>е</strong> попад<strong>е</strong>т. Вот р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> пробл<strong>е</strong>мі.]!<br />

Други<strong>е</strong> мячи н<strong>е</strong> могут<br />

подсо<strong>е</strong>диниться к эт о­<br />

му д<strong>е</strong>л<strong>е</strong>гату, так как<br />

данно<strong>е</strong> пол<strong>е</strong> объ<strong>е</strong>кта<br />

Bat закрыто.<br />

-Г hitBalICalIback<br />

t<br />

Т<strong>е</strong>п<strong>е</strong>рь<br />

объ<strong>е</strong>кт<br />

Bat мож<strong>е</strong>т вызвать<br />

д<strong>е</strong>л<strong>е</strong>гат<br />

hitBallCallhackj который,<br />

в свою оч<strong>е</strong>р<strong>е</strong>дь,<br />

вызов<strong>е</strong>т м <strong>е</strong> ­<br />

тод OnBallInPiayQ<br />

объ<strong>е</strong>кта Ball.<br />

516 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

IJ ягоиМ иш ^щ ная<br />

т а й н а<br />

Случай с золотым крабом<br />

І<strong>е</strong>нри «Простак» Ходкингс — охотник за сокровищами (Тг<strong>е</strong>азиг<strong>е</strong>НипЪ<strong>е</strong>г).<br />

С<strong>е</strong>йчас он высл<strong>е</strong>жива<strong>е</strong>т одно из самых ж<strong>е</strong>ланных и р<strong>е</strong>дких юв<strong>е</strong>лирных изд<strong>е</strong>лий на<br />

морскую т<strong>е</strong>му —инструктированного н<strong>е</strong>фритами золотого краба. Но охотников<br />

за сокровищами много. И в их конструкторах так ж<strong>е</strong> присутству<strong>е</strong>т ссылка на этого<br />

краба. І<strong>е</strong>нри ж<strong>е</strong> хоч<strong>е</strong>т найти сокровищ<strong>е</strong> п<strong>е</strong>рвым.<br />

Из украд<strong>е</strong>нных диаграмм классов Г<strong>е</strong>нри узнал, что как только кто-то<br />

приближа<strong>е</strong>тся к крабу, класс Со1(і<strong>е</strong>пСгаЬ вызыва<strong>е</strong>т событи<strong>е</strong> Кип-<br />

ForC over (Поб<strong>е</strong>г в укрыти<strong>е</strong>). Бол<strong>е</strong><strong>е</strong> того, событи<strong>е</strong> включа<strong>е</strong>т Н<strong>е</strong>ід^Ьосаtio<br />

n A rg s (Ново<strong>е</strong> м<strong>е</strong>сто), указывающ<strong>е</strong><strong>е</strong>, куда п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>стился краб. Но так<br />

как остальны<strong>е</strong> охотники н<strong>е</strong> знают о событии, І<strong>е</strong>нри счита<strong>е</strong>т, что смож<strong>е</strong>т<br />

получить сокровищ<strong>е</strong> п<strong>е</strong>рвым.<br />

Г<strong>е</strong>нри добавля<strong>е</strong>т в конструктор код, пр<strong>е</strong>вращающий м<strong>е</strong>тод tre a s u re _ R u n -<br />

F orC over () в обработчик события RunForCover. Зат<strong>е</strong>м кто-то посыла<strong>е</strong>тся за<br />

крабом, чтобы тот спрятался и вызвал событи<strong>е</strong> RunForCover —это даст м<strong>е</strong>тоду<br />

tre a su re _ R u n F o rC o v er () всю нужную информацию.<br />

Вс<strong>е</strong> шло по плану, пока Г<strong>е</strong>нри н<strong>е</strong> прибыл на нужно<strong>е</strong> м<strong>е</strong>сто и н<strong>е</strong> обнаружил, что там<br />

за краба уж<strong>е</strong> д<strong>е</strong>рутся три <strong>е</strong>го конкур<strong>е</strong>нта.<br />

К аким ж<strong>е</strong> образом они там оказались? ----------------- ►<br />

0 ш Б <strong>е</strong> т На с. ^2<br />

К онструктор<br />

посл<strong>е</strong>доват<strong>е</strong>льно<br />

добавля<strong>е</strong>т<br />

два обработчика<br />

к событи!^М<br />

Load. В итог<strong>е</strong><br />

они вызываются<br />

сразу посл<strong>е</strong> загрузки<br />

формы.<br />

Щ<strong>е</strong>лчок на кнопк<strong>е</strong> -<br />

вызыва<strong>е</strong>т ц<strong>е</strong>почку<br />

из тр<strong>е</strong>х связанных<br />

с н<strong>е</strong>й обработчиков<br />

событий.<br />

p u b l i c F o r m l 0 {<br />

I n i t i a l i z e C o m p o n e n t ();<br />

t h i s .Load += n e w E v e n t H a n d l e r ( M i n i v a n ) ;<br />

this. Load += n e w E v e n t H a n d l e r (Motorcycle) ;<br />

}<br />

v o i d T o w t r u c k ( o b j e c t sender, E v e n t A r g s e) {<br />

C o n s o l e . W r i t e ("is c o m i n g ");<br />

}<br />

v o i d M o t o r c y c l e ( o b j e c t sender, E v e n t A r g s e) {<br />

b u t t o n l .Click += n e w E v e n t H a n d l e r (Bicycle) ;<br />

v o i d B i c y c l e ( o b j e c t sender, E v e n t A r g s e) {<br />

— C o n s o l e . W r i t e L i n e ("to g e t you!");<br />

v o i d Minivan (object sender, E v e n t A r g s e) {<br />

b u t t o n l .Click -1-= n e w E v e n t H a n d l e r (Dumptruck)<br />

b u t t o n l .Click += n e w E v e n t H a n d l e r (Towtruck) ;<br />

}<br />

v o i d Dumptruck (obj ect sender, E v e n t A r g s e) {<br />

}<br />

C o n s o l e . W r i t e (" F i n g e r s ");<br />

і ^ і п <strong>е</strong> н и <strong>е</strong> p * e ^ c :a<br />

Б басс<strong>е</strong>йн<strong>е</strong><br />

■'f'^^f^P^iom4UKa события<br />

Load привязывают к обработчику<br />

события Click<br />

кнопки три других, от<br />

д<strong>е</strong>льных обработчика.<br />

у<br />

дальш<strong>е</strong> > 517


оставьт<strong>е</strong> сообщ<strong>е</strong>ни<strong>е</strong>, я вам п<strong>е</strong>р<strong>е</strong>звоню<br />

Обратный Вызов как способ работы с д<strong>е</strong>л<strong>е</strong>гатами<br />

Обратный вызов явля<strong>е</strong>тся <strong>е</strong> щ <strong>е</strong> о д н и м с п о с о б о м р а б о т ы с д <strong>е</strong> л <strong>е</strong> г а т а м и .<br />

Он описыва<strong>е</strong>т ш а б л о н —способ, при котором вы использу<strong>е</strong>т<strong>е</strong> д<strong>е</strong>л<strong>е</strong>гатов<br />

в своих классах таким образом, что один объ<strong>е</strong>кт мож<strong>е</strong>т сообщить другому<br />

«Сообщи мн<strong>е</strong>, когда это случится!»<br />

®<br />

1 Г У ^ р а ^ <strong>е</strong> н и <strong>е</strong> !<br />

Добавим в про<strong>е</strong>кт <strong>е</strong>щ<strong>е</strong> один д<strong>е</strong>л<strong>е</strong>гат<br />

Так как объ<strong>е</strong>кт Bat хранит д<strong>е</strong>л<strong>е</strong>гата в закрытом пол<strong>е</strong>, указывающ<strong>е</strong>м на м<strong>е</strong>тод, новый д<strong>е</strong>л<strong>е</strong>гат долж<strong>е</strong>н<br />

им<strong>е</strong>ть совпадающую сигнатуру:<br />

Обратный вызов обь<strong>е</strong>кта Bat буд<strong>е</strong>т<br />

d e l e g a t e v o i d B a t C a l l b a c k ( B a l l E v e n t A r g s e) ; Указывать на м<strong>е</strong>тод OnBalllnPlayQ<br />

г. -у а о этого Объ<strong>е</strong>кта, поэтому д<strong>е</strong>л<strong>е</strong>гат об-<br />

Созааоать для д<strong>е</strong>л<strong>е</strong>гатов отд<strong>е</strong>льны<strong>е</strong> фай- / у ратного вызова долж<strong>е</strong>н им<strong>е</strong>ть аналы<br />

н<strong>е</strong>обязат<strong>е</strong>льно. Этот д<strong>е</strong>л<strong>е</strong>гат пом <strong>е</strong>- \ логичную сигнатуру — использовать<br />

стит<strong>е</strong> в файл с классом Bat.<br />

V___ в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра BallEventArgs<br />

_ _<br />

Добавим к про<strong>е</strong>кту класс B a t<br />

н<strong>е</strong> возвращать знач<strong>е</strong>ния.<br />

Это оч<strong>е</strong>нь простой класс. Он сод<strong>е</strong>ржит м<strong>е</strong>тод HitTheBall (), запускающийся при каждом удар<strong>е</strong><br />

по мячу, который с помощью д<strong>е</strong>л<strong>е</strong>гата hitBallCallback () вызыва<strong>е</strong>т м<strong>е</strong>тод OnBalllnPlay ()<br />

(п<strong>е</strong>р<strong>е</strong>дава<strong>е</strong>мый в конструктор).<br />

c l a s s B a t {<br />

p r i v a t e B a t C a l l b a c k h i t B a l l C a l l b a c k ;<br />

Д ля пр<strong>е</strong>дот- p u b l i c B a t ( B a t C a l l b a c k c a l l b a c k D e l e g a t e ) {<br />

вращ<strong>е</strong>ния UC- t h i s . h i t B a l l C a l l b a c k = n e w B a t C a l l b a c k ( c a l l b a c k D e l e g a t e ) ;<br />

ключ<strong>е</strong>ния нужно }<br />

p u b l i c v o i d H i t T h e B a l l ( B a l l E v e n t A r g s e)<br />

ссыла<strong>е</strong>тся ли<br />

какой д<strong>е</strong>л<strong>е</strong>гат -----=> i f ( h i t B a l l C a l l b a c k != null)<br />

на знач<strong>е</strong>ни<strong>е</strong> null.<br />

h i t B a l l C a l l b a c k (<strong>е</strong>)<br />

©<br />

}<br />

Мы воспользовались оп<strong>е</strong>ратором =, так как в данном случа<strong>е</strong> нужно, чтобы объ<strong>е</strong>кт bat<br />

получал сообщ<strong>е</strong>ния только от одного объ<strong>е</strong>кта ball, соотв<strong>е</strong>тств<strong>е</strong>нно, данный д<strong>е</strong>л<strong>е</strong>гат<br />

настраива<strong>е</strong>тся вс<strong>е</strong>го один раз. Но ничто н<strong>е</strong> запр<strong>е</strong>ща<strong>е</strong>т написать обратный вызов с<br />

оп<strong>е</strong>ратором +=, который буд<strong>е</strong>т адр<strong>е</strong>сован н<strong>е</strong>скольким м<strong>е</strong>тодам. Основной смысл<br />

обратного вызова — в отсл<strong>е</strong>живании вызывающим объ<strong>е</strong>ктом адр<strong>е</strong>сатов. В случа<strong>е</strong><br />

события, объ<strong>е</strong>кты тр<strong>е</strong>буют опов<strong>е</strong>щ<strong>е</strong>ния, добавляя обработчики, в то вр<strong>е</strong>мя как при<br />

обратном вызов<strong>е</strong> объ<strong>е</strong>кты п<strong>е</strong>р<strong>е</strong>бирают д<strong>е</strong>л<strong>е</strong>гатов и просят об опов<strong>е</strong>щ<strong>е</strong>нии.<br />

Свяж<strong>е</strong>м биту с мячом<br />

Каким<br />

...........<br />

ж<strong>е</strong> образом<br />

гг__________<br />

конструктор объ<strong>е</strong>кта Bat получа<strong>е</strong>т ссылку на м<strong>е</strong>тод OnBalllnPlay () опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нного<br />

мяча? Он вызыва<strong>е</strong>т м<strong>е</strong>тод GetNewBat {) (Получить новую биту) этого объ<strong>е</strong>кта, который мы<br />

с<strong>е</strong>йчас добавим:<br />

p u b l i c Bat G e t N e w B a t О<br />

{<br />

r e t u r n n e w B a t ( n e w B a t C a l l b a c k ( O n B a l l l n P l a y ) )<br />

) /<br />

<strong>е</strong>го 8 mL oS „л» мЗ “ / „ Г “<br />

518 глава 11<br />

М<strong>е</strong>тод QetNewBatÇ) созда<strong>е</strong>т<br />

объ<strong>е</strong>кт Bat и использу<strong>е</strong>т д<strong>е</strong>л<strong>е</strong>гат<br />

BatCallBack для п<strong>е</strong>р<strong>е</strong>дачи<br />

ссылки на этот новый объ<strong>е</strong>кт<br />

собств<strong>е</strong>нному м<strong>е</strong>тоду<br />

OnBallInPiayQ. Им<strong>е</strong>нно этот<br />

м<strong>е</strong>тод обратного вызова буд<strong>е</strong>т<br />

прим<strong>е</strong>н<strong>е</strong>н битой в мом<strong>е</strong>нт удара<br />

по мячу.


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Инкапсулиру<strong>е</strong>м класс B a l l<br />

М<strong>е</strong>тоды, вызывающи<strong>е</strong> события, названия которых начинаются с On... н<strong>е</strong> бывают открытыми.<br />

Попробуйт<strong>е</strong> в форм<strong>е</strong> вызвать событи<strong>е</strong> OnClick () кнопки playBall, вы н<strong>е</strong> смож<strong>е</strong>т<strong>е</strong> это сд<strong>е</strong>лать,<br />

так как оно защищ<strong>е</strong>но (в итог<strong>е</strong> производный класс мож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>крыть <strong>е</strong>го). Сд<strong>е</strong>ла<strong>е</strong>м такой уров<strong>е</strong>нь<br />

доступа и для м<strong>е</strong>тода OnBalllnPlay ():<br />

p r o t e c t e d v o i d O n B a l l l n P l a y ( B a l l E v e n t A r g s e) {<br />

E v e n t H a n d l e r < B a l l E v e n t A r g s > b a l l l n P l a y = B a l l l n P l a y ;<br />

H ( b a l l l n P l a y „ u l l l ^<br />

й<br />

b a l l I n P l a y ( t h i s , e) ,■ N E T<br />

О сталось связать м<strong>е</strong>тод с ф ормой<br />

<strong>е</strong>тся с «Оп».<br />

Форма больш<strong>е</strong> н<strong>е</strong> мож<strong>е</strong>т вызывать м<strong>е</strong>тод OnBalllnPlay () объ<strong>е</strong>кта Ball, как мы<br />

и хот<strong>е</strong>ли. Для этого и был вставл<strong>е</strong>н м<strong>е</strong>тод Ball. GetNewBat {). Т<strong>е</strong>п<strong>е</strong>рь форма<br />

должна попросить у объ<strong>е</strong>кта Ball новую биту для удара по мячу. При этом м<strong>е</strong>тод<br />

OnBalllnPlay () нужно связать с обратным вызовом биты.<br />

p r i v a t e v o i d p l a y B a l l B u t t o n _ C l i c k ( o b j e c t sender, E v e n t A r g s e)<br />

{<br />

Если форма (или симулятор) ко-<br />

Bat b a t = b a l l . G e t N e w B a t 0 ;<br />

~~ ’ ч<strong>е</strong>ил ударить по мячу, <strong>е</strong>й пот р<strong>е</strong>бу<strong>е</strong>тся<br />

новый объ<strong>е</strong>кт Bat. Мяч<br />

B a l l E v e n t A r g s b a l l E v e n t A r g s = n e w B a l l E v e n t A r g s (<br />

гарантиру<strong>е</strong>т связь обратного<br />

( i n t ) t r a j e c t o r y . V a l u e , ( i n t ) d i s t a n c e . V a l u e ) ; вызова с битой. При вызов<strong>е</strong> м <strong>е</strong>т о­<br />

b a t . H i t T h e B a l l ( b a l l E v e n t A r g s ) ;<br />

да HitTheBall() биты он вызыва<strong>е</strong>т<br />

м<strong>е</strong>тод OnBallinPlayO мяча, иници-<br />

}<br />

ируюи^ий событи<strong>е</strong> BalllnPlay.<br />

Запустит<strong>е</strong> программу, она должна работать, как и раньш<strong>е</strong>. Но т<strong>е</strong>п<strong>е</strong>рь в н<strong>е</strong>й н<strong>е</strong>воз- ^<br />

можно появл<strong>е</strong>ни<strong>е</strong> набора мяч<strong>е</strong>й, р<strong>е</strong>агирующих на одно и то ж<strong>е</strong> событи<strong>е</strong>.<br />

Н<strong>е</strong> в<strong>е</strong>рьт<strong>е</strong> нам на слово, посмотрит<strong>е</strong><br />

на работу программы в р<strong>е</strong>жим<strong>е</strong><br />

отладки!<br />

КЛЮЧЕВЫЕ<br />

МОМЕНТЫ<br />

Добавляя к про<strong>е</strong>кту д<strong>е</strong>л<strong>е</strong>гата, вы созда<strong>е</strong>т<strong>е</strong> новый<br />

тип, хранящий ссылки на м<strong>е</strong>тоды.<br />

С помощью д<strong>е</strong>л<strong>е</strong>гатов события опов<strong>е</strong>щают объ<strong>е</strong>кты<br />

о произв<strong>е</strong>д<strong>е</strong>нных д<strong>е</strong>йствиях.<br />

Объ<strong>е</strong>кгы подписываются на события, <strong>е</strong>сли им нужно<br />

р<strong>е</strong>агировать на происходящ<strong>е</strong><strong>е</strong> с другими объ<strong>е</strong>ктами.<br />

EventHandler — это вид д<strong>е</strong>л<strong>е</strong>гата, часто работающий<br />

с событиями.<br />

С одним событи<strong>е</strong>м можно связать н<strong>е</strong>сколько обработчиков.<br />

Им<strong>е</strong>нно поэтому для присво<strong>е</strong>ния обработчика<br />

событию использу<strong>е</strong>тся оп<strong>е</strong>ратор +=.<br />

Вс<strong>е</strong>гда пров<strong>е</strong>ряйт<strong>е</strong> события и д<strong>е</strong>л<strong>е</strong>гаты на рав<strong>е</strong>нство null.<br />

Вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты с пан<strong>е</strong>ли toolbox используют события.<br />

Когда один объ<strong>е</strong>кт п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т другому ссылку на<br />

м<strong>е</strong>тод таким образом, что этот второй объ<strong>е</strong>кт мож<strong>е</strong>т<br />

в<strong>е</strong>рнуть информацию, это называ<strong>е</strong>тся обратным<br />

вызовом.<br />

М<strong>е</strong>тоды могут подписываться на события анонимно,<br />

в то вр<strong>е</strong>мя как обратны<strong>е</strong> вызовы позволяют объ<strong>е</strong>ктам<br />

контролировать д<strong>е</strong>л<strong>е</strong>гаты.<br />

Обратны<strong>е</strong> вызовы и события используют д<strong>е</strong>л<strong>е</strong>гатов<br />

для ссылки и вызова м<strong>е</strong>тодов других объ<strong>е</strong>ктов.<br />

Чтобы понять, как работают д<strong>е</strong>л<strong>е</strong>гаты, используйт<strong>е</strong><br />

отладчик.<br />

дальш<strong>е</strong> > 519


патт<strong>е</strong>рны про<strong>е</strong>ктирования<br />

_<br />

Часто<br />

д а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Bollj=»oCbi<br />

Ч<strong>е</strong>м обратный вызов отлича<strong>е</strong>тся от события?<br />

! События и д<strong>е</strong>л<strong>е</strong>гаты — это часть .NET. Это способ, которым<br />

одни объ<strong>е</strong>кты опов<strong>е</strong>щают других о произв<strong>е</strong>д<strong>е</strong>нных д<strong>е</strong>йствиях. На<br />

событи<strong>е</strong> мож<strong>е</strong>т подписаться произвольно<strong>е</strong> колич<strong>е</strong>ство объ<strong>е</strong>ктов,<br />

при этом издат<strong>е</strong>ль лиш<strong>е</strong>н возможность узнать о них. При запуск<strong>е</strong><br />

события вс<strong>е</strong> подписанны<strong>е</strong> на н<strong>е</strong>го объ<strong>е</strong>кты запускают обработчики.<br />

Обратны<strong>е</strong> вызовы н<strong>е</strong> принадл<strong>е</strong>жат .NET — это вс<strong>е</strong>го лишь названи<strong>е</strong><br />

способа использования д<strong>е</strong>л<strong>е</strong>гатов (или событий, ничто<br />

н<strong>е</strong> м<strong>е</strong>ша<strong>е</strong>т вам создать обратный вызов из закрытого события).<br />

Этим т<strong>е</strong>рмином вс<strong>е</strong>го лишь называются отнош<strong>е</strong>ния м<strong>е</strong>жду двумя<br />

классами, при которых объ<strong>е</strong>кг запрашива<strong>е</strong>т опов<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>. В случа<strong>е</strong><br />

ж<strong>е</strong> событий объ<strong>е</strong>кты тр<strong>е</strong>буют опов<strong>е</strong>щ<strong>е</strong>ний.<br />

То <strong>е</strong>сть обратны<strong>е</strong> вызовы н<strong>е</strong> принадл<strong>е</strong>жат .NET?<br />

Q ; Н<strong>е</strong>т. Обратный вызов — это шаблон, способ использования<br />

сущ<strong>е</strong>ствующих типов, ключ<strong>е</strong>вых слов и инструм<strong>е</strong>нтов. Рассмотрит<strong>е</strong><br />

внимат<strong>е</strong>льно код обратного вызова, написанный для<br />

биты и мяча. Присутствуют ли там н<strong>е</strong>изв<strong>е</strong>стны<strong>е</strong> вам ключ<strong>е</strong>вы<strong>е</strong><br />

слова? Н<strong>е</strong>т! Но при этом там н<strong>е</strong> используются д<strong>е</strong>л<strong>е</strong>гаты, которы<strong>е</strong><br />

являются типом .NET<br />

Получа<strong>е</strong>тся, что обратны<strong>е</strong> вызовы — это вс<strong>е</strong>го лишь<br />

закрыты<strong>е</strong> события?<br />

Q ; Н<strong>е</strong> совс<strong>е</strong>м. Прощ<strong>е</strong> вс<strong>е</strong>го пр<strong>е</strong>дставлять их таким образом,<br />

но закрыты<strong>е</strong> события им<strong>е</strong>ют свою сп<strong>е</strong>цифику. Помнит<strong>е</strong>, что на<br />

самом д<strong>е</strong>л<strong>е</strong> означа<strong>е</strong>т модификатор доступа p r i v a t e ? Доступ<br />

к пом<strong>е</strong>ч<strong>е</strong>нному им чл<strong>е</strong>ну класса им<strong>е</strong>ют только экз<strong>е</strong>мпляры этого<br />

класса. Поэтому, пом<strong>е</strong>тив событи<strong>е</strong> как p r iv a t e , вы запр<strong>е</strong>ща<strong>е</strong>т<strong>е</strong><br />

подписываться на н<strong>е</strong>го из других классов. В то вр<strong>е</strong>мя как<br />

обратны<strong>е</strong> вызовы допускают анонимную подписку.<br />

Но обратный вызов выглядит как событи<strong>е</strong>, н<strong>е</strong> снабж<strong>е</strong>нно<strong>е</strong><br />

ключ<strong>е</strong>вым словом event.<br />

Q l Обратный вызов похож на событи<strong>е</strong>, потому что они оба используют<br />

д<strong>е</strong>л<strong>е</strong>гатов. Это им<strong>е</strong><strong>е</strong>т смысл, так как обратный вызов<br />

явля<strong>е</strong>тся инструм<strong>е</strong>нтом, позволяющим одному объ<strong>е</strong>кту п<strong>е</strong>р<strong>е</strong>дать<br />

другому ссылку на свой м<strong>е</strong>тод.<br />

Но событи<strong>е</strong> — это способ, которым класс опов<strong>е</strong>ща<strong>е</strong>т мир о н<strong>е</strong>ких<br />

д<strong>е</strong>йствиях, в случа<strong>е</strong> ж<strong>е</strong> обратных вызовов опов<strong>е</strong>щ<strong>е</strong>ния отсутствуют.<br />

Они являются закрытыми, и м<strong>е</strong>тод, осущ<strong>е</strong>ствляющий<br />

вызов, отсл<strong>е</strong>жива<strong>е</strong>т, кто им<strong>е</strong>нно вызыва<strong>е</strong>тся.<br />

Шаблонов сущ<strong>е</strong>ству<strong>е</strong>т множ<strong>е</strong>ство. Есть даж<strong>е</strong> отд<strong>е</strong>льная область<br />

программирования — патт<strong>е</strong>рны про<strong>е</strong>ктирования. В<strong>е</strong>дь многи<strong>е</strong><br />

пробл<strong>е</strong>мы, с которыми вы мож<strong>е</strong>т<strong>е</strong> столкнуться, уж<strong>е</strong> р<strong>е</strong>ш<strong>е</strong>ны,<br />

и вам достаточно воспользоваться подходящим патт<strong>е</strong>рном.<br />

520 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

Случай с золотым крабом<br />

Поч<strong>е</strong>му други<strong>е</strong> охотники оп<strong>е</strong>р<strong>е</strong>дили Г<strong>е</strong>нри?<br />

Разгадка в том, как им<strong>е</strong>нно наш охотник искал кам<strong>е</strong>ноломню.<br />

Впроч<strong>е</strong>м, начн<strong>е</strong>м с изуч<strong>е</strong>ния украд<strong>е</strong>нных Г<strong>е</strong>нри диаграмм.<br />

Г<strong>е</strong>нри обнаружил, что при попытк<strong>е</strong> приблизишься к крабу класс<br />

GoldenCrab вызыва<strong>е</strong>т событи<strong>е</strong> RunForCover. Событи<strong>е</strong> включа<strong>е</strong>т<br />

NewLocationArgs, с информаци<strong>е</strong>й о новом м<strong>е</strong>ст<strong>е</strong> укрытия. Так как<br />

конкур<strong>е</strong>нты о событии н<strong>е</strong> знают, Г<strong>е</strong>нри р<strong>е</strong>шил, что поб<strong>е</strong>да буд<strong>е</strong>т за ним.<br />

IJffmuMuHijrtiHaff гоайна<br />

р’асК І^ьш іа<br />

c l a s s G o l d e n C r a b {<br />

p u b l i c d e l e g a t e v o i d E s c a p e ( N e w L o c a t i o n A r g s e ) ;<br />

p u b l i c e v e n t E s c a p e R u n F o r C o v e r ;<br />

p u b l i c v o i d S o m e o n e s N e a r b y () {<br />

}<br />

N e w L o c a t i o n A r g s e = n e w N e w L o c a t i o n A r g s ("Под к а м н<strong>е</strong>м");<br />

R u n F o r C o v e r ( e ) ;<br />

}<br />

c l a s s N e w L o c a t i o n A r g s {<br />

}<br />

p u b l i c N e w L o c a t i o n A r g s ( H i d i n g P l a c e n e w L o c a t i o n ) {<br />

}<br />

t h i s . n e w L o c a t i o n = n e w L o c a t i o n ;<br />

p r i v a t e H i d i n g P l a c e n e w L o c a t i o n ;<br />

p u b l i c H i d i n g P l a c e N e w L o c a t i o n { g e t { r e t u r n n e w L o c a t i o n ; } }<br />

Как ж<strong>е</strong> Г<strong>е</strong>нри воспользовался получ<strong>е</strong>нной информаци<strong>е</strong>й?<br />

Как только к крабц<br />

кт о-т о приближ айся<br />

м<strong>е</strong>тод Вот<strong>е</strong>оп<strong>е</strong>вЫ<strong>е</strong>агЬуО<br />

иницииру<strong>е</strong>т событи<strong>е</strong><br />

^ипРогСоу<strong>е</strong>г, и краб пряч<strong>е</strong>тся<br />

в другом м <strong>е</strong> с т [<br />

Благодаря получ<strong>е</strong>нной ссылк<strong>е</strong> на краба Г<strong>е</strong>нри добавил к сво<strong>е</strong>му конструктору м<strong>е</strong>тод<br />

treasure_RunForCover() в кач<strong>е</strong>ств<strong>е</strong> обработчика события RunForCover. Зат<strong>е</strong>м оп послал за<br />

крабом помощника, зная, что это стан<strong>е</strong>т причиной поб<strong>е</strong>га краба и появл<strong>е</strong>ния события<br />

RunForCover, которо<strong>е</strong> даст м<strong>е</strong>тоду treasure_RunForCover() всю нужную информацию.<br />

cl a s s T r e a s u r e H u n t e r {<br />

p u b l i c T r e a s u r e H u n t e r ( G o l d e n C r a b treasure) {<br />

t r e a s u r e . R u n F o r C o v e r += n e w G o l d e n C r a b .E s c a p e ( t r e a s u r e _ R u n F o r C o v e r ) ;<br />

v o i d t r e a s u r e R u n F o r C o v e r ( N e w L o c a t i o n A r g s e) { Г<strong>е</strong>нри ЗуМал, ч т о добавл<strong>е</strong>ни<strong>е</strong> К KOHC^yK<br />

}<br />

’<br />

v o i d M o v e H e r e ( H i d i n g P l a c e Location) {<br />

бытия RunForCover у краба, — это хит<br />

OH забыл, что вс<strong>е</strong> охотники<br />

и к о д п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> щ <strong>е</strong> н и я в н о в о <strong>е</strong> м <strong>е</strong> с т о зд %кровиш,ами насл<strong>е</strong>дуют от f<br />

того L класса поэтому ^^o fd Jo 6 a 6 u<br />

в ц<strong>е</strong>почку и их обработчики событии<br />

Вот поч<strong>е</strong>му Г<strong>е</strong>нри пот<strong>е</strong>рп<strong>е</strong>л пораж<strong>е</strong>ни<strong>е</strong>. Добавив обработчик событий конструктору Тг<strong>е</strong>азиг<strong>е</strong>НипЪ<strong>е</strong>г,<br />

он н<strong>е</strong>чаянно сд<strong>е</strong>лал это для вс<strong>е</strong>х охотников] Обработчики событий вс<strong>е</strong>х охотников оказались связанными<br />

с одним и т<strong>е</strong>м ж<strong>е</strong> событи<strong>е</strong>м RunForCover. и сообщ<strong>е</strong>ни<strong>е</strong> о п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>нии краба в ново<strong>е</strong> укрыти<strong>е</strong> пришло<br />

вс<strong>е</strong>м. Можно было бы об<strong>е</strong>рнуть д<strong>е</strong>ла в свою пользу, <strong>е</strong>сли бы Г<strong>е</strong>нри получил сообщ<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>рвым. Но Г<strong>е</strong>нри<br />

н<strong>е</strong> мог узнать, в каком порядк<strong>е</strong> проводится опов<strong>е</strong>щ<strong>е</strong>ни<strong>е</strong>. В итог<strong>е</strong> вс<strong>е</strong> подписавши<strong>е</strong>ся до н<strong>е</strong>го получили<br />

новость о м<strong>е</strong>стополож<strong>е</strong>нии краба раньш<strong>е</strong>.<br />

дальш<strong>е</strong> > 521


уб<strong>е</strong>й моль!<br />

ОЗЬМИ в руку карандаш<br />

Заполнит<strong>е</strong> проб<strong>е</strong>лы, чтобы игра «Уб<strong>е</strong>й моль» заработала. Вам нуж<strong>е</strong>н код, подд<strong>е</strong>рживающий<br />

обратны<strong>е</strong> вызовы. Когда программа буд<strong>е</strong>т готова, пров<strong>е</strong>рьт<strong>е</strong> <strong>е</strong><strong>е</strong> работу в ИСР!<br />

p u b l i c p a r t i a l class Forml : F o r m {<br />

M o l e mole;<br />

R a n d o m r a n d o m = n e w R a n d o m {);<br />

p u b l i c F o r m l 0 {<br />

I n i t i a l i z e C o m p o n e n t ();<br />

}<br />

m o l e = n e w M o l e ( r a n d o m , n e w M o l e . ________<br />

t i m e r l .In t e r v a l = r a n d o m . N e x t (500, 1000)<br />

t i m e r l . S t a r t 0 ;<br />

p r i v a t e v o i d t i m e r l _ T i c k ( o b j e c t sender, E v e n t A r g s e)<br />

t i m e r l . S t o p 0 ;<br />

T o g g l e M o l e () ;<br />

J ) ;<br />

форма п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т д<strong>е</strong>л<strong>е</strong>гата<br />

указыван>и1,ий на м<strong>е</strong>тод<br />

обратного вызова в конструктор<strong>е</strong><br />

моли.<br />

Э т о т<br />

м<strong>е</strong>тод<br />

управля<strong>е</strong>т<br />

появл<strong>е</strong>ни<strong>е</strong>м<br />

и исч<strong>е</strong>знов<strong>е</strong>ни<strong>е</strong>м<br />

моли<br />

по р<strong>е</strong>зуль-j<br />

татам<br />

/ " " ^ p r i v a t e v o i d T o g g l e M o l e 0 {<br />

if ( m o l e . H i d d e n == true)<br />

m o l e .S h o w ();<br />

else<br />

m o l e . H i d e A g a i n O ;<br />

t i m e r l .I n t e r v a l = r a n d o m . N e x t (500,<br />

t i m e r l .S t a r t ();<br />

p r i v a t e v o i d M o l e C a l l B a c k ( i n t m o l e N u m b e r , b o o l show)<br />

работы if (moleNumber < 0) {<br />

тайм<strong>е</strong>ра. t i m e r l .s t o p () ;<br />

return;<br />

6 ^ Ьлок switch<br />

^арантиру -<br />

<strong>е</strong>т изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong><br />

т<strong>е</strong>кста<br />

и цв<strong>е</strong>та у<br />

^^равильной<br />

Кнопки.<br />

}<br />

B u t t o n<br />

s w i t c h<br />

button;<br />

(moleNumber)<br />

b u t t o n =<br />

b u t t o n =<br />

b u t t o n =<br />

b u t t o n =<br />

{<br />

b u t t o n l ;<br />

b u t t o n 2 ;<br />

b u t t o n s ;<br />

b u t t o n 4 ;<br />

case<br />

b r e a k<br />

case<br />

b r e a k<br />

case<br />

b r e a k<br />

case<br />

b r e a k<br />

default: b u t t o n = b u t t o n 5 ; break;<br />

{<br />

1000)<br />

(show == true)<br />

b u t t o n . T e x t = "HIT ME!"; ,<br />

button. B a c k C o l o r = Color. Red;<br />

'*<br />

} e l s e {<br />

b u t t o n . T e x t = "";<br />

IB!<br />

b u t t o n . B a c k C o l o r = S y s t e m C o l o r s .C o n t r o l ;<br />

t i m e r l .I n t e r v a l = r a n d o m . N e x t (500, 1000)<br />

t i m e r l . S t a r t ();<br />

}<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t<br />

m o l e .S m a c k e d (0)<br />

}<br />

{<br />

F o rm lx s [Design]<br />

Щ W h a c k -a -m o le<br />

sender, E v e n t A r g s <strong>е</strong>) {<br />

Добавьт<strong>е</strong> эти обработчики событий<br />

обычным способом, то<br />

<strong>е</strong>сть двойным щ<strong>е</strong>лчком на кнопках<br />

в конструктор<strong>е</strong> формы.<br />

ю т СО­<br />

М Ы поговорим<br />

-г X<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт<br />

imeri ' Timer из окна toolbox<br />

л и дважды щ<strong>е</strong>лкнит<strong>е</strong><br />

^ на н<strong>е</strong>м.<br />

Добавьт<strong>е</strong> пять обработчиков<br />

событий для кнопок.<br />

buttonZ_click() вызыва<strong>е</strong>т<br />

mole.Smacked(l) и заставля<strong>е</strong>т<br />

button3 вызвать<br />

mole.Smacked(Z)>что за-<br />

^ ставля<strong>е</strong>т button4 вызвать<br />

mole.Smacked(3) и buttons<br />

вызвать mole.Smacked(4).<br />

522 глава 11


события и д<strong>е</strong>л<strong>е</strong>гаты<br />

u s i n g S y s t e m . W i n d o w s . F o r m s ;<br />

class M o l e {<br />

p u b l i c<br />

v o i d P o p U p ( i n t hole, b o o l show)<br />

p r i v a t e _____________ p o p U p C a l l b a c k ;<br />

p r i v a t e b o o l hidden;<br />

p u b l i c b o o l H i d d e n { g e t { r e t u r n hidden; } }<br />

p r i v a t e int t i m e s H i t = 0;<br />

p r i v a t e int t i m e s S h o w n = 0;<br />

p r i v a t e int h o l e = 0;<br />

R a n d o m random;<br />

p u b l i c M o l e ( R a n d o m random, P o p U p p o p U p C a l l b a c k ) {<br />

if ( p o p U p C a l l b a c k == null)<br />

t h r o w n e w A r g u m e n t E x c e p t i o n (" p o p U p C a l l b a c k c a n ' t b e null")<br />

t h i s . r a n d o m = random;<br />

}<br />

t h i s .___________<br />

h i d d e n = true;<br />

p u b l i c v o i d S h o w O<br />

t i m e s S h o w n + + ;<br />

h i d d e n = false;<br />

h o l e = r a n d o m .N e x t (5)<br />

{<br />

Впиш им<strong>е</strong> д<strong>е</strong>л<strong>е</strong>гаш, и пол<strong>е</strong>, в к о ­<br />

т ором он буд<strong>е</strong>т хранит ься,<br />

,ода п арам <strong>е</strong>т ра должны находиться<br />

в в<strong>е</strong>рхн<strong>е</strong>й части класса<br />

Mole.<br />

Зд<strong>е</strong>сь мы пров<strong>е</strong>ря<strong>е</strong>м н <strong>е</strong>­<br />

рав<strong>е</strong>нст во обратного<br />

вызова null, в п рот и в­<br />

ном случа<strong>е</strong> объ<strong>е</strong>кт Mole<br />

/в ы з о в <strong>е</strong> т исключ<strong>е</strong>ни<strong>е</strong><br />

у / A rgum entE xception.<br />

При создании нового объ<strong>е</strong>кт<br />

а Mole ф орм а п <strong>е</strong>р <strong>е</strong>­<br />

да<strong>е</strong>т ссылки на <strong>е</strong>го м <strong>е</strong>т од<br />

обрат ного вызова. Посмот<br />

рит <strong>е</strong>, как им<strong>е</strong>нно вы ­<br />

зыва<strong>е</strong>т ся конст рукт ор<br />

ф орм ы , и заполнит <strong>е</strong> эт о<br />

пол<strong>е</strong>.<br />

p u b l i c v o i d H i d e A g a i n O<br />

h i d d e n = true;<br />

C h e c k F o r G a m e O v e r ()<br />

(hole, true)<br />

(hole. f a l s e ) ;<br />

p u b l i c v o i d S m a c k e d ( i n t h o l e S m a c k e d )<br />

if ( h o l e S m a c k e d == hole) {<br />

t i m e s H i t + + ;<br />

h i d d e n = true;<br />

C h e c k F o r G a m e O v e r ();<br />

p r i v a t e<br />

if<br />

{<br />

(hole, false)<br />

v o i d C h e c k F o r G a m e O v e r (<br />

(timesShown >=10) {<br />

p o p U p C a l l b a c k (-1, false);<br />

M e s s a g e B o x . S h o w ( " Y o u s c o r e d<br />

A p p l i c a t i o n . E x i t O ;<br />

{<br />

т <strong>е</strong>кст «HIT ME!»<br />

^ ^


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

возьми в руку карандаш<br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как долж<strong>е</strong>н выгляд<strong>е</strong>ть код программы «Уб<strong>е</strong>й моль».<br />

p u b l i c p a r t i a l class Forml : F o r m {<br />

}<br />

p r i v a t e v o i d F o r m l _ L o a d ( o b j e c t sender, E v e n t A r g s e) {<br />

}<br />

c l a s s M o l e {<br />

m o l e = n e w M o l e ( r a n d o m , n e w Mole,<br />

Popup<br />

t i m e r l .I n t e r v a l = r a n d o m . N e x t (500, 1000);<br />

t i m e r l .S t a r t ();<br />

p u b l i c _<br />

p r i v a t e<br />

Popup<br />

p o p U p C a l l b a c k ;<br />

v o i d P o p U p d n t hole, b o o l show)<br />

p u b l i c M o l e ( R a n d o m random, P o p U p p o p U p C a l l b a c k ) {<br />

t h i s . r a n d o m = random;<br />

}<br />

t h i s .___________<br />

h i d d e n = true;<br />

popUpCallback<br />

p u b l i c v o i d S h o w O {<br />

t i m e s S h o w n + + ;<br />

h i d d e n = false;<br />

}<br />

h o l e = r a n d o m .N e x t (5);<br />

popUpCallback<br />

p u b l i c v o i d H i d e A g a i n O {<br />

h i d d e n = true;<br />

}<br />

popUpCallback<br />

C h e c k F o r G a m e O v e r ();<br />

(hole, true)<br />

(hole, false)<br />

p u b l i c v o i d S m a c k e d ( i n t h o l e S m a c k e d ) {<br />

if ( h o l e S m a c k e d == hole) {<br />

t i m e s H i t + + ;<br />

h i d d e n = true;<br />

C h e c k F o r G a m e O v e r ();<br />

popUpCallback<br />

(hole, false)<br />

popUpCallback<br />

MoleCallBack<br />

Форма п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т ссылку на<br />

м<strong>е</strong>тод MokCallBackQ о Ь <strong>е</strong>кт у<br />

Mole, что позволя<strong>е</strong>т мол« вызывать<br />

данный м<strong>е</strong>тод.<br />

М О Л & опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т свой<br />

д<strong>е</strong>л<strong>е</strong>гат и и сп о льзу<strong>е</strong>т <strong>е</strong>го<br />

для задания закры т ого<br />

поля, в кот ором буд<strong>е</strong>т<br />

хранит ся ссылка на м<strong>е</strong>-^<br />

mod в форм<strong>е</strong>, м<strong>е</strong>няющий<br />

цв<strong>е</strong>т кнопок.<br />

Создав новый экз<strong>е</strong>мпляр объ<strong>е</strong>кта Mole,<br />

\ форма п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т конструктору в ка-<br />

\ ч<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра ссылку на м<strong>е</strong>тод<br />

MoleCallBackQ. Эта строка в конструктор<strong>е</strong><br />

копиру<strong>е</strong>т ссылку в пол<strong>е</strong><br />

popUpCal back. М<strong>е</strong>тоды конструктора<br />

при помощи этого поля м о ­<br />

гут вызывать м<strong>е</strong>тод MoleCallBackQ<br />

в форм<strong>е</strong>.<br />

V — Когда м о ль показы ва<strong>е</strong>т ся, пря<br />

ч <strong>е</strong> т с я или оказы ва<strong>е</strong>т ся у д и -<br />

т Т 1 объ<strong>е</strong>кт ^о1<strong>е</strong> и % о л ^<br />

д<strong>е</strong>л<strong>е</strong>гат рорирСаНЬаск °<br />

зова м <strong>е</strong>т ода, м <strong>е</strong>няю щ <strong>е</strong>го цб<strong>е</strong><br />

и т <strong>е</strong> к с т к н о п о к ф о р м ы .<br />

524 глава 11


12 обзор и пр<strong>е</strong>ДБа]=пхіхі<strong>е</strong>ЛьНьіЄ р<strong>е</strong>ЗуЛьніазпьі<br />

^ Знания, сила и постро<strong>е</strong>ни<strong>е</strong><br />

классных прилож<strong>е</strong>ний<br />

Знания нужно прим<strong>е</strong>нять на практик<strong>е</strong>.<br />

Пока вы н<strong>е</strong> начн<strong>е</strong>т<strong>е</strong> писать работаю щ ий код, вряд ли можно бы ть ув<strong>е</strong>р<strong>е</strong>нным,<br />

что вы на самом д<strong>е</strong>л<strong>е</strong> усвоили сложны<strong>е</strong> понятия С#. С <strong>е</strong>йчас мы займ<strong>е</strong>мся<br />

прим<strong>е</strong>н<strong>е</strong>ни<strong>е</strong>м на практик<strong>е</strong> получ<strong>е</strong>нных ран<strong>е</strong><strong>е</strong> знаний. Кром<strong>е</strong> того,<br />

вы найд<strong>е</strong>т<strong>е</strong> пр<strong>е</strong>дварит<strong>е</strong>льны <strong>е</strong> св<strong>е</strong>д<strong>е</strong>ния о понятиях, которы<strong>е</strong> будут рассматриваться<br />

в сл<strong>е</strong>дую щ их главах. М ы начн<strong>е</strong>м постро<strong>е</strong>ни<strong>е</strong> д<strong>е</strong>йствит<strong>е</strong>льно<br />

сложного прилож<strong>е</strong>ния, чтобы закр<strong>е</strong>пить ваш и навыки.


так много информации<br />

Вы прошли долгий путь<br />

Много вр<strong>е</strong>м<strong>е</strong>ни прошло с мом<strong>е</strong>нта, когда вы взялись за свой п<strong>е</strong>рвый код для<br />

объ<strong>е</strong>ктвильской фирмы по производству бумаги. Ниж<strong>е</strong> п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>но много<strong>е</strong><br />

из того, ч<strong>е</strong>му вы научились за н<strong>е</strong>сколько сот<strong>е</strong>н страниц.<br />

Вы создавали формы, пользовались<br />

ср<strong>е</strong>дствами .NET Framework и даж<strong>е</strong><br />

обм<strong>е</strong>нивались данными с базой.<br />

.NET Fram ew ork<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>кт ы,<br />

4<br />

ры... вс<strong>е</strong> эти<br />

повс<strong>е</strong>дн<strong>е</strong>вную<br />

Party<br />

NumberOPeople<br />

CosfôfDecorations<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

б а за данны х<br />

Вы научились работать<br />

даж<strong>е</strong> с такими сложными<br />

типами данных как<br />

массивы.<br />

SetLocationO<br />

SetDestinationO<br />

ModifyRouteToAvoidO<br />

ModifyRouteTolncludeO<br />

GetRouteO<br />

GetTimeToDestinationO<br />

TotalDistanceO<br />

DinnerParty<br />

NumlwrOfPeopte<br />

CostODecorations<br />

CostOffieveragesPerPerson<br />

HealthyOption<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

SetHealthyOptionO<br />

BirthdayParty<br />

NumljerOfPeople<br />

CostODecorations<br />

CakeSize<br />

CakeWriting<br />

CalculateCostOfDecorationsO<br />

CalculateCostO<br />

7 п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных т ипа in t<br />

eimii<br />

в «<br />

Вы бор<strong>е</strong>т<strong>е</strong>сь с п р о - '" ' ' ^ ^<br />

ол<strong>е</strong>мами при по МОщи,<br />

отладки и и Т<br />

хлюч<strong>е</strong>ний.<br />

p r iv a t e v o id ra n d o M E x c u s e _ C iic k (o b je c t s e n d e r, EventArgs. в )<br />

{<br />

'в п


обзор и пр<strong>е</strong>дварит<strong>е</strong>льны<strong>е</strong> р<strong>е</strong>зультаты<br />

Вы стали пч<strong>е</strong>лоВодом<br />

Помнит<strong>е</strong>, как в глав<strong>е</strong> 6 вы мод<strong>е</strong>лировали работу улья?<br />

Разны<strong>е</strong> виды пч<strong>е</strong>л выполняли<br />

разную работу...<br />

Но мо)кно сд<strong>е</strong>лать ßce намного лучш<strong>е</strong>...<br />

Вы многому научились за это вр<strong>е</strong>мя. Поэтому начн<strong>е</strong>м сначала<br />

и построим анимированный симулятор улья. Создадим<br />

пользоват<strong>е</strong>льский инт<strong>е</strong>рф<strong>е</strong>йс, показывающий ул<strong>е</strong>й и поля,<br />

над которыми л<strong>е</strong>тают пч<strong>е</strong>лы, а такж<strong>е</strong> статистику произв<strong>е</strong>д<strong>е</strong>нных<br />

пч<strong>е</strong>лами д<strong>е</strong>йствий.<br />

Окно HiVe<br />

Ї Ї Ї с З т <strong>е</strong> » в ад«-<br />

iß Beehive Simylator<br />

Pause simulation Reset ^<br />

Окно статистики позволя<strong>е</strong>т<br />

отсл<strong>е</strong>живать<br />

работу симулятора.<br />

# Bees 6<br />

Sflowera 11<br />

Totrf honey h the twe 1.200<br />

TtAdnetJarhfte field 34.^<br />

Frames fun 383<br />

Frane rsts 16 ^S2.5msj<br />

kSe;1bee<br />

FlywigToFtow«-: 2 bees<br />

GMheringNectar: 1bee<br />

R^iBrtngToKve: 2 bees<br />

Можно даж<strong>е</strong> наблюдать<br />

за работой<br />

пч<strong>е</strong>л d пол<strong>е</strong>.<br />

дальш<strong>е</strong> > 527


н<strong>е</strong> слишком сложно... да?<br />

Архит<strong>е</strong>ктура симулятора улья<br />

Вот как выглядит ул<strong>е</strong>й изнутри. Н<strong>е</strong>смотря на н<strong>е</strong>обходимость контролировать<br />

множ<strong>е</strong>ство пч<strong>е</strong>л, общая мод<strong>е</strong>ль довольно проста.<br />

основно<strong>е</strong> окно,<br />

отображающ<strong>е</strong><strong>е</strong><br />

статистику<br />

и сообщ<strong>е</strong>ния.<br />

Обь<strong>е</strong>км \AJorid сл<strong>е</strong>дит за<br />

работой симулятора: за<br />

оош,им состояни<strong>е</strong>м улья<br />

Sysfem.V'fi'<br />

fire эл<strong>е</strong>м<strong>е</strong>нты архит<strong>е</strong>ктуры<br />

лТпТают пч<strong>е</strong>линый мир,<br />

инт<strong>е</strong>рф<strong>е</strong>.йс.<br />

Обь<strong>е</strong>кт World<br />

пр<strong>е</strong>дставля<strong>е</strong>т<br />

общую картину.<br />

Для каждого<br />

цв<strong>е</strong>тка пот р<strong>е</strong>бу<strong>е</strong>тся<br />

обь<strong>е</strong>кт<br />

Flower.<br />

'разум<strong>е</strong><strong>е</strong>тся, мы<br />

н<strong>е</strong> обойд<strong>е</strong>мся б<strong>е</strong>з<br />

класса В<strong>е</strong><strong>е</strong>.<br />

528 глава 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> з у л ь т а т ы<br />

Постро<strong>е</strong>ни<strong>е</strong> симулятора улья<br />

М ы пока н<strong>е</strong> создавали про<strong>е</strong>ктов такого уровня слож ности, поэтом у на подготовит<strong>е</strong>льную<br />

работу прид<strong>е</strong>тся затр ати ть пару глав. Вам п р<strong>е</strong>дстоит научиться<br />

работать с тайм <strong>е</strong>рам и , освоить встро<strong>е</strong>н н ы й язы к зап росов L IN Q<br />

и п ри <strong>е</strong>м ы работы с граф и кой.<br />

Вот ч<strong>е</strong>м вам пр<strong>е</strong>дстои т заняться в этой глав<strong>е</strong>;<br />

О С о з д а т ь к л а с с F lo w e r, в ко т о р о м ц в <strong>е</strong>ты р а с п у с к а ю т с я ,<br />

д а ю т н <strong>е</strong> к т а р , в я н у т и у м и р а ю т.<br />

© С о з д а т ь к л а с с В <strong>е</strong> <strong>е</strong> с н а б о р о м р а з л и ч н ы х с о с т о я н и й<br />

(с б о р н <strong>е</strong> к т а р а , в о з в р а щ <strong>е</strong> н и <strong>е</strong> в у л <strong>е</strong> й ) и н а б о р о м з а д а н и й<br />

в з а в и с и м о с т и о т с о с то я н и я .<br />

О С о з д а т ь к л а с с H iv e , с о д <strong>е</strong> р ж а щ и й в хо д , в ы х о д , и н к у б а ­<br />

то р п ч <strong>е</strong> л и ф а б р и к у д л я п <strong>е</strong> р <strong>е</strong> р а б о т к и с о б р а н н о го н <strong>е</strong> к т а ­<br />

р а в м <strong>е</strong> д .<br />

О С о з д а т ь к л а с с W o rld , у п р а в л я ю щ и й у л ь <strong>е</strong> м , ц в <strong>е</strong> та м и<br />

и п ч <strong>е</strong> л а м и в к а ж д ы й м о м <strong>е</strong> н т в р <strong>е</strong> м <strong>е</strong> н и .<br />

О П о с т р о и т ь ф о р м у д л я с о б о р а с т а т и с т и к и о с о с то я н и и<br />

к л а с с о в и у п р а в л <strong>е</strong> н и я у л ь <strong>е</strong> м .<br />

д а л ь ш <strong>е</strong> ► 529


п о н ю х а <strong>е</strong> м ц в <strong>е</strong> т ы<br />

'^пражн<strong>е</strong>ни<strong>е</strong><br />

р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong><br />

П <strong>е</strong> р <strong>е</strong> й д <strong>е</strong> м к н а п и с а н и ю к о д а . Н а ч н <strong>е</strong> м с к л а с с а F lo w e r. О н с о ­<br />

д <strong>е</strong> р ж и т и н ф о р м а ц и ю о п о л о ж <strong>е</strong> н и и ц в <strong>е</strong> т к а , в о з р а с т <strong>е</strong> и п р о д о л ж и ­<br />

т <strong>е</strong> л ь н о с т и ж и з н и . Н у ж н о с д <strong>е</strong> л а т ь т а к , ч то б ы ц в <strong>е</strong> ты с о в р <strong>е</strong> м <strong>е</strong> н <strong>е</strong> м<br />

с т а р <strong>е</strong> л и и у м и р а л и . Э т и м вы с <strong>е</strong> й ч а с и з а й м <strong>е</strong> т <strong>е</strong> с ь . ^ с к <strong>е</strong> л <strong>е</strong> т о м класса<br />

Основа класса Flower<br />

oSv^eACH f<br />

^ока н<strong>е</strong> н.ап\лсана р<strong>е</strong>а<br />

а .wvca<br />

Н а основ<strong>е</strong> диаграм м ы класса F lo w e r нап иш и т<strong>е</strong> <strong>е</strong>го ск<strong>е</strong>л<strong>е</strong>т. L o c a t i o n (М <strong>е</strong>стополож <strong>е</strong>ни<strong>е</strong>),<br />

А д<strong>е</strong> (В озраст), A l i v e (Ж и вой), N e c t a r (Н <strong>е</strong>ктар) и N e c t a r H a r v e s t e d (С обран ны й н<strong>е</strong>ктар) -<br />

автоматич<strong>е</strong>ски<strong>е</strong> свойства. П осл<strong>е</strong>дн <strong>е</strong><strong>е</strong> свойство п <strong>е</strong>р<strong>е</strong>записы ва<strong>е</strong>м о, в то вр<strong>е</strong>м я как п <strong>е</strong>рвы <strong>е</strong> ч<strong>е</strong>ты<br />

р <strong>е</strong> пр<strong>е</strong>дназн ач<strong>е</strong>н ы только для чт<strong>е</strong>ния.<br />

Вс<strong>е</strong> эти свойства,<br />

кром<strong>е</strong> N ectarH arvested,<br />

^р&дназнач<strong>е</strong>иы только<br />

для чт<strong>е</strong>ния.<br />

^<br />

Эт о пол<strong>е</strong> использу<strong>е</strong>тся<br />

только внутри класса,<br />

поэт ом у <strong>е</strong>го нужно<br />

сд<strong>е</strong>лать закрытым.<br />

F lo w e r<br />

Location; Point<br />

Age: int<br />

Alive: bool<br />

Nectar: double<br />

NectarHarvested: double<br />

lifespan: int<br />

HarvestNectarQ: double<br />

Go()<br />

П осл<strong>е</strong> дво<strong>е</strong>т очия<br />

аказан<br />

б <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о м . . .<br />

7 -м ли т ип возвраш,а<strong>е</strong>мого<br />

Ь м<strong>е</strong>т одом знач<strong>е</strong>ния.<br />

О<br />

Н<strong>е</strong>обходимы <strong>е</strong> константы<br />

Д о б а в и м в кл а сс F l o w e r ш <strong>е</strong> с т ь к о н с т а н т :<br />

Конст ант ы обычно<br />

н<strong>е</strong> показываются на<br />

диаграмм<strong>е</strong> классоО.<br />

♦ Lif eSpanMin - м и н и м а л ь н а я п р о д о л ж и т <strong>е</strong> л ь н о с т ь ж и з н и ц в <strong>е</strong> т к а .<br />

♦ Lif eSpanMax м а кс и м а л ь н а я п р о д о л ж и т <strong>е</strong> л ь н о с т ь ж и з н и ц в <strong>е</strong> т к а .<br />

♦ InitialNectar — с к о л ь к о н <strong>е</strong> к т а р а и з н а ч а л ь н о с о д <strong>е</strong> р ж и т ц в <strong>е</strong> т о к .<br />

♦ MaxNectar - м а кс и м а л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о н <strong>е</strong> к т а р а , к о т о р о <strong>е</strong> м о ж н о с о б р а ть с ц в <strong>е</strong> т к а .<br />

♦ NectarAddedPerTurn - к о л и ч <strong>е</strong> с т в о н <strong>е</strong> к т а р а , д о б ав л я <strong>е</strong> м о <strong>е</strong> п о м <strong>е</strong> р <strong>е</strong> р о с т а ц в <strong>е</strong> т к а .<br />

♦ NectarGatheredPerTurn - к а к м н о г о н <strong>е</strong> к т а р а уд а <strong>е</strong>тся с о б р а ть за о д и н ц и к л .<br />

о с н о в у з н а ч <strong>е</strong> н и <strong>е</strong> к а ж д о й к о н с т а н т ы , в ы б р а ть для н <strong>е</strong> <strong>е</strong> т и п . Ц в <strong>е</strong> т ы ж и в у т о т<br />

15 ООО д о 3 0 ООО ц и к л о в , и в н а ч а л ь н ы й м о м <strong>е</strong> н т и м <strong>е</strong> ю т 1 .5 <strong>е</strong> д и н и ц ы н <strong>е</strong> к т а р а . К о л и ч <strong>е</strong> с т в о<br />

н <strong>е</strong> к т а р а м о ж <strong>е</strong> т д о х о д и т ь д о 5 <strong>е</strong> д и н и ц . З а о д и н ц и к л п р и б а в л я <strong>е</strong> т с я 0 .0 1 <strong>е</strong> д и н и ц ы н <strong>е</strong> к т а р а<br />

и 0 .3 <strong>е</strong> д и н и ц ы м о ж <strong>е</strong> т б ы ть с о б р а н о . 4 ^ ’<br />

Анимированны<strong>е</strong> симуляторы созда-<br />

^ ^ Р м ш ы «ка др»,<br />

Х а<br />

в наил<strong>е</strong>м случа<strong>е</strong><br />

являются взаимозам<strong>е</strong>ня<strong>е</strong>мыми<br />

530 г л а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

В в<strong>е</strong>рхн<strong>е</strong>й части класса, использую щ <strong>е</strong>го тип Point, должна бы ть<br />

строка using System.Drawing;.<br />

О<br />

П остро<strong>е</strong>ни<strong>е</strong> конструктора<br />

К о н с т р у к т о р д о л ж <strong>е</strong> н п <strong>е</strong> р <strong>е</strong> д а в а ть с т р у к т у р у Point, за д а ю щ у ю п о л о ж <strong>е</strong> н и <strong>е</strong> ц в <strong>е</strong> т ­<br />

к а , и э к з <strong>е</strong> м п л я р кл а с с а Random. Н у ж н о у ка з а ть , ч т о в о з р а с т ц в <strong>е</strong> т к а р а в <strong>е</strong> н О, ч т о<br />

о н ж и в о й , а т а к ж <strong>е</strong> п р и с в о и т ь <strong>е</strong>м у н а ч а л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о н <strong>е</strong> к т а р а . Н а к о н <strong>е</strong> ц , т р <strong>е</strong> ­<br />

б у <strong>е</strong>тся р а с с ч и т а т ь п р о д о л ж и т <strong>е</strong> л ь н о с т ь ж и з н и ц в <strong>е</strong> т к а . В о т с т р о ч к а , к о т о р а я вам<br />

п о м о ж <strong>е</strong> т :<br />

lifeSpan = random.Next (LifeSpanMin, LifeSpanMax -н 1);<br />

Х Г и Г » Г <strong>е</strong> р <strong>е</strong> Э .6 » .« «<br />

конст рукт ору Flower.<br />

М <strong>е</strong>тод HarvestNectar О<br />

П р и к а ж д о м в ы зо в<strong>е</strong> э т о г о м <strong>е</strong> то д а п р о в <strong>е</strong> р я <strong>е</strong> т с я , д о с т и гл о л и к о л и ч <strong>е</strong> с т в о с о б р а н ­<br />

н о г о н <strong>е</strong> к т а р а м а кс и м у м а , к о т о р ы й м о гу т д ать ц в <strong>е</strong> ты . В э т о м случа<strong>е</strong> м <strong>е</strong> т о д возв<br />

р а щ а <strong>е</strong> т 0. В п р о т и в н о м случа<strong>е</strong> в о з в р а щ а <strong>е</strong> т с я к о л и ч <strong>е</strong> с т в о с о б р а н н о го н <strong>е</strong> к т а р а ,<br />

к о т о р о <strong>е</strong> д о б а в л я <strong>е</strong> т с я к п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й N e c t a r H a r v e s t e d , х р а н я щ <strong>е</strong> й и н ф о р м а ­<br />

ц и ю о б о б щ <strong>е</strong> м с б о р <strong>е</strong> с к а ж д о г о ц в <strong>е</strong> т к а . ^<br />

Подсказка: В эт ом м<strong>е</strong>т од<strong>е</strong> использиются<br />

только конст ант ы N ecta rG atheredP erTurn<br />

N ecta r и N ectarHarvested.<br />

О<br />

М <strong>е</strong>тод Go {)<br />

К а ж д ы й в ы зо в э т о г о м <strong>е</strong> т о д а с о о т в <strong>е</strong> т с т в у <strong>е</strong> т п р о ж и в а н и ю ц в <strong>е</strong> т к о м о д н о го ц и к л а ,<br />

з н а ч и т , д о л ж <strong>е</strong> н о б н о в л я ть с я и <strong>е</strong> го в о зр а с т. Н у ж н о п р о в <strong>е</strong> р я т ь , н <strong>е</strong> д о с т и гл а л и<br />

э т а п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н а я з а д а н н о го для ц в <strong>е</strong> т к а в р <strong>е</strong> м <strong>е</strong> н и ж и з н и . В случа<strong>е</strong> п о л о ж и т <strong>е</strong> л ь н о ­<br />

г о р <strong>е</strong> зу л ь та та ц в <strong>е</strong> т о к у м и р а <strong>е</strong> т.<br />

К ж и в ы м ц в <strong>е</strong> т а м н у ж н о д о б а в и ть к о л и ч <strong>е</strong> с т в о п р о и з в <strong>е</strong> д <strong>е</strong> н н о г о за ц и к л н <strong>е</strong> к т а р а .<br />

П р о в <strong>е</strong> р я й т <strong>е</strong> , н <strong>е</strong> п р <strong>е</strong> в ы ш а <strong>е</strong> т л и о н о м а кс и м а л ь н о в о з м о ж н о <strong>е</strong> з н а ч <strong>е</strong> н и <strong>е</strong> .<br />

Р<strong>е</strong>зульт ат ом буд<strong>е</strong>т анимация с м а ­<br />

л<strong>е</strong>нькими л<strong>е</strong>т ающ ими ф игуркам и пч<strong>е</strong>л.<br />

М<strong>е</strong>т од


к у д а п р о п а л и ц в <strong>е</strong> т ы ?<br />

н<strong>е</strong>нк<strong>е</strong><br />

)^<strong>е</strong>ш <strong>е</strong>нк<strong>е</strong><br />

В о т к а к в ы гл я д и т к л а с с Flower д л я с и м у л я т о р а у л ь я .<br />

class Flower {<br />

private const int LifeSpanMin = 15000;<br />

private const int LifeSpanMax = 30000;<br />

private const double InitialNectar = 1.5;<br />

private const double MaxNectar = 5.0;<br />

private const double NectarAddedPerTurn = 0.01;<br />

private const double NectarGatheredPerTurn = 0.3;<br />

свойст ва {public Point Location { get; private set; }<br />

L o c a t i o n . ,<br />

public int Age { get; private set; }<br />

Aüve U Nectar<br />

к\р<strong>е</strong>Эназнйч<strong>е</strong>н<strong>е</strong>>| public bool Alive { get; private set; }<br />

т о л ь к о Эля<br />

^ public -----------------------^ double Nectar { get; private -t. V d u e Oset; C U ; ^}<br />

чт<strong>е</strong>н и я.<br />

public Г М 1 T -i ^ double /-ЧЧ ЛV-4 1 Л NectarHarvested ^ 4- _ ^ T T _ _________ ______ □ { f get; _ set; } ^родожит<strong>е</strong>ль--<br />

ность жизни.<br />

М <strong>е</strong>т од а о () вызыва<strong>е</strong>тся<br />

для каждого<br />

кадра. Возраст<br />

цв<strong>е</strong>тка за один цикл<br />

ув<strong>е</strong>личива<strong>е</strong>тся н<strong>е</strong>значит<strong>е</strong>льно,,<br />

но по<br />

м <strong>е</strong>р<strong>е</strong> работы с и м у ­<br />

лятора эти знач<strong>е</strong>ния<br />

сум м ирую т ся.<br />

public Flower(Point location,<br />

Location = location;<br />

Age = 0;<br />

Alive = true;<br />

Nectar = InitialNectar;<br />

NectarHarvested = 0;<br />

lifeSpan = random.Next(LifeSpanMin,<br />

}<br />

public double HarvestNectar0<br />

if (NectarGatheredPerTurn<br />

return 0;<br />

else {<br />

}<br />

}<br />

Random random) {<br />

{<br />

> Nectar)<br />

Nectar -= NectarGatheredPerTurn;<br />

NectarHarvested += NectarGatheredPerTurn;<br />

return NectarGatheredPerTurn;<br />

public void Go О {<br />

Age++;<br />

if (Age > lifeSpan)<br />

Alive = false;<br />

else {<br />

1/<br />

Nectar += NectarAddedPerTurn;<br />

if (Nectar > MaxNectar)<br />

Nectar = MaxNectar;<br />

Н <strong>е</strong>кт ар сл<strong>е</strong>ду<strong>е</strong>т<br />

добавлять только<br />

Живым цв<strong>е</strong>там.<br />

1<br />

F lo w e r<br />

Location: Point<br />

Age: int<br />

Alive: bool<br />

Nectar: double<br />

NectarHarvested: double<br />

lifespan: int<br />

HarvestNectar(): double<br />

Go()<br />

Д ост уп к полю<br />

N ectarH arvested<br />

должны им<strong>е</strong>т ь<br />

други<strong>е</strong> классы.<br />

LifeSpanMax + 1);<br />

Пч<strong>е</strong>лы вызывают м<strong>е</strong>т од<br />

H arvestN ectarQ для сбора н<strong>е</strong>ктара.<br />

За один раз пч<strong>е</strong>ла забира<strong>е</strong>т совс<strong>е</strong>м<br />

н<strong>е</strong>много н<strong>е</strong>кт ара, поэт ом у м<strong>е</strong>т од<br />

отсл<strong>е</strong>жива<strong>е</strong>т состояни<strong>е</strong> цв<strong>е</strong>тка<br />

на протяж<strong>е</strong>нии ряда кадров, пока<br />

н<strong>е</strong>кт ар н<strong>е</strong> закончится.<br />

, ^ П <strong>е</strong>р<strong>е</strong>м <strong>е</strong>нны <strong>е</strong> типа P o in t п ринадл<strong>е</strong>ж ат пространству им<strong>е</strong>н<br />

System.Drawing, ПОЭТОМу н<strong>е</strong> Забудьт<strong>е</strong> ДОбаВИТЬ СТрОЧКу using<br />

System.Drawing; В в<strong>е</strong>рхнюю часть ф зйла класса.<br />

532 г л а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Жизнь U см<strong>е</strong>рть цВ<strong>е</strong>тка<br />

К а ж д ы й ц в <strong>е</strong> т о к п р о х о д и т б а зо в ы й ц и к л , р а с т <strong>е</strong> т , н а к а п л и в а <strong>е</strong> т<br />

н <strong>е</strong> к т а р , о т д а <strong>е</strong> т э т о т н <strong>е</strong> к т а р п ч <strong>е</strong> л а м и н а к о н <strong>е</strong> ц у м и р а <strong>е</strong> т :<br />

4acni°<br />

З а д а в а <strong>е</strong> м ы <strong>е</strong><br />

Б о І 1р>осГьі<br />

___<br />

^ 5 П<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная NectarHarvested<br />

только ув<strong>е</strong>личива<strong>е</strong>т сво<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>,<br />

а больш<strong>е</strong> нигд<strong>е</strong> в класс<strong>е</strong> н<strong>е</strong> использу<strong>е</strong>тся.<br />

Зач<strong>е</strong>м она нужна?<br />

^ ; Это заготовка на будущ<strong>е</strong><strong>е</strong>. Симулятор<br />

долж<strong>е</strong>н отсл<strong>е</strong>живать состояни<strong>е</strong><br />

цв<strong>е</strong>тов и колич<strong>е</strong>ство собранного н<strong>е</strong>ктара.<br />

Эта п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная была оставл<strong>е</strong>на<br />

в открытом доступ<strong>е</strong>, им<strong>е</strong>нно потому что<br />

она потр<strong>е</strong>бу<strong>е</strong>тся другим классам.<br />

О & ь<strong>е</strong>у :^<br />

Ч<strong>е</strong>м с т а р м <strong>е</strong> .<br />

с т а н о в и т <strong>е</strong><br />

ив<strong>е</strong>т ок,<br />

д <strong>е</strong> т .<br />

собирают н <strong>е</strong>-<br />

<strong>е</strong>го^п^ УЛ1<strong>е</strong>н&и.


т рудяга-пч<strong>е</strong>ла<br />

Класс В<strong>е</strong><strong>е</strong><br />

Д л я цв<strong>е</strong>тов, г о т о в ы х дать н<strong>е</strong>ктар, п о н адобится класс В<strong>е</strong><strong>е</strong>, в к о т о р о м сод<strong>е</strong>ржатся<br />

св<strong>е</strong>д<strong>е</strong>ния о возраст<strong>е</strong> пч<strong>е</strong>лы, <strong>е</strong><strong>е</strong> м <strong>е</strong> с т о п о л о ж <strong>е</strong> н и и и в о з м о ж н о м колич<strong>е</strong>ств<strong>е</strong> соб<br />

и р а <strong>е</strong> м о г о н<strong>е</strong>ктара. В класс б ы л т а к ж <strong>е</strong> добавл<strong>е</strong>н м<strong>е</strong>тод, п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> щ а ю щ и й пч<strong>е</strong>лу<br />

в н у ж н у ю точку пространства.<br />

c l a s s B e e {<br />

p r i v a t e c o n s t d o u b l e H o n e y C o n s u m e d = 0.5;<br />

p r i v a t e c o n s t i n t M o v e R a t e = 3;<br />

p r i v a t e c o n s t d o u b l e M i n i m u m F l o w e r N e c t a r = l<br />

p r i v a t e c o n s t int C a r e e r S p a n = 1000;<br />

P l o w e r ^ ^<br />

•только с эт им к л а ссо м ""'''''''’'''<br />

p u b l i c int A g e { get; p r i v a t e set; }<br />

p u b l i c b o o l I n s i d e H i v e { get; p r i v a t e set; }<br />

p u b l i c d o u b l e N e c t a r C o l l e c t e d { get; p r i v a t e<br />

s e t ; }<br />

ла опр<strong>е</strong>д<strong>е</strong>ляй ^ н<strong>е</strong>т цв<strong>е</strong>тов, н Т к о т п Т '''^ бр<strong>е</strong>м<strong>е</strong>ни<br />

Д л я задания м<strong>е</strong>стополож<strong>е</strong>ния<br />

(использовалось вспомога -<br />

т<strong>е</strong>льно<strong>е</strong> пол<strong>е</strong>. А в т о м а т и ­<br />

ч<strong>е</strong>ски<strong>е</strong> свойства в данном<br />

случа<strong>е</strong> н<strong>е</strong> пом огут , т ак как<br />

м <strong>е</strong>т од Моу<strong>е</strong>Тош аЫ 5иосаНоп()<br />

н<strong>е</strong> о состоянии задать знач<strong>е</strong>ния<br />

своих чл<strong>е</strong>нов напрямую<br />

(иосаЬюп.Х -= Моу<strong>е</strong>каЬ<strong>е</strong>).<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m ) {<br />

}<br />

A g e + + ;<br />

534 г л а в а 12


М <strong>е</strong>т од M atkA bsO вычисля<strong>е</strong>т модуль разности<br />

м<strong>е</strong>жду пункт ом назнач<strong>е</strong>ния и т <strong>е</strong>кущ им<br />

полож<strong>е</strong>ни<strong>е</strong>м- ^<br />

private bool MoveTowardsLocation(Point destination)<br />

~Ч<br />

{<br />

хлчала мы<br />

if (MatbC^s^tdestination.X - location.X) location.X)<br />

назнач<strong>е</strong>ния.<br />

знач<strong>е</strong>ни<strong>е</strong> location.X += MoveRate;<br />

tru e при e l s e if (destination.X < location.X) Если пч<strong>е</strong>ла находится н<strong>е</strong>дост а­<br />

достиж<strong>е</strong>-^ location.X -= MoveRate;<br />

точно близко к пункт у назнач<strong>е</strong>ния,<br />

HUU пч<strong>е</strong>лой<br />

она см<strong>е</strong>щ а<strong>е</strong>т ся в <strong>е</strong>го направл<strong>е</strong>нии<br />

пункт а н а­<br />

на в<strong>е</strong>личину, опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>мую к о эф ­<br />

знач<strong>е</strong>ния. if (destination.Y > location.Y)<br />

фици<strong>е</strong>нт ом см<strong>е</strong>щ<strong>е</strong>ния.<br />

location.Y += MoveRate;<br />

else if (destination.Y < location.Y)<br />

location.Y -= MoveRate;<br />

return false;<br />

- М <strong>е</strong>т од возвраща<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> false, т ак как<br />

пункт назнач<strong>е</strong>ния н<strong>е</strong> ■<br />

дост игнут и нужно<br />

‘продолжать движ<strong>е</strong>ни<strong>е</strong>.<br />

о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> з у л ь т а т ы<br />

М <strong>е</strong>т од MoveTowardsLocationQ<br />

^ см<strong>е</strong>щ а<strong>е</strong>т полож<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>лы,<br />

м<strong>е</strong>няя с<strong>е</strong> коорЭинлилм X м Y.<br />

К а к только пч<strong>е</strong>ла достига<strong>е</strong>т<br />

пункт а назнач<strong>е</strong>ния, он<br />

возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true.<br />

Н и ж <strong>е</strong> п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н с п и с о к д <strong>е</strong> й с т в и й , к о т о р ы <strong>е</strong> д о л ж н ы в ы п о л н я т ь п ч <strong>е</strong> л ы . С о з д а й ­<br />

т <strong>е</strong> д л я о б ъ <strong>е</strong> к т а В<strong>е</strong><strong>е</strong> п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и <strong>е</strong> BeeState (С о с т о я н и <strong>е</strong> п ч <strong>е</strong> л ы ). Д л я к а ж д о й и з<br />

п ч <strong>е</strong> л п о т р <strong>е</strong> б у <strong>е</strong> т с я п р <strong>е</strong> д н а з н а ч <strong>е</strong> н н о <strong>е</strong> т о л ь к о д л я ч т <strong>е</strong> н и я а в т о м а т и ч <strong>е</strong> с к о <strong>е</strong> с в о й с т в о<br />

Currentstate (Т <strong>е</strong> к у щ <strong>е</strong> <strong>е</strong> с о с т о я н и <strong>е</strong> ). В н а ч а л ь н ы й м о м <strong>е</strong> н т в р <strong>е</strong> м <strong>е</strong> н и п ч <strong>е</strong> л а н а х о ­<br />

д и т с я в с о с т о я н и и idle (Н <strong>е</strong> з а н я т ы й ). Д о б а в ь т <strong>е</strong> к м <strong>е</strong> т о д у Go () о п <strong>е</strong> р а т о р switch<br />

с п а р а м <strong>е</strong> т р а м и д л я к а ж д о г о э л <strong>е</strong> м <strong>е</strong> н т а п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и я .<br />

Эл<strong>е</strong>м<strong>е</strong>нт<br />

Idle<br />

FlyingToFlow er<br />

G atkerin gN ectar<br />

Retu rningToH ive<br />

M akingHoney<br />

R etired<br />

функция<br />

Пч<strong>е</strong>ла нич<strong>е</strong>м н<strong>е</strong> занята<br />

Пч<strong>е</strong>ла л<strong>е</strong>т ит на цв<strong>е</strong>ток<br />

Пч<strong>е</strong>ла собира<strong>е</strong>т н<strong>е</strong>кт ар<br />

Пч<strong>е</strong>ла возвраща<strong>е</strong>тся в ул<strong>е</strong>й<br />

Пч<strong>е</strong>ла производит м<strong>е</strong>д<br />

Пч<strong>е</strong>ла пр<strong>е</strong>кращ а<strong>е</strong>т работ у<br />

д а л ь ш <strong>е</strong> > 535


п ч<strong>е</strong>ла, с п о к о й н о !<br />

'а ж н <strong>е</strong> н и <strong>е</strong><br />

'р т о и к о<br />

о с н о в <strong>е</strong> д а н н о г о н а п р <strong>е</strong> д ы д у щ <strong>е</strong> й с т р а н и ц <strong>е</strong> с п и с к а п ч <strong>е</strong> л и н ы х з а н я т и й<br />

к л а с с а в <strong>е</strong> <strong>е</strong> б ы л о с о з д а н о п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и <strong>е</strong> Beestate. З а к р ы т о <strong>е</strong> п о л <strong>е</strong><br />

c u r r e n t s t a t e п р <strong>е</strong> д н а з н а ч <strong>е</strong> н о д л я о т с л <strong>е</strong> ж и в а н и я с о с т о я н и я к а ж д о й п ч <strong>е</strong> л ы .<br />

<strong>е</strong>пшп B e e s t a t e {<br />

}<br />

I d l e ,<br />

F ly in g T o F lo w e r ,<br />

G a t h e r i n g N e c t a r ,<br />

R e t u r n in g T o H iv e ,<br />

M a k in g H o n ey ,<br />

R e t i r e d<br />

Э т о п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

возможных состояний<br />

пч<strong>е</strong>лы.<br />

c l a s s B e e {<br />

// о б ъ я в л <strong>е</strong> н и <strong>е</strong> к о н с т а н т<br />

// о б ъ я в л <strong>е</strong> н и <strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы х<br />

p u b l i c B e e s t a t e C u r r e n t s t a t e { g e t ; p r i v a t e s e t ; }<br />

p u b l i c B e e ( i n t ID, P o i n t i n i t i a l L o c a t i o n ) {<br />

t h i s . I D = ID;<br />

A g e = 0;<br />

l o c a t i o n = i n i t i a l L o c a t i o n ;<br />

I n s i d e H i v e = true;<br />

C u r r e n t s t a t e = B eestate.Idle;^<br />

d e s t i n a t i o n F l o w e r = n u l l ; Сначала пч<strong>е</strong>лы нич<strong>е</strong>го<br />

N e c t a r C o l l e c t e d = 0 ; н<strong>е</strong> д<strong>е</strong>лают.<br />

}<br />

Вы н<strong>е</strong> забы ли добавить в в<strong>е</strong>рхню ю часть ф айла класса строку<br />

us ing Sys tem.Drawing;?<br />

536 гл а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m )<br />

A g e + + ;<br />

s w i t c h ( C u r r e n t s t a t e ) {<br />

c a s e B e e s t a t e . I d l e :<br />

if (Age > CareertJpanj a r e e r S p a n ) {<br />

О п<strong>е</strong>рат ор sw itckf)<br />

обрабат ыва<strong>е</strong>т<br />

состояни<strong>е</strong> каждой<br />

1лч<strong>е</strong>лы.<br />

C u r r e n t s t a t e = B e e s t a t e .Retired^^<br />

e l s e {<br />

// Ч т о м ы д <strong>е</strong> л а <strong>е</strong> м в с о с т о я н и и i d l e ?<br />

b r e a k ;<br />

c a s e B e e s t a t e . F ly in g T o F lo w e r :<br />

// П <strong>е</strong> р <strong>е</strong> м <strong>е</strong> щ <strong>е</strong> н и <strong>е</strong> п ч <strong>е</strong> л ы к в ы б р а н н о м у ц в <strong>е</strong> т к у<br />

b r e a k ;<br />

c a s e B e e s t a t e . G a t h e r i n g N e c t a r :<br />

^ d o u b l e n e c t a r = d e s t i n a t i o n F l o w e r . H a r v e s t N e c t a r ()<br />

if ( n e c t a r > 0) ^ ------- <strong>е</strong>сли н<strong>е</strong>кт ар <strong>е</strong>щ<strong>е</strong><br />

N e c t a r C o l l e c t e d += n e c t a r ; ост ался, добавьт<strong>е</strong> <strong>е</strong>го<br />

e l s e ^


в н <strong>е</strong> ш н и й в и д у л ь я<br />

Программисты против б<strong>е</strong>здомных пч<strong>е</strong>л<br />

у н а с <strong>е</strong> с ть п ч <strong>е</strong> л ы и п о л н ы <strong>е</strong> н <strong>е</strong> к т а р а ц в <strong>е</strong> ты . Н у ж н о н а п и с а т ь к о д для с б о р а н <strong>е</strong> к т а р а ,<br />

н о п <strong>е</strong> р <strong>е</strong> д э т и м задум а<strong>е</strong>м с я о т о м , о тку д а п о я в и л и с ь пч<strong>е</strong>лы ? И куд а о н и п о н <strong>е</strong> с у т в<strong>е</strong>сь<br />

э т о т н <strong>е</strong> к т а р ? О т в <strong>е</strong> т о м н а в о п р о с б уд<strong>е</strong>т кл асс H iv e .<br />

У л <strong>е</strong> й — н <strong>е</strong> п р о с т о м <strong>е</strong> с т о , куд а в о зв р а щ а ю т с я п ч <strong>е</strong> л ы . В н у т р и о н р а зд <strong>е</strong> л <strong>е</strong> н н а зо н ы<br />

р а з л и ч н о г о н а з н а ч <strong>е</strong> н и я . С у щ <strong>е</strong> с т в у ю т в хо д и в ы х о д , п и т о м н и к д ля в ы р а щ и в а н и я<br />

м о л о д ы х п ч <strong>е</strong> л и ф а б р и к а п о п <strong>е</strong> р <strong>е</strong> р а б о т к <strong>е</strong> н <strong>е</strong> к т а р а в м<strong>е</strong>д.<br />

Зоны б н у т р м ул1?я<br />

отд<strong>е</strong>л<strong>е</strong>ны друг от<br />

друга, и пч<strong>е</strong>ла м о ­<br />

ж<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>ходить<br />

из зоны в зону т ак<br />

ж<strong>е</strong>, как она л<strong>е</strong>т ит<br />

из улья к цв<strong>е</strong>тку.<br />

Нобы<strong>е</strong> іяч<strong>е</strong>л&і<br />

їл о я б л я ю тс я из<br />

lA.UWOMHWKfl-<br />

Пч<strong>е</strong>лы зал<strong>е</strong>т аю т в цл<strong>е</strong>й<br />

ч<strong>е</strong>р<strong>е</strong>з вход, а покидают<br />

<strong>е</strong> го ч<strong>е</strong>р<strong>е</strong>з выход. Вс<strong>е</strong><br />

хорошо организовано.<br />

Для )кизни улья ну)к<strong>е</strong>н м<strong>е</strong>д<br />

С у щ <strong>е</strong> с т в о в а н и <strong>е</strong> улья з а в и с и т о т к о л и ч <strong>е</strong> с т в а х р а н и м о г о<br />

в н <strong>е</strong> м м <strong>е</strong>да. М <strong>е</strong> д н у ж <strong>е</strong> н д ля ф у н к ц и о н и р о в а н и я с та р ы х<br />

и с о з д а н и я н о в ы х п ч <strong>е</strong> л . С о о т в <strong>е</strong> т с т в <strong>е</strong> н н о , н а м п о т р <strong>е</strong> б у <strong>е</strong> т с я<br />

ф а б р и к а , п <strong>е</strong> р <strong>е</strong> р а б а т ы в а ю щ а я с о б р а н н ы й п ч <strong>е</strong> л а м и н <strong>е</strong> к т а р<br />

в м <strong>е</strong>д. И з <strong>е</strong> д и н и ц ы н <strong>е</strong> к т а р а п о л у ч а <strong>е</strong> т с я 0 .2 5 <strong>е</strong> д и н и ц ы м <strong>е</strong>да.<br />

^<br />

Обдумайт <strong>е</strong> эт у информацию... м<strong>е</strong>д<br />

нуж<strong>е</strong>н для функционирования улья и<br />

создания новых пч<strong>е</strong>л. Уж<strong>е</strong> им<strong>е</strong>юш,и<strong>е</strong>£.я<br />

пч<strong>е</strong>лы собирают н<strong>е</strong>кт ар, который<br />

^"^— п<strong>е</strong>р<strong>е</strong>рабат ыва<strong>е</strong>т ся в м<strong>е</strong>д и позволя<strong>е</strong>т<br />

улью работ ат ь дальш<strong>е</strong>.<br />

Им<strong>е</strong>нно это (с н<strong>е</strong>большой помощ ью<br />

с наш<strong>е</strong>й стороны) вам пр<strong>е</strong>дст оит<br />

смод<strong>е</strong>лировать.<br />

538 г л а в а 12


о б з о р и пр<strong>е</strong>дварит<strong>е</strong>льны<strong>е</strong> р <strong>е</strong> з у л ь т а т ы<br />

^ п р а ж н <strong>е</strong> н и <strong>е</strong> В а ш а з а д а ч а — с о з д а т ь к л а с с H iv e .<br />

О<br />

О<br />

Н апиш ит<strong>е</strong> ск<strong>е</strong>л<strong>е</strong>т класса<br />

К ак и в случа<strong>е</strong> класса F lo w e r, нужно н ачать со ск<strong>е</strong>л<strong>е</strong>та.<br />

Д иаграм м а класса показана справа. С д<strong>е</strong>лайт<strong>е</strong><br />

свойство H oney п р<strong>е</strong>дназнач<strong>е</strong>нны м только для чт<strong>е</strong>н и я,<br />

пол<strong>е</strong> l o c a t i o n s долж но бы ть закры ты м , как и пол<strong>е</strong><br />

b e e C o u n t.<br />

О пр<strong>е</strong>д<strong>е</strong>л ит<strong>е</strong> константы<br />

У к а ж и т <strong>е</strong> н а ч а л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о п ч <strong>е</strong> л ( 6 ) , м <strong>е</strong> д а (3 .2 ) ,<br />

м а кс и м а л ь н о к о л и ч <strong>е</strong> с т в о м <strong>е</strong>д а (1 5 ) , к о э ф ф и ц и <strong>е</strong> н т п <strong>е</strong> р <strong>е</strong> ­<br />

р а б о т к и н <strong>е</strong> к т а р а в м <strong>е</strong>д ( .2 5 ) , м а кс и м а л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о<br />

п ч <strong>е</strong> л (8 ) и м и н и м а л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о м <strong>е</strong>да, п р и к о т о р о м<br />

п о я в л я ю т с я н о в ы <strong>е</strong> п ч <strong>е</strong> л ы (4 ).<br />

Код, работаю щ ий с пол<strong>е</strong>м L o c a t i o n<br />

Н а п и ш и т <strong>е</strong> м <strong>е</strong> т о д GetLocation ( ) . О н д о л ж <strong>е</strong> н б р а ть<br />

с тр о ку, с р а в н и в а т ь <strong>е</strong><strong>е</strong> со с л о в а р н ы м и з н а ч <strong>е</strong> н и я м и и в о з­<br />

в р а щ а ть с т р у к т у р у point. П р и о т с у т с т в и и с т р о к и д о л ж ­<br />

н о п о я в л я ть с я и с к л ю ч <strong>е</strong> н и <strong>е</strong> ArgumentException.<br />

З а т <strong>е</strong> м н а п и ш и т <strong>е</strong> м <strong>е</strong> т о д InitializeLocations ( ) , за ­<br />

д а ю щ и <strong>е</strong> к о о р д и н а т ы э л <strong>е</strong> м <strong>е</strong> н т о в улья:<br />

H iv e<br />

Honey; double<br />

locations: Dictionary<br />

beeCount; int<br />

InitializeLocationsQ<br />

AddHoney(Nectar; double); bool<br />

ConsumeHoney(amount: double); bool<br />

AddBee(random; Random)<br />

Go(random; Random)<br />

GetLocation(location; string); Point<br />

Присвойт<strong>е</strong> к о н с т л н -<br />

■т ам и м <strong>е</strong> н а<br />

Гх° н Г и о Т н а Т <strong>е</strong> н Т £ в ы р а ж <strong>е</strong> н и и .<br />

в к о т о р ш эти константы<br />

S y d y m ф и г у р и р о в а т ь .<br />

В х о д ( 6 0 0 ,1 0 0 )<br />

П и т о м н и к (9 5 , 1 7 4 )<br />

Ф а б р и к а (1 5 7 , 9 8 )<br />

В ы х о д (1 9 4 , 2 1 3 )<br />

Вс<strong>е</strong> эт о привязано<br />

к т очкам в двум<br />

<strong>е</strong>рном п рост ранств<strong>е</strong><br />

улья.<br />

Конструктор H iv e<br />

К о н с т р у к т о р д о л ж <strong>е</strong> н зад ав ать н а ч а л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о<br />

м <strong>е</strong>да в уль<strong>е</strong> и п о л о ж <strong>е</strong> н и <strong>е</strong> в н у т р <strong>е</strong> н н и х э л <strong>е</strong> м <strong>е</strong> н т о в , а т а к ­<br />

ж <strong>е</strong> с о зд ав ать э к з <strong>е</strong> м п л я р Random. З а т <strong>е</strong> м д ля к а ж д о й зар<br />

о ж д а ю щ <strong>е</strong> й с я п ч <strong>е</strong> л ы н у ж н о вы зв ать м <strong>е</strong> т о д A ddB ee {),<br />

п <strong>е</strong> р <strong>е</strong> д а в а я <strong>е</strong>м у т о л ь к о ч т о с о з д а н н ы й э к з <strong>е</strong> м п л я р Random.<br />

в пользу<strong>е</strong>імся к « - « « Г Г^ Г Рсинат Т “ ам “ “ и. -<br />

р о в а и н ь ї м и ^ ^ 0 -<br />

h p u<br />

можно<br />

ж <strong>е</strong> л а н и и з д _<br />

V о б ь <strong>е</strong> к т R andom добавля<strong>е</strong>т случайно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> к полож<strong>е</strong>нию объ<strong>е</strong>кта<br />

^ Nursery. Эт о позволит изб<strong>е</strong>жать появл<strong>е</strong>ния пч<strong>е</strong>л в одной точк<strong>е</strong>.<br />

д а л ь ш <strong>е</strong> > 539


н а ч н и т <strong>е</strong> с м о д <strong>е</strong> л и<br />

а ж н <strong>е</strong> н и <strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

c l a s s H i v e {<br />

В а м н у ж н о б ы л о начать п о с т р о <strong>е</strong> н и <strong>е</strong> класса Hive.<br />

Уб<strong>е</strong>дит<strong>е</strong>сь в наличии строчки «using<br />

S ystem .D raw ing;» т ак как код<br />

использу<strong>е</strong>т знач<strong>е</strong>ния т ипа Point.<br />

p r i v a t e c o n s t i n t I n i t i a l B e e s = 6 ;<br />

p r i v a t e c o n s t d o u b l e I n i t i a l H o n e y =3.2;<br />

p r i v a t e c o n s t d o u b l e M a x i m u t n H o n e y = 15.0;<br />

p r i v a t e c o n s t d o u b l e N e c t a r H o n e y R a t i o = .25;<br />

Вы мож <strong>е</strong>т<strong>е</strong> выдрат ь для<br />

конст ант и други<strong>е</strong> им<strong>е</strong>на.<br />

p r i v a t e c o n s t d o u b l e M i n i m u m H o n e y F o r C r e a t i n q B e e s = 4 0•<br />

p r i v a t e c o n s t i n t M , x i „ » E a e s = 8 ,-<br />

p r i v a t e D i c t i o n a r y < s t r i n g , P o i n t > l o c a t i o n s ;<br />

p r i v a t e int b e e C o u n t = 0; f:r<br />

p u b l i c d o u b l e H o n e y { g e t ; p r i v a t e set; }<br />

p r i v a t e v o i d I n i t i a l i z e L o c a t i o n s () 0 ({<br />

}<br />

l o c a t i o n s = n e w D i c t i o n a r y < s t r i n g , P o i n t > ( )<br />

l o c a t i o n s . A d d ( " E n t r a n c e " , n e w P o i n t (600, 100))<br />

l o c a t i o n s . A d d (" N u r s e r y " , n e w P o i n t ( 9 5 , 174))<br />

l o c a t i o n s . A d d (" H o n e y F a c t o r y " , n e w P o i n t (157,<br />

l o c a t i o n s . A d d (" E x i t " , n e w P o i n t (194, 2 1 3 ) ) ;<br />

p u b l i c P o i n t G e t L o c a t i o n ( s t r i n g l o c a t i o n )<br />

if ( l o c a t i o n s .K e y s .C o n t a i n s ( l o c a t i o n ) )<br />

e l s e<br />

r e t u r n l o c a t i o n s [ l o c a t i o n ] ;<br />

{<br />

98) )<br />

t h r o w n e w A r g u m e n t E x c e p t i o n (" U n k n o w n l o c a t i o n :<br />

} Э т от м <strong>е</strong>т од н<strong>е</strong> позволя<strong>е</strong>т<br />

\ другим классам вносить<br />

г<br />

V. изм<strong>е</strong>н<strong>е</strong>ния в словарь, то<br />

p u b l i c H i v e О<br />

^<br />

<strong>е</strong>ст ь п<strong>е</strong>р<strong>е</strong>д нами прим <strong>е</strong>р<br />

H o n e y = I n i t i a l H o n e y ; инкапсиляции.<br />

}<br />

I n i t i a l i z e L o c a t i o n s {);<br />

R a n d o m r a n d o m = n e w R a n d o m ();<br />

f o r (int i = 0; i < I n i t i a l B e e s ; i++)<br />

A d d B e e ( r a n d o m ) ;<br />

пч<strong>е</strong>лы.<br />

овар,<br />

в м з й г «<br />

К онст ант а<br />

M aximumHoney м <strong>е</strong> ­<br />

т <strong>е</strong>т ся в диапазон<strong>е</strong><br />

от InitialHoney (3 .2 )<br />

эт ого знач<strong>е</strong>ния,<br />

T Z T IZ A V<br />

им<strong>е</strong>нно эт ом у т ипу<br />

принадл<strong>е</strong>жит конст<br />

ант а InitialHoney.<br />

или эт о н<strong>е</strong> буд<strong>е</strong>т<br />

работ ат ь.<br />

+ l o c a t i o n )<br />

p u b l i c b o o l A d d H o n e y ( d o u b l e n e c t a r ) { r e t u r n t r ue; }<br />

p u b l i c b o o l C o n s u m e H o n e y ( d o u b l e a m o u n t ) { r e t u r n true;<br />

p r i v a t e v o i d A d d B e e ( R a n d o m r a n d o m ) { }<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m ) { }<br />

М о ж н о добавть исключ<strong>е</strong>ни<strong>е</strong> N otlm plem entedE xception ко вс<strong>е</strong>м<br />

м <strong>е</strong>т одам , для кот орых пока н<strong>е</strong> написана р<strong>е</strong>ализация. Эт о п о ­<br />

зволит обнаруж ить м <strong>е</strong>ст а, в кот оры<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т дописат ь код.<br />

Э т от код <strong>е</strong>щ<strong>е</strong> н<strong>е</strong><br />

написан, используй<br />

т <strong>е</strong> пуст ы <strong>е</strong><br />

м <strong>е</strong>т оды в кач<strong>е</strong>ст в<strong>е</strong><br />

м<strong>е</strong>ст озаполнит <strong>е</strong>ля.<br />

540 г л а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Странный способ<br />

написания кода. П ч <strong>е</strong> л ы пока н<strong>е</strong> знаю т<br />

о цв<strong>е</strong>тах, а у л <strong>е</strong> й полон пусты х объявл<strong>е</strong>ний<br />

м <strong>е</strong>тодов. И н и ч <strong>е</strong>го н<strong>е</strong> работа<strong>е</strong>т, н<strong>е</strong> так ли?<br />

Код составля<strong>е</strong>тся из кусочков.<br />

Б ы л о бы п р <strong>е</strong> к р а с н о , <strong>е</strong> сл и бы к о д кл а с с а п и с а л с я за о д и н р а з,<br />

к о м п и л и р о в а л с я , т <strong>е</strong> с т и р о в а л с я и откл а д ы в ал с я в с то р о н у , ч т о ­<br />

бы п <strong>е</strong> р <strong>е</strong> й т и к р а б о т <strong>е</strong> н а д с л <strong>е</strong> д у ю щ и м кл а с с о м . К с о ж а л <strong>е</strong> н и ю ,<br />

э т о н <strong>е</strong> в о з м о ж н о .<br />

В б о л ь ш и н с т в <strong>е</strong> случа<strong>е</strong>в к о д п и ш <strong>е</strong> т с я ф р а г м <strong>е</strong> н т за ф р а гм <strong>е</strong> н т о м .<br />

М ы п р а к т и ч <strong>е</strong> с к и н а п и с а л и кл а сс F l o w e r , а в о т д ля кл а с с а В <strong>е</strong> <strong>е</strong><br />

э т о сд<strong>е</strong>лать н <strong>е</strong> п о л у ч и л о с ь . В ам н у ж н о д о п и с а т ь , ч т о сл <strong>е</strong>ду<strong>е</strong>т<br />

д <strong>е</strong>л ать в к а ж д о м и з с о с т о я н и й .<br />

И кл а сс H i v e о с та л с я с м н о ж <strong>е</strong> с т в о м п у с т ы х м <strong>е</strong> то д о в . К р о м <strong>е</strong><br />

т о г о , п ч <strong>е</strong> л ы п о к а н и к а к н <strong>е</strong> связан ы с уль<strong>е</strong>м . П л ю с н <strong>е</strong> р <strong>е</strong> ш <strong>е</strong> н н а я<br />

п р о б л <strong>е</strong> м а с м н о г о к р а т н ы м вы зо в о м м <strong>е</strong> т о д а G o О ...<br />

Н о м ы <strong>е</strong>щ <strong>е</strong> даж <strong>е</strong> н<strong>е</strong> п р и ступ ил и<br />

к со<strong>е</strong>д ин<strong>е</strong>н и ю классов д руг с другом!<br />

М ы разобрались с архит<strong>е</strong>ктуро й<br />

и п р и с туп и л и к постро<strong>е</strong>нию .<br />

С начала разрабаты ва<strong>е</strong>м , зат<strong>е</strong>м строим<br />

М ы н а ч а л и п р о <strong>е</strong> к т с п о н и м а н и я т о г о , ч т о и м <strong>е</strong> н н о м ы х о т и м п о л у ­<br />

ч и т ь в и т о г<strong>е</strong> : с и м у л я т о р улья. М ы м н о г о <strong>е</strong> зн а <strong>е</strong> м о в з а и м о д <strong>е</strong> й с т в и и<br />

т а к и х о б ъ <strong>е</strong> кто в к а к п ч <strong>е</strong> л ы , ц в <strong>е</strong> ты , у л <strong>е</strong> й и о к р у ж а ю щ и й м и р . И м <strong>е</strong> н ­<br />

н о п о э т о м у м ы н а ч а л и с а р х и т <strong>е</strong>к т у р ы , д а ю щ <strong>е</strong> й п р <strong>е</strong> д с т а в л <strong>е</strong> н и <strong>е</strong> о<br />

т о м , к а к кл ассы р а б о т а ю т д р у г с д р у го м . Т о л ь ко п о с л <strong>е</strong> э т о г о м о ж н о<br />

п <strong>е</strong> р <strong>е</strong> х о д и т ь к р а з р а б о т к <strong>е</strong> к а ж д о г о и з кл асс о в .<br />

Р а б о т а т ь н а д п р о <strong>е</strong> к т о м н а м н о г о п р о щ <strong>е</strong> , <strong>е</strong> сл и вы за р а н <strong>е</strong> <strong>е</strong> п р <strong>е</strong> д с т а в ­<br />

л я <strong>е</strong> т <strong>е</strong> к о н <strong>е</strong> ч н ы й р <strong>е</strong>зу л ь тат. Э т о в п о л н <strong>е</strong> о ч <strong>е</strong> в и д н о . И и м <strong>е</strong> н н о э т о п о ­<br />

з в о л я <strong>е</strong> т в н <strong>е</strong> с т и в к о н <strong>е</strong> ч н ы й п р о д у к т з н а ч и т <strong>е</strong> л ь н ы <strong>е</strong> и з м <strong>е</strong> н <strong>е</strong> н и я .<br />

д а л ь ш <strong>е</strong> *■ 541


д о б а в ь т <strong>е</strong> в у л <strong>е</strong> й м <strong>е</strong> т о д G o ß<br />

Постро<strong>е</strong>ни<strong>е</strong> класса Hive<br />

В <strong>е</strong> р н <strong>е</strong> м с я к кл а ссу H i v e и н а п и ш <strong>е</strong> м к о д для о т-<br />

сутств ую ш :и х п о к а м <strong>е</strong> то д о в :<br />

c l a s s H i v e {<br />

// объявл<strong>е</strong>ни<strong>е</strong> констант<br />

// объявл<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных<br />

// I n i t i a l i z e L o c a t i o n s ()<br />

// G e t L o c a t i o n ()<br />

// H i v e c o n s t r u c t o r<br />

^<br />

p u b l i c b o o l A d d H o n e y ( d o u b l e n e c t a r ) { V /<br />

d o u b l e h o n e y T o A d d = n e c t a r * N e c t a r H o n e y R a t i o ;<br />

if ( h o n e y T o A d d + H o n e y > M a x i m u m H o n e y )<br />

r e t u r n false;<br />

■М пров<strong>е</strong>рим , <strong>е</strong>ст ь ли<br />

о уль<strong>е</strong> м <strong>е</strong>ст о для т акого<br />

колич<strong>е</strong>ства м<strong>е</strong>да.<br />

H o n e y += h o n e y T o A d d ; ^ — При наличии м <strong>е</strong>ст а<br />

добавим м<strong>е</strong>д.<br />

м <strong>е</strong>т од б<strong>е</strong>р<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нную<br />

r e t u r n true;<br />

am ou n t (колич<strong>е</strong>ство м<strong>е</strong>да) и<br />

}<br />

^ ^ л я <strong>е</strong> т м <strong>е</strong>д из хранилища пот р<strong>е</strong>бит <strong>е</strong><br />

p u b l i c b o o l C o n s u m e H o n e y ( d o u b l e a m o u n t ) { лям.<br />

if ( a m o u n t > Honey)<br />

J<br />

r e t u r n f a l s e ;<br />

e l s e {<br />

Если колич<strong>е</strong>ство м<strong>е</strong>да м<strong>е</strong>ньш <strong>е</strong>, ч<strong>е</strong>м т р<strong>е</strong>бу<strong>е</strong>т ся<br />

пч<strong>е</strong>лам, м <strong>е</strong>т од возвращ а<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> False.<br />

H o n e y -= a m o u n t ;


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р<strong>е</strong>зультаты<br />

М<strong>е</strong>тод 6о() для улья<br />

М ы у ж <strong>е</strong> п и с а л и м <strong>е</strong> т о д G o ( ) д л я кл а с с о в F l o w e r и В <strong>е</strong> <strong>е</strong><br />

(х о т я .и н <strong>е</strong> з а к о н ч и л и э ту р а б о т у ). В о т м <strong>е</strong> т о д G o () для<br />

кл а с с а Hive:<br />

5 ^й н ст^<strong>е</strong>н н й л і<br />

public void Go(Random random) {<br />

if (Honey > MinimumHoneyForCreatingBees)<br />

^


п о с т р о и м м и р<br />

Вс<strong>е</strong> готобо для класса IVorM<br />

И м <strong>е</strong> я п р а к т и ч <strong>е</strong> с к и го т о в ы <strong>е</strong> кл а сс ы Hive, В <strong>е</strong> <strong>е</strong> и Flower, м о ж н о п р и с т у п и т ь к п о с т р о <strong>е</strong> н и ю кл а сса World,<br />

п р <strong>е</strong> д н а з н а ч <strong>е</strong> н н о г о д ля к о о р д и н а ц и и с о с т а в н ы х ч а с т <strong>е</strong> й н а ш <strong>е</strong> г о с и м у л я то р а . И м <strong>е</strong> н н о о н буд<strong>е</strong>т п о д д <strong>е</strong> р ж и ­<br />

в ать ж и з н <strong>е</strong> д <strong>е</strong> я т <strong>е</strong> л ь н о с т ь п ч <strong>е</strong> л , о п р <strong>е</strong> д <strong>е</strong> л я т ь н а л и ч и <strong>е</strong> м <strong>е</strong> с т а д ля н о в ы х п ч <strong>е</strong> л , р а з м <strong>е</strong> щ а т ь ц в <strong>е</strong> ты и т. п .<br />

Y~ko.cc World<br />

u ли<strong>е</strong>д-<br />

System.VW'<br />

Объ<strong>е</strong>кт IVorld упрабдя<strong>е</strong>ш миром<br />

классов<br />

^ока н<strong>е</strong> написан,<br />

но вс<strong>е</strong> сост авм<br />

Т с :“Г “ «<br />

О с н о в н о й з а д а ч <strong>е</strong> й о б ъ <strong>е</strong> к т а W o r l d я в л я <strong>е</strong> т с я в ы зо в м <strong>е</strong> т о ­<br />

д а G o ( ) в к а ж д о м к а д р <strong>е</strong> д ля к а ж д о г о э к з <strong>е</strong> м п л я р а Flower,<br />

В <strong>е</strong> <strong>е</strong> и Hive. Д р у г и м и с л о в а м и , о б ъ <strong>е</strong> к т W o r l d о б <strong>е</strong> с п <strong>е</strong> ч и ­<br />

в а <strong>е</strong> т суш ;<strong>е</strong>с тв о вани<strong>е</strong> п ч <strong>е</strong> л и н о г о м и р а .<br />

М <strong>е</strong> т о а ^ о ( ) йз кл асса<br />

W orld вызыва<strong>е</strong>т,<br />

одноим<strong>е</strong>нный м <strong>е</strong>т од<br />

ОЛЯ в<strong>е</strong><strong>е</strong>к объ<strong>е</strong>ктов<br />

пч<strong>е</strong>линого мира.<br />

fo r e a c h (F low er f lo w e r in F lo w ers)<br />

f lo w e r . Go(random );<br />

О сновная<br />

ф орм а<br />

5у8»<strong>е</strong>т.\№ ^''^°<br />

( # ^ V ,..,___<br />

1<br />

Н а м вс<strong>е</strong> равно прид<strong>е</strong>тся<br />

има/^ь д<strong>е</strong>ло с вызовом м й -<br />

тода ОоО класса W orld, но<br />

к эт ом у мы <strong>е</strong>щ<strong>е</strong> в<strong>е</strong>рн<strong>е</strong>мся.<br />

fo r e a c h (В<strong>е</strong><strong>е</strong> b e e in B ees)<br />

b e e . Go (rctndom) ;<br />

[h i v e . G o(randonO<br />

^epe4env>'<br />

544 г л а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Сист<strong>е</strong>ма, осноВанная на кадрах<br />

М <strong>е</strong> т о д Go ( ) для к а ж д о г о и з о б ъ <strong>е</strong> кто в д о л ж <strong>е</strong> н вы зы в ать ся в к а ж д о м к а д р <strong>е</strong> н а ш <strong>е</strong> г о с и м у л я то р а . П о д к а ­<br />

д р о м в д а н н о м сл у ч а<strong>е</strong> п о д р а зу м <strong>е</strong> в а <strong>е</strong> тс я п р о и з в о л ь н о <strong>е</strong> к о л и ч <strong>е</strong> с т в о в р <strong>е</strong> м <strong>е</strong> н и : н а п р и м <strong>е</strong> р , к а р т и н к а м о ж <strong>е</strong> т<br />

о б н о в л я ть с я ка ж д ы <strong>е</strong> 10 с <strong>е</strong> кун д и л и к а ж д ы <strong>е</strong> 6 0 с <strong>е</strong> кун д л и б о к а ж д ы <strong>е</strong> 10 м и н у т.<br />

С м <strong>е</strong> н а кад р о в в л и я <strong>е</strong> т н а с о с т о я н и <strong>е</strong> к а ж д о г о о б ъ <strong>е</strong> кта. У н <strong>е</strong> й с т а р <strong>е</strong> <strong>е</strong> т и п р о в <strong>е</strong> р я <strong>е</strong> т , н <strong>е</strong> т р <strong>е</strong> б у ю т с я л и н о ­<br />

вы <strong>е</strong> п ч <strong>е</strong> л ы . П ч <strong>е</strong> л ы п р о л <strong>е</strong> т а ю т н <strong>е</strong> б о л ь ш о й о т р <strong>е</strong> з о к п у т и п о н а п р а в л <strong>е</strong> н и ю к п у н к т у н а з н а ч <strong>е</strong> н и я , в ы п о л н я ­<br />

ю т м а л <strong>е</strong> н ь к и й к у с о к р а б о т ы и л и с т а р <strong>е</strong> ю т . К а ж д ы й ц в <strong>е</strong> т о к п р о и з в о д и т н <strong>е</strong> б о л ь ш о <strong>е</strong> к о л и ч <strong>е</strong> с т в о н <strong>е</strong> к т а р а<br />

и т о ж <strong>е</strong> с та р <strong>е</strong> <strong>е</strong> т. Ю гасс World о т с л <strong>е</strong> ж и в а <strong>е</strong> т , ч т о б ы п р и к а ж д о м вы зо в<strong>е</strong> м <strong>е</strong> т о д а Go () с к а ж д ы м о б ъ <strong>е</strong> к т о м<br />

п р о и с х о д и л и н <strong>е</strong> о б х о д и м ы <strong>е</strong> и з м <strong>е</strong> н <strong>е</strong> н и я .<br />

Каждый вызов<br />

Ф О<br />

в класс<strong>е</strong> W orld приводит<br />

яЛ Ф этого лл<strong>е</strong>тода для<br />

вс<strong>е</strong>х объ<strong>е</strong>ктов симулятора.<br />

^ з ь м и в руку карандаш<br />

М<strong>е</strong>тоЭ Go() долж<strong>е</strong>н<br />

для каждой пч<strong>е</strong>лы и каждого<br />

цв<strong>е</strong>тка, инач<strong>е</strong> симулят ор<br />

п<strong>е</strong>р<strong>е</strong>ст ан<strong>е</strong>т paSomamt^.<br />

При постро<strong>е</strong>нии сим улятора буд<strong>е</strong>т использован один из основны х<br />

принципов объ <strong>е</strong>ктно-ори<strong>е</strong>нтированного програм м ирования — и нкапсуляция.<br />

П рив<strong>е</strong>дит<strong>е</strong> по два прим <strong>е</strong>ра инкапсуляции для каж дого из<br />

созданны х нами классов.<br />

Н і ^ В<strong>е</strong><strong>е</strong> Flower<br />

1. 1 . 1 .<br />

2. 2. 2.<br />

д а л ь ш <strong>е</strong> * 545


в а ш <strong>е</strong> м <strong>е</strong> с т о в м и р <strong>е</strong><br />

Код для класса l/1/orld<br />

К л а с с W o r ld — о д и н и з с ам ы х п р о с т ы х в н а ш <strong>е</strong> м с и м у л я т о ­<br />

р <strong>е</strong> . В о т о т п р а в н а я т о ч к а для н а п и с а н и я ко д а . Е с л и п р и с м о ­<br />

т р <strong>е</strong> т ь с я , вы у в и д и т <strong>е</strong> о т с у т с т в и <strong>е</strong> о тд <strong>е</strong> л ь н ы х ф р а гм <strong>е</strong> н т о в , к о ­<br />

т о р ы <strong>е</strong> м ы с о в с <strong>е</strong>м с к о р о д о б ав и м .<br />

u s i n g S y s t e m . D r a w i n g ;<br />

c l a s s W o r l d {<br />

p r i v a t e c o n s t d o u b l e N e c t a r H a r v e s t e d P e r N e w F l o w e r = 50.0;<br />

p r i v a t e c o n s t int F i e l d M i n X =15;<br />

p r i v a t e c o n s t int F i e l d M i n Y = m ■. i KoopduHamfi,<br />

опр<strong>е</strong>д<strong>е</strong>ляющи<strong>е</strong> границы<br />

p r i v a t e c o n s t int F i e l d M a x X = 690<br />

цв<strong>е</strong>точного поля.<br />

p r i v a t e c o n s t int F i e l d M a x Y = 2 90<br />

Пробл<strong>е</strong>мы с инкапсуляци<strong>е</strong>й!<br />

Обратит<strong>е</strong> внимани<strong>е</strong> на открыты<strong>е</strong><br />

поля Hive, Bees и Flowers. Другой<br />

класс мож<strong>е</strong>т случайно присвоить им<br />

знач<strong>е</strong>ни<strong>е</strong> null, что стан<strong>е</strong>т причиной<br />

с<strong>е</strong>рь<strong>е</strong>зных пробл<strong>е</strong>м! Подумайт<strong>е</strong>, какими<br />

свойствами и м<strong>е</strong>тодами можно<br />

воспользоваться для инкапсуляции.<br />

p u b l i c H i v e Hive;<br />

p u b l i c L i s t < B e e > B e es;<br />

p u b l i c L i s t < F l o w e r > F l o w e r s ;<br />

в м и р <strong>е</strong> сущ <strong>е</strong>ст ву<strong>е</strong>т<br />

вс<strong>е</strong>го один ул<strong>е</strong>й,<br />

/^лнож<strong>е</strong>ство пч<strong>е</strong>л<br />

и цв<strong>е</strong>тков.<br />

p u b l i c W o r l d 0 {<br />

B e e s = n e w L i s t < B e e > ( ) ;<br />

F l o w e r s = n e w L i s t < F l o w e r > ()<br />

R a n d o m r a n d o m = n e w R a n d o m ()<br />

f o r (int i = 0 ; i < 10; i++)<br />

A d d F l o w e r ( r a n d o m ) ;<br />

}<br />

ф о р т р у я новый м ир, мы<br />

. созда<strong>е</strong>м ул<strong>е</strong>м м добавля<strong>е</strong>м<br />

%0 цв<strong>е</strong>тков.<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m ) { Зд<strong>е</strong>сь мы прост о вызывав,л л . .<br />

H i v e . G o (random) ; < ----- - п<strong>е</strong>р<strong>е</strong>давая <strong>е</strong>му e-My экз<strong>е</strong>мпляр Random.<br />

f o r (int і = B e e s . C o u n t -<br />

B e e b e e = B e e s [ i ] ;<br />

b e e .G o ( r a n d o m ) ;<br />

if ( b e e . C u r r e n t s t a t e ==<br />

B e e s .R e m o v e ( b e e );<br />

}<br />

i >= 0 ; i--) {<br />

— М<strong>е</strong>т од QoQ} вызыва<strong>е</strong>тся для в<strong>е</strong><strong>е</strong>к<br />

им<strong>е</strong>ющихся в наличии пч<strong>е</strong>л.<br />

B e e s t a t e . R e t i r e d ) „<br />

_______<br />

Выш<strong>е</strong>дыАуьо<br />

■-------------- пч<strong>е</strong>лу нужно удалить<br />

(дз наш<strong>е</strong>го мира.<br />

d o u b l e t o t a l N e c t a r H a r v e s t e d = 0;<br />

f o r (int i = F l o w e r s .C o u n t - 1; i<br />

}<br />

F l o w e r f l o w e r = F l o w e r s [ i ] ;<br />

f l o w e r . G o 0 ;<br />

>= 0 ; І-) {<br />

t o t a l N e c t a r H a r v e s t e d -t-= f l o w e r . N e c t a r H a r v e s t e d ;<br />

if (!f l o w e r . A l i v e )<br />

F l o w e r s .R e m o v e (flower) ;<br />

цв<strong>е</strong>т ы такжр<br />

сл<strong>е</strong>ду<strong>е</strong>т удалить.<br />

Зля „.жЭого<br />

Нужно отсл<strong>е</strong>живать<br />

колич<strong>е</strong>ство н<strong>е</strong>ктара,<br />

-собранно<strong>е</strong> на каждом<br />

этап<strong>е</strong>. Поэт ому мы<br />

сум м иру<strong>е</strong>м н<strong>е</strong>кт ар,<br />

собранный с каждого<br />

цв<strong>е</strong>тка.<br />

546 гл а в а 12


^ з ь м и в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот т<strong>е</strong>. кот оры<strong>е</strong> пришли<br />

4 м 8 голову. У вас <strong>е</strong>ст ь<br />

други<strong>е</strong> варианты?<br />

Hive<br />

о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

При написании сим улятора использовался один из основны х принципов<br />

о бъ <strong>е</strong>ктно-ори<strong>е</strong>нтированного програм м ирования, инкапсуляция.<br />

Вот прим<strong>е</strong>ры инкапсуляции для каж дого из созданны х нам и классов.<br />

В<strong>е</strong><strong>е</strong><br />

Flowe_r<br />

1. Закры т словарь<br />

Locations.<br />

2. Эт о да<strong>е</strong>т пч<strong>е</strong>лам<br />

м <strong>е</strong>т од добавл<strong>е</strong>ния<br />

м<strong>е</strong>да.<br />

1. Полож<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>лы в п р о ­<br />

ст ранст в<strong>е</strong> явля<strong>е</strong>тся свойст<br />

вом только для чт<strong>е</strong>ния.<br />

2. Аналогично с <strong>е</strong><strong>е</strong> возрастом.<br />

Эт и свойства н<strong>е</strong>льзя<br />

пом<strong>е</strong>нят ь из другого класса.<br />

1. Э т от класс об<strong>е</strong>сп<strong>е</strong>чива<strong>е</strong>т<br />

м<strong>е</strong>т од сбора н <strong>е</strong>­<br />

ктара.<br />

2. Логич<strong>е</strong>ско<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

alive явля<strong>е</strong>тся закры ­<br />

тым.<br />

j<br />

if ( t o t a l N e c t a r H a r v e s t e d > N e c t a r H a r v e s t e d P e r N e w F l o w e r ) {<br />

f o r e a c h ( F l o w e r f l o w e r in P o w e r s )<br />

}<br />

пч<strong>е</strong>лы<br />

f l o w e r . N e c t a r H a r v e s t e d = 0; ^ R н л ш <strong>е</strong> М М м » <strong>е</strong><br />

опыляют цв<strong>е</strong>ты. В<br />

A d d F l o w e r ( r a n d o m ) ;<br />

^<br />

счит а<strong>е</strong>т ся, что собрав дост а­<br />

точно<strong>е</strong> колич<strong>е</strong>ство н<strong>е</strong>кт ара,<br />

7 При дост ат очном колич<strong>е</strong>ств<strong>е</strong> пч<strong>е</strong>лы инициируют появл<strong>е</strong>ни<strong>е</strong><br />

н<strong>е</strong>кт ара на пол<strong>е</strong> появля<strong>е</strong>мся нооыи<br />

цв<strong>е</strong>ток.<br />

нового цв<strong>е</strong>тка.<br />

p r i v a t e v o i d A d d F l o w e r ( R a n d o m r a ndom)<br />

P o i n t l o c a t i o n = n e w P o i n t ( r a n d o m . N e x t ( F i e l d M i n X , F i e l d M a x X ) ,<br />

r a n d o m . N e x t ( F i e l d M i n Y , F i e l d M a x Y ) );<br />

F l o w e r n e w F l o w e r = n e w F l o w e r ( l o c a t i o n , r a n d o m ) ;<br />

F l o w e r s .Add ( n e wFlower) ;<br />

п^ш бот чик выбира<strong>е</strong>т полож<strong>е</strong>ни<strong>е</strong><br />

на пол<strong>е</strong> по слуил^ному принципу...<br />

..и пом <strong>е</strong>щ а<strong>е</strong>т т уда<br />

новый цв<strong>е</strong>ток.<br />

Поч<strong>е</strong>му бы н<strong>е</strong> воспользоваться<br />

циклом foreach для удал<strong>е</strong>ния увядших<br />

цв<strong>е</strong>тов и отслуживших пч<strong>е</strong>л?<br />

Q ; Потому что удалить эл<strong>е</strong>м<strong>е</strong>нт колл<strong>е</strong>кции<br />

изнутри просматривающ<strong>е</strong>го <strong>е</strong><strong>е</strong> цикла<br />

foreach н<strong>е</strong>возможно. Попытка сд<strong>е</strong>лать<br />

это прив<strong>е</strong>д<strong>е</strong>т к появл<strong>е</strong>нию исключ<strong>е</strong>ния.<br />

_ Ч а с з » °<br />

------- ^ а Д а Б а <strong>е</strong> М ы <strong>е</strong> ------<br />

B o r tp o ^ jjl<br />

А поч<strong>е</strong>му циклы f o r считать<br />

от конца списка к началу?<br />

^ ; Цикл н<strong>е</strong> долж<strong>е</strong>н нарушать нум<strong>е</strong>рацию.<br />

Пр<strong>е</strong>дположим, мы начали<br />

просматривать с начала список из пяти<br />

цв<strong>е</strong>тов, и оказалось, что один из них увял.<br />

Удалив цв<strong>е</strong>ток с инд<strong>е</strong>ксом, наприм<strong>е</strong>р #3,<br />

вы получит<strong>е</strong> список из ч<strong>е</strong>тыр<strong>е</strong>х пунктов,<br />

новый цв<strong>е</strong>ток, который буд<strong>е</strong>т записан<br />

под инд<strong>е</strong>ксом #3, в сл<strong>е</strong>дующий раз буд<strong>е</strong>т<br />

пропускаться, так как цикл п<strong>е</strong>р<strong>е</strong>скочит на<br />

инд<strong>е</strong>кс #4.<br />

Начав ж<strong>е</strong> просмотр с конца, вы никогда<br />

н<strong>е</strong> пропустит<strong>е</strong> цв<strong>е</strong>ток, пом<strong>е</strong>щ<strong>е</strong>нного на<br />

освободивш<strong>е</strong><strong>е</strong>ся м<strong>е</strong>сто.<br />

д а л ь ш <strong>е</strong> ► 547


с о <strong>е</strong> д и н и м в с <strong>е</strong> в м <strong>е</strong> с т <strong>е</strong><br />

ажн<strong>е</strong>ни<strong>е</strong><br />

В с <strong>е</strong> ч <strong>е</strong> т ы р <strong>е</strong> к л а с с а н а п и с а н ы , т <strong>е</strong> п <strong>е</strong> р ь и х н у ж н о с о <strong>е</strong> д и н и т ь . С л <strong>е</strong> д у й т <strong>е</strong><br />

д а н н о й н и ж <strong>е</strong> и н с т р у к ц и и . П о м н и т <strong>е</strong> , ч т о в а м п р и д <strong>е</strong> т с я в н <strong>е</strong> с т и<br />

и з м <strong>е</strong> н <strong>е</strong> н и я п р а к т и ч <strong>е</strong> с к и в к а ж д ы й к л а с с .<br />

Обновит<strong>е</strong> класс в <strong>е</strong> <strong>е</strong> .<br />

Пч<strong>е</strong>лы должны узнать о сущ<strong>е</strong>ствовании улья и вн<strong>е</strong>шн<strong>е</strong>го мира. Пом<strong>е</strong>стит<strong>е</strong> в конструктор<br />

класса В<strong>е</strong><strong>е</strong> в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тров ссылки на ул<strong>е</strong>й и мир и сохранит<strong>е</strong> их<br />

для дальн<strong>е</strong>йш<strong>е</strong>го использования.<br />

О<br />

О<br />

Обновит<strong>е</strong> класс H iv e .<br />

Пч<strong>е</strong>лы должны знать, что ул<strong>е</strong>й сущ<strong>е</strong>ству<strong>е</strong>т, ул<strong>е</strong>й ж<strong>е</strong> долж<strong>е</strong>н знать о сущ<strong>е</strong>ствовании<br />

вн<strong>е</strong>шн<strong>е</strong>го мира. Пом<strong>е</strong>стит<strong>е</strong> в конструктор класса H i v e ссылку на объ<strong>е</strong>кт<br />

W o r l d и сохранит<strong>е</strong> <strong>е</strong><strong>е</strong>. Обновит<strong>е</strong> код создания новых пч<strong>е</strong>л, п<strong>е</strong>р<strong>е</strong>дав в н<strong>е</strong>го<br />

ссылки на ул<strong>е</strong>й и на мир.<br />

Обновит<strong>е</strong> класс W o rld .<br />

Обновит<strong>е</strong> класс w o r l d таким образом, чтобы при создании нового<br />

улья <strong>е</strong>му п<strong>е</strong>р<strong>е</strong>давалась ссылка на мир.<br />

Л<br />

STOP<br />

г<br />

СТОП! На данный мом<strong>е</strong>нт код уж<strong>е</strong> долж<strong>е</strong>н<br />

компилироваться. Если этого н<strong>е</strong> происходит,<br />

поищит<strong>е</strong> ошибки.<br />

Вн<strong>е</strong>сит<strong>е</strong> огранич<strong>е</strong>ни<strong>е</strong> на создани<strong>е</strong> пч<strong>е</strong>л.<br />

В класс<strong>е</strong> H i v e <strong>е</strong>сть константа M a x i m u m B e e s , указывающая,<br />

сколько пч<strong>е</strong>л в состоянии подд<strong>е</strong>рживать ул<strong>е</strong>й (счита<strong>е</strong>тся колич<strong>е</strong><br />

ство нас<strong>е</strong>комых внутри и снаружи). Т<strong>е</strong>п<strong>е</strong>рь, когда объ<strong>е</strong>кт H i v e<br />

им<strong>е</strong><strong>е</strong>т доступ к объ<strong>е</strong>кту World, огранич<strong>е</strong>ни<strong>е</strong> можно усилить.<br />

< -<br />

Подсказка: Обрат ит <strong>е</strong><br />

М ир долж<strong>е</strong>н знать о создании новых пч<strong>е</strong>л.<br />

Класс W o r l d использу<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> L i s t для сл<strong>е</strong>ж<strong>е</strong>ния за<br />

им<strong>е</strong>ющимися пч<strong>е</strong>лами. Уб<strong>е</strong>дит<strong>е</strong>сь, что новы<strong>е</strong> пч<strong>е</strong>лы попадают<br />

в список, состояни<strong>е</strong> которого отсл<strong>е</strong>жива<strong>е</strong>тся объ<strong>е</strong>ктом World.<br />

■«=— ><br />

548 гл а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

ча


ажн<strong>е</strong>ни<strong>е</strong><br />

J'^ e m e n n e<br />

Зд<strong>е</strong>сь вы увидит<strong>е</strong>, каким ж<strong>е</strong> способом наши ч<strong>е</strong>тыр<strong>е</strong> класса со<strong>е</strong>диняются друг с другом.<br />

Обновл<strong>е</strong>ни<strong>е</strong> класса в <strong>е</strong> <strong>е</strong><br />

П ч <strong>е</strong> л ы д о л ж н ы у з н а т ь о с у щ <strong>е</strong> с т в о в а н и и у л ь я и в н <strong>е</strong> ш н <strong>е</strong> г о м и р а . П о ­<br />

м <strong>е</strong> с т и т <strong>е</strong> в к о н с т р у к т о р к л а с с а В <strong>е</strong> <strong>е</strong> в к а ч <strong>е</strong> с т в <strong>е</strong> п а р а м <strong>е</strong> т р о в с с ы л ки н а<br />

у л <strong>е</strong> й и м и р и с о х р а н и т <strong>е</strong> и х д л я д а л ь н <strong>е</strong> й ш <strong>е</strong> г о и с п о л ь з о в а н и я .<br />

c l a s s В <strong>е</strong> <strong>е</strong> {<br />

// о б ъ я в л <strong>е</strong> н и <strong>е</strong> к о н с т а н т<br />

// о б ъ я в л <strong>е</strong> н и <strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы х<br />

p r i v a t e W o rld w o r ld ;<br />

p r i v a t e H iv e h i v e ;<br />

p u b l i c B e e ( i n t ID, P o i n t I n i t i a l L o c a t i o n , W o rld w o r ld . H iv e h i v e ) {<br />

// к о д<br />

t h i s . w o r l d e w o r ld ;<br />

t h i s . h i v e * h i v e ;<br />

Это вполн<strong>е</strong> оч<strong>е</strong>видно.,■<br />

присвойт <strong>е</strong> эт и знач<strong>е</strong>ния<br />

закрыт ым п о л я м .<br />

О Обновл<strong>е</strong>ни<strong>е</strong> класса Hive<br />

П ч <strong>е</strong> л ы д о л ж н ы з н а т ь , ч т о с у щ <strong>е</strong> с т в у <strong>е</strong> т у л <strong>е</strong> й , у л <strong>е</strong> й ж <strong>е</strong> д о л ж <strong>е</strong> н з н а т ь<br />

о с у щ <strong>е</strong> с т в о в а н и и в н <strong>е</strong> ш н <strong>е</strong> г о м и р а . П о м <strong>е</strong> с т и т <strong>е</strong> в к о н с т р у к т о р к л а с с а<br />

H i v e с с ы л к у н а о б ъ <strong>е</strong> к т w o r l d и с о х р а н и т <strong>е</strong> <strong>е</strong> <strong>е</strong> . О б н о в и т <strong>е</strong> ко д с о з д а ­<br />

н и я н о в ы х п ч <strong>е</strong> л , п <strong>е</strong> р <strong>е</strong> д а в в н <strong>е</strong> го с с ы л к у н а у л <strong>е</strong> й и н а м и р .<br />

c l a s s H i v e {<br />

p r i v a t e W o rld w o r ld ;<br />

p u b l i c H i v e (W orld w o r ld )<br />

t h i s .w o r ld e w o r ld ;<br />

11 к о д<br />

}<br />

p u b l i c v o i d A d d B e e (R a n d o m r a n dom)<br />

}<br />

// к о д с о з д а н и я н о в ы х п ч <strong>е</strong> л<br />

Ссылка на м ир дап<strong>е</strong>рвой,<br />

т ак<br />

как она использив<br />

остальной<br />

части Конст риктора.<br />

B e e n e w B e e = n e w B e e ( b e e C o u n t , S t a r t P o i n t , w o r ld , t h i s )<br />

{<br />

550 г л а в а 12


Если у вас н<strong>е</strong> получа<strong>е</strong>тся написать<br />

)аботаюпщй код, скачайт<strong>е</strong> готовую в<strong>е</strong>рсию с сайта:<br />

1Нр://\¥т<strong>е</strong>.Ь<strong>е</strong>аёПг811аЬ8.сот/Ьоок8/ЬГс8Ьагр/<br />

<strong>е</strong><br />

О гранич<strong>е</strong>ни<strong>е</strong> на создани<strong>е</strong> пч<strong>е</strong>л<br />

В к л а с с <strong>е</strong> H i v e <strong>е</strong> с т ь к о н с т а н т а M a x i m u m B e e s , у к а з ы в а ю щ а я , с к о л ь ­<br />

ко п ч <strong>е</strong> л в с о с т о я н и и п о д д <strong>е</strong> р ж и в а т ь у л <strong>е</strong> й (у ч и т ы в а <strong>е</strong> т с я к о л и ч <strong>е</strong> с т в о<br />

н а с <strong>е</strong> к о м ы х в н у т р и и с н а р у ж и ). Т <strong>е</strong> п <strong>е</strong> р ь , ко гд а о б ъ <strong>е</strong> к т H i v e и м <strong>е</strong> <strong>е</strong> т<br />

д о с т у п к о б ъ <strong>е</strong> к т у World, о г р а н и ч <strong>е</strong> н и <strong>е</strong> м о ж н о у с и л и т ь . О бъ<strong>е</strong>кт W orld позво<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m ) {<br />

)<br />

пч<strong>е</strong>л и<br />

СрйОНЦИлЬ <strong>е</strong>го г ААґЧґп,<br />

& & H o n e y > M i n i m u m H o n e y F o r C r e a t i n g B e e s м алш о возможтш для<br />

ScSc r a n d o m .N e x t {10) == 1) { ^ ^лнного улья.<br />

if ( w o r l d .B e e s .Cotuat < M a x i m i m B e e s<br />

A d d B e e ( r a n d o m ) ; |<br />

) ‘р о вн<strong>е</strong>н ш<br />

М ир долж<strong>е</strong>н знать о создании новых пч<strong>е</strong>л<br />

К л а с с W o r l d и с п о л ь з у <strong>е</strong> т п <strong>е</strong> р <strong>е</strong> ч и с л <strong>е</strong> н и <strong>е</strong> L i s t д л я с л <strong>е</strong> ж <strong>е</strong> н и я з а и м <strong>е</strong> ­<br />

ю щ и м и с я п ч <strong>е</strong> л а м и . У б <strong>е</strong> д и т <strong>е</strong> с ь , ч т о н о в ы <strong>е</strong> п ч <strong>е</strong> л ы п о п а д а ю т в с п и с о к ,<br />

с о с т о я н и <strong>е</strong> к о т о р о го о т с л <strong>е</strong> ж и в а <strong>е</strong> т с я о б ъ <strong>е</strong> к т о м World.<br />

О<br />

p r i v a t e v o i d A d d B e e ( R a n d o m r a n d o m ) {<br />

^<br />

b e e C o u n t ++;<br />

// C a l c u l a t e t h e s t a r t i n g p o i n t<br />

P o i n t S t a r t P o i n t = 1 1 s t a r t t h e n e a r t h e n u r s e r y<br />

B e e n e w B e e = n e w B e e ( b e e C o u n t , S t a r t P o i n t , w o r l d , t h i s ) ;<br />

w o r l d . B e e s . Add (n e w B ee) ,•<br />

Ч т о одна ооп(л из WO причин .....<br />

н<strong>е</strong>обходит ст и ссылки ня<br />

Добавля<strong>е</strong>тся новая пч<strong>е</strong>ла. Х <strong>е</strong> к ~ W o r U 6 класс<strong>е</strong> H ive.<br />

Обновл<strong>е</strong>ни<strong>е</strong> класса w o rld .<br />

О б н о в и т <strong>е</strong> к л а с с w o r l d т а к и м о б р а з о м , ч то б ы п р и с о з ­<br />

д а н и и н о в о го у л ь я <strong>е</strong> м у п <strong>е</strong> р <strong>е</strong> д а в а л а с ь с с ы л к а н а м и р .<br />

p u b l i c W o r l d 0 {<br />

B e e s = n e w L i s t < B e e > ( ) ;<br />

F l o w e r s = n e w L i s t < F l o w e r > ()<br />

H iv e a n ew H i v e ( t h i s ) ;<br />

R a n d o m r a n d o m = n e w R a n d o m ();<br />

f o r (int i = 0 ; i < 10; i++)<br />

A d d F l o w e r ( r a n d o m ) ;<br />

Зд<strong>е</strong>сь п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся ссылка<br />

на объ<strong>е</strong>кт H ive.<br />

д а л ь ш <strong>е</strong> > 551


п у с т ь п ч <strong>е</strong> л ы в <strong>е</strong> д у т с <strong>е</strong> б я п р и л и ч н о<br />

Поб<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>л<br />

у нас отсутству<strong>е</strong>т м <strong>е</strong> тод G o () объ<strong>е</strong>кта В<strong>е</strong><strong>е</strong>. М ы н ачали<br />

писать код для н <strong>е</strong> к о т о р ы х состояний, н о м н о г о <strong>е</strong> осталось<br />

н <strong>е</strong> з а к о н ч <strong>е</strong> н ы м (Idle, F l y i n g T o F l o w e r и частично<br />

MakingHoney).<br />

П р и ш л о в р <strong>е</strong> м я заполнить проб<strong>е</strong>лы:<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m ) {<br />

A g e + + ;<br />

s w i t c h ( C u r r e n t s t a t e ) {<br />

c a s e B e e s t a t e . I d l e :<br />

Если вс<strong>е</strong> условия<br />

соблюд<strong>е</strong>ны, пч<strong>е</strong>ла<br />

л<strong>е</strong>т ит на новый і<br />

цв<strong>е</strong>ток. }<br />

По этой причин<strong>е</strong><br />

мы п<strong>е</strong>р<strong>е</strong>дали “<br />

ссылку на ул<strong>е</strong>й<br />

конст рукт ору<br />

класса В<strong>е</strong><strong>е</strong>.<br />

if (Age > C a r e e r S p a n ) {<br />

состояния б<strong>е</strong>з<br />

И З<br />

Э <strong>е</strong> м с т б и я п ч <strong>е</strong> л а<br />

в состояни<strong>е</strong> поиска<br />

ц б <strong>е</strong> т к й с н <strong>е</strong> к т а р о м .<br />

Если остались цв<strong>е</strong>ты с н<strong>е</strong>собранным<br />

н<strong>е</strong>кт аром и пч<strong>е</strong>ла<br />

собира<strong>е</strong>т нужно<strong>е</strong> для жизн<strong>е</strong>д<strong>е</strong>ят<strong>е</strong>льности<br />

колич<strong>е</strong>ство<br />

м<strong>е</strong>да. В прот ивном случа<strong>е</strong><br />

п ч <strong>е</strong> м ост а<strong>е</strong>т ся в состоянии<br />

д<strong>е</strong>зд<strong>е</strong>йск\лвия.<br />

C u r r e n t s t a t e = B e e s t a t e . R e t i r e d<br />

Н у ж <strong>е</strong> н другой<br />

} e l s e i f ( w o r ld .F lo w e r s .C o u n t > 0 xudow живой цoemc цв<strong>е</strong>ток<br />

&& h i v e . C on su m eH on ey (H o n e y C o n su m e d )) { g:::: i c HCKmapoM-<br />

F lo w e r f l o w e r =<br />

J<br />

}<br />

b r e a k ;<br />

w o r l d .F l o w e r s [ r a n d o m .N e x t ( w o r l d .F l o w e r s . C o u n t ) ] ;<br />

i f ( f l o w e r . N e c t a r >= M in im u m F lo w e r N e c ta r && f l o w e r . A l i v e ) {<br />

d e s t i n a t i o n F l o w e r = f l o w e r ;<br />

C u r r e n t s t a t e = B e e s t a t e . F l y i n g T o F l o w e r ;<br />

c a s e B e e s t a t e .F l y i n g T o F l o w e r :<br />

i f ( ! w o r l d . F l o w e r s . C o n t a i n s ( d e s t i n a t i o n F l o w e r ) ) <<br />

C u r r e n t s t a t e = B e e s t a t e .R e t u r n i n g T o H i v e ;<br />

e l s e i f ( I n s i d e H i v e ) {<br />

i f<br />

( M o v e T o w a r d s L o c a t i o n ( h iv e .G e t L o c a t io n ( " E x i t<br />

I n s i d e H i v e = f a l s e ;<br />

l o c a t i o n = h i v e . G e t L o c a t i o n ( " E n t r a n c e " ) ;<br />

Уб<strong>е</strong>дит<strong>е</strong>сь, что за то<br />

вр<strong>е</strong>мя, пока пч<strong>е</strong>ла л <strong>е</strong>­<br />

т ит к цв<strong>е</strong>т ку, цв<strong>е</strong>ток<br />

н<strong>е</strong> завян<strong>е</strong>т.<br />

' ) ) ) {<br />

Если пч<strong>е</strong>ла добралась до выхода, она мож <strong>е</strong>т покинут ь<br />

ул<strong>е</strong>й. Обновит<strong>е</strong> <strong>е</strong><strong>е</strong> полож<strong>е</strong>ни<strong>е</strong>. С поля ж<strong>е</strong> она буд<strong>е</strong>т<br />

л<strong>е</strong>т <strong>е</strong>т ь в ст орону входа.<br />

( M o v e T o w a r d s L o c a t i o n ( d e s t i n a t io n F l o w e r . L o c a t i o n ) )<br />

C u r r e n t s t a t e = B e e s t a t e . G a t h e r i n g N e c t a r ;<br />

b r e a k ;<br />

Если пч<strong>е</strong>ла<br />

c a s e B e e s t a t e .G a t h e r i n g N e c t a r :<br />

выл<strong>е</strong>т<strong>е</strong>ла из<br />

улья, а цв<strong>е</strong>ток<br />

d o u b l e n e c t a r = d e s t i n a t i o n F l o w e r . H a r v e s t N e c t a r ();<br />

^ 0)<br />

собирать с н<strong>е</strong>го<br />

N e c t a r C o l l e c t e d += n e c t a r ;<br />

н<strong>е</strong>ктар..<br />

e l s e<br />

C u r r e n t s t a t e = B e e s t a t e . R e t u r n i n g T o H i v e ;<br />

b r e a k ;<br />

552 гл а в а 12


Эт о выход. Когда ул<strong>е</strong>й с о ­<br />

храня<strong>е</strong>м. полож<strong>е</strong>ни<strong>е</strong> E xitj эм о<br />

соот в<strong>е</strong>т ст ву<strong>е</strong>т точк<strong>е</strong> на<br />

ф орм <strong>е</strong> обь<strong>е</strong>кт а HiVe^ в к о т о ­<br />

рой располага<strong>е</strong>т ся картинка<br />

с изображ<strong>е</strong>ни<strong>е</strong>м выхода.<br />

\<br />

c a s e B e e s t a t e .R e t u r n i n g T o H i v e :<br />

i<br />

Поэтому в словар<strong>е</strong> location<br />

^панятся два отд<strong>е</strong>льных<br />

Е Г Г л о ж <strong>е</strong> и » » E x it .<br />

о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Эт о вход. В о з в р а щ а я с !^ ^<br />

в ул<strong>е</strong>й,, пч<strong>е</strong>лы л<strong>е</strong>т ят<br />

по направл<strong>е</strong>нию<br />

к входу на ф орм <strong>е</strong><br />

обь<strong>е</strong>кт а field.<br />

if (!I n s i d e H i v e ) {<br />

i f ( M o v e T o w a r d s L o c a t i o n ( h iv e .G e t L o c a t io n ( " E n t r a n c e " ) ) ) {<br />

}<br />

e l s e<br />

}<br />

b r e a k ;<br />

I n s i d e H i v e = t r u e ;<br />

l o c a t i o n = h i v e . G e t L o c a t i o n ( " E x i t " )<br />

в случа<strong>е</strong> проникнов<strong>е</strong>ния<br />

в ул<strong>е</strong>й обновит<strong>е</strong> п олож<strong>е</strong>ни<strong>е</strong><br />

и ст ат ус п <strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

insideHtSl'e.<br />

i f ( M o v e T o w a r d s L o c a t io n ( h iv e .G e t L o c a t io n ( " H o n e y F a c t o r y " ) ) )<br />

C u r r e n t s t a t e = B e e S ta t e .M a k in g H o n e y ;<br />

c a s e B e e S t a t e . M a k i n g H o n e y :<br />

if { N e c t a r C o l l e c t e d


п р о д о л ж а <strong>е</strong> м с о з д а в а т ь н а ш м и р<br />

Оснобная форма<br />

К а к вы з н а <strong>е</strong> т <strong>е</strong> п р и к а ж д о м вы зо в<strong>е</strong> м <strong>е</strong> т о д а О о () вс<strong>е</strong> о б ъ <strong>е</strong> кты<br />

н а ш <strong>е</strong> г о м и р а с л <strong>е</strong> гк а м <strong>е</strong> н я ю т с я . Н о к а к вы зв ать э т о т м <strong>е</strong>тод?<br />

Р а з у м <strong>е</strong> <strong>е</strong> тс я , п р и п о м о ш ;и ф о р м ы ! П р и ш л о в р <strong>е</strong> м я за н я т ь с я <strong>е</strong><strong>е</strong><br />

п о с т р о <strong>е</strong> н и <strong>е</strong> м .<br />

Д о б а в ь т <strong>е</strong> ф о р м у к п р о <strong>е</strong> к т у и п р и д а й т <strong>е</strong> <strong>е</strong> й п о к а з а н н ы й н и ж <strong>е</strong><br />

в ид . О н а с о д <strong>е</strong> р ж и т н о в ы <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н ты у п р а в л <strong>е</strong> н и я , н а з н а ч <strong>е</strong> н и <strong>е</strong><br />

к о т о р ы х буд<strong>е</strong>т р а с с м о т р <strong>е</strong> н о н а с л <strong>е</strong> д у ю щ и х с т р а н и ц а х .<br />

М <strong>е</strong>т ки 6 правом ст олбц<strong>е</strong> будит<br />

от ображ ат ь ст а т и ст и ку.<br />

П рисвойт <strong>е</strong> им им<strong>е</strong>на B e e s,'<br />

Flowers, Honey InHiVe и т . п.<br />

Э л<strong>е</strong>м <strong>е</strong>нт ToolStrip п о ­<br />

м <strong>е</strong>щ а <strong>е</strong>т в в<strong>е</strong>рхню ю<br />

част ь ф орм ы пан<strong>е</strong>ль<br />

инст рум <strong>е</strong>нт ов. В оспользуй<br />

т <strong>е</strong>сь раскр ы ­<br />

ваю щ им ся списком<br />

эл<strong>е</strong>м <strong>е</strong>н т а в конст рук<br />

т ор<strong>е</strong> и добавьт<strong>е</strong> дв<strong>е</strong><br />

кнопки. П рисвойт <strong>е</strong> па<br />

р а м <strong>е</strong> т р у P isplayStyle<br />

кнопок знач<strong>е</strong>ни<strong>е</strong> T e x t<br />

Forml.cs [Design]<br />

^ ieehwe Simulator f “s<br />

Start Simulation Reset<br />

.# Bees —-j gggj —<br />

:^A.itavW9l&.....Howws<br />

Tsstal honey n the twe | Hon^hHve "<br />

Tdirf'riedarjiJhgS^_| NeaBrtiftewera_^~<br />

Frames rm....... *__ "I FranesRun<br />

fiame rate ........ f Frametoe<br />

П X<br />

Ч/<br />

Каждая из эт и х м <strong>е</strong>т о к<br />

за н и м а <strong>е</strong>т одну яч<strong>е</strong>й -<br />

ку эл<strong>е</strong>м <strong>е</strong>нт а управл<strong>е</strong>ния<br />

TableLayoutPanel. Вы з а ­<br />

полня<strong>е</strong>т <strong>е</strong> <strong>е</strong><strong>е</strong>, как обычную<br />

т аблицу в M icrosoft W ord.<br />

Щ <strong>е</strong>л к н и т<strong>е</strong> на м ал<strong>е</strong>нькой<br />

. ч<strong>е</strong>рной ст р <strong>е</strong>лк<strong>е</strong>, чтобы<br />

добавит ь, удали т ь или<br />

п ом <strong>е</strong>нят ь р азм <strong>е</strong>р ст олбца<br />

или ст роки.<br />

Эл<strong>е</strong>м<strong>е</strong>нт S tatu sS trip<br />

добавля<strong>е</strong>т в н м ж - ^<br />

нюю част ь формы<br />

ст року состояния.<br />

Воспользуйт <strong>е</strong>сь р а с ­<br />

крывающимся сп и ­<br />

ском эт ого эл<strong>е</strong>м <strong>е</strong>нт<br />

а, чтобы добавить<br />

такж<strong>е</strong> StatusLabel.<br />

Simuletion paused<br />

EooiStripl tai statusStripl © timerl<br />

Э л<strong>е</strong>м <strong>е</strong>нт управл<strong>е</strong>ния ToolStrip добавля<strong>е</strong>т пан<strong>е</strong>ль<br />

и н ст р ум <strong>е</strong>нт о в в в<strong>е</strong>рхню ю част ь ф орм ы , а э л <strong>е</strong> ­<br />

м <strong>е</strong> н т S ta tu sS trip — ст року сост ояния в нижнюю.<br />

Но кром <strong>е</strong> эт ого, они появляю т ся в вид<strong>е</strong> значков<br />

под ф орм ой, чтобы дат ь вам дост уп к р <strong>е</strong> д а к т и ­<br />

рованию своих свойств.<br />

[fo re a c h (Flow er flo w e r in F low ers)<br />

flo w e r.G o (ra n d o m );<br />

Добавьт<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт<br />

управл<strong>е</strong>н ия Tim er. Он<br />

н<strong>е</strong> явля<strong>е</strong>т ся визуальны м<br />

поэт ом у появля<strong>е</strong>т ся<br />

снизу от формы.<br />

fo re a c h (Bee b ee in Bees)<br />

b e e .G o {random ) ;<br />

-----f<br />

1% '®pewe«v><br />

h i v e . Go (random) ;<br />

System.Wv<br />

554 г л а в а 12


о б зо р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Получ<strong>е</strong>ни<strong>е</strong> статисти ки<br />

О т р <strong>е</strong> д а к т и р у <strong>е</strong> м д о б а в л <strong>е</strong> н н ы <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н ты у п р а в л <strong>е</strong> н и я . М ы н <strong>е</strong> буд<strong>е</strong>м<br />

п о о ч <strong>е</strong> р <strong>е</strong> д и в ы д <strong>е</strong>л ять к а ж д ы й и з н и х , а в о сп о л ь зу <strong>е</strong>м ся м <strong>е</strong> то д о м ,<br />

о б н о в л я ю щ и м с т а т и с т и к у с и м у л я то р а :<br />

' v<br />

и м <strong>е</strong> н а м <strong>е</strong> ­<br />

т о к 9 олЖ"<br />

кы быть<br />

т <strong>е</strong>м и<br />

ж<strong>е</strong>^ чт о<br />

ц 6 ф о р м <strong>е</strong> .<br />

S<br />

p r i v a t e v o i d U p d a te S ta ts { T im e S p a n f r a m e D u r a tio n ) {<br />

}<br />

Добавьт<strong>е</strong><br />

эт от м<strong>е</strong>т од<br />

в файл Formü-,<br />

B e e s .T e x t = w o r l d . B e e s . C o u n t . T o S t r i n g O ;<br />

F l o w e r s .T e x t = w o r l d . F l o w e r s . C o u n t . T o S t r i n g O ;<br />

большая часть этого<br />

кода получа<strong>е</strong>т данны<strong>е</strong><br />

о м обь<strong>е</strong>км а w orld<br />

к обновля<strong>е</strong>т м<strong>е</strong>тки.<br />

H o n e y ln H iv e . T e x t = S t r i n g . F o r m a t ( " { 0 : f 3 } " , w o r l d .H i v e .H o n e y ) ;<br />

d o u b le n e c t a r = 0 ;<br />

П<strong>е</strong>рвый парам <strong>е</strong>т р<br />

f o r e a c h (F lo w e r f l o w e r i n w o r ld .F lo w e r s )<br />

выводится 8 вид<strong>е</strong> числа<br />

n e c t a r += f l o w e r . N e c t a r ;<br />

б<strong>е</strong>з д<strong>е</strong>сятичной точки,<br />

, , , , зат <strong>е</strong>м посл<strong>е</strong> проб<strong>е</strong>ла<br />

N e c t a r l n F l o w e r s .T e x t = S t r i n g . F o r m a t ("{О: f 3 , n e c t a r ) ;<br />

F ra m e s R u n .T e x t = f r a m e s R u n . T o S t r i n g ( ) ;<br />

d o u b le m i l l i s e c o n d s = f r a m e D u r a t i o n . T o t a l M i l l i s e c o n d s ;<br />

парам <strong>е</strong>т р с одним<br />

Г к Т о ^ ^ м / л <strong>е</strong> Э у ^ т '<br />

i f ( m i l l i s e c o n d s != 0 . 0 ) буквы ms (в скобках).<br />

F r a m e R a te .T e x t = s t r i n g . F o r m a t ( " { 0 : f O } T [ T 7 f l } m s ) " ,<br />

А откуда взялся объ<strong>е</strong>кт W o rld , <strong>е</strong>сл и мы<br />

<strong>е</strong> го <strong>е</strong>щ <strong>е</strong> н<strong>е</strong> создали? И к ч<strong>е</strong>м у вс<strong>е</strong> эти<br />

разговоры о вр<strong>е</strong>м <strong>е</strong>ни и кадрах?<br />

1 0 0 0 / m i l l i s e c o n d s , m i l l i s e c o n d s ) ;<br />

e l s e _— Част от ой кадров называ<strong>е</strong>тся<br />

F r a m e R a te .T e x t = " N /A " ;<br />

колич<strong>е</strong>ство кадров, показыва<strong>е</strong>мых<br />

за одну с<strong>е</strong>кунду. И н ф о р ­<br />

мация о продолжит<strong>е</strong>льности<br />

одного кадра хранит ся в объ<strong>е</strong>кт<br />

<strong>е</strong> Т/т <strong>е</strong>5рап. Чтобы узнать<br />

част от у, мы д<strong>е</strong>лим 1 -0 0 0 на<br />

колич<strong>е</strong>ство миллис<strong>е</strong>кунд, к о т о ­<br />

ро<strong>е</strong> показыва<strong>е</strong>мся один кадр Д<br />

Сотвор<strong>е</strong>ни<strong>е</strong> М ира<br />

Зд<strong>е</strong>сь вы видит<strong>е</strong> т от Вы правы , нам нужно создать объ<strong>е</strong>кт W o rld . Д обавьт<strong>е</strong><br />

ж <strong>е</strong> самый м<strong>е</strong>т од в конструктор ф орм ы сл<strong>е</strong>дующую строчку:<br />

S tring.Form a tQ J к о ­<br />

т орый использовали p u b l i c F o r m l() {<br />

в ш <strong>е</strong>ст надцат ирич- I n i t i a l i z e C o m p o n e n t O ;<br />

н о м дамп<strong>е</strong>. Но вм<strong>е</strong>ст о , „<br />

вывода информации W o r ld ( ) ;<br />

в xZ, вы указыва<strong>е</strong>т<strong>е</strong> f3 ><br />

и отобража<strong>е</strong>т<strong>е</strong> число „ , ,<br />

с т р<strong>е</strong>мя д<strong>е</strong>сятичными Д обавьт<strong>е</strong> к ф орм <strong>е</strong> закры то<strong>е</strong> пол<strong>е</strong> w o rld .<br />

знакам и.<br />

каса<strong>е</strong>тся кода, связанного со вр<strong>е</strong>м<strong>е</strong>н<strong>е</strong>м... нам<br />

ж <strong>е</strong> тр<strong>е</strong>бовался способ м ногократного вы зова м<strong>е</strong>тода<br />

Go О в класс<strong>е</strong> W o rld ... значит, нам тр<strong>е</strong>бовался тайм <strong>е</strong>р.<br />

Мы поговорим об<br />

эт ом подробн<strong>е</strong><strong>е</strong><br />

в разд<strong>е</strong>л<strong>е</strong>,<br />

посвящ<strong>е</strong>нном<br />

создании}<br />

объ<strong>е</strong>кта<br />

Tim eSpan.<br />

д а л ь ш <strong>е</strong> * 555


п о в т о р н о <strong>е</strong> в о с п р о и з в <strong>е</strong> д <strong>е</strong> н и <strong>е</strong><br />

Тайм<strong>е</strong>ры<br />

Т а к о й п о л <strong>е</strong> з н ы й о б ъ <strong>е</strong> к т к а к т а й м <strong>е</strong> р п о з в о л я <strong>е</strong> т за п у с к а т ь о д н о<br />

и т о ж <strong>е</strong> с о б ы т и <strong>е</strong> с н о в а и с н о в а , ты с я ч у р а з в с<strong>е</strong>кунду.<br />

Создайт<strong>е</strong> новый про<strong>е</strong>кт , чтобы<br />

посм от р<strong>е</strong>т ь, как им<strong>е</strong>нно р а ­<br />

бот аю т тайм<strong>е</strong>ры. З я т <strong>е</strong> м мы<br />

в<strong>е</strong>рн<strong>е</strong>мся к сим улят ору и п р и ­<br />

м<strong>е</strong>ним получ<strong>е</strong>нны<strong>е</strong> знания на<br />

практик<strong>е</strong>.<br />

^^Упр^н<strong>е</strong>ни<strong>е</strong>!<br />

О<br />

Создайт<strong>е</strong> новый про<strong>е</strong>кт<br />

О т к р о й т <strong>е</strong> V is u a l S tu d io и с о з д а й т <strong>е</strong> п р о <strong>е</strong> к т с ф о р м о й . П <strong>е</strong> р <strong>е</strong> т а щ и т <strong>е</strong> н а<br />

н <strong>е</strong> <strong>е</strong> т а й м <strong>е</strong> р и т р и к н о п к и . Щ <strong>е</strong> л к н и т <strong>е</strong> н а т а й м <strong>е</strong> р <strong>е</strong> и п р и с в о й т <strong>е</strong> с в о й ств у<br />

In te r v a l з н а ч <strong>е</strong> н и <strong>е</strong> 1 0 0 0 . И з м <strong>е</strong> р <strong>е</strong> н и я в <strong>е</strong>д утся в м и л л и с <strong>е</strong> ку н д а х , соотв<strong>е</strong>т^<br />

с т в <strong>е</strong> н н о , с о б ы т и <strong>е</strong> буд<strong>е</strong>т за п у с кать с я о д и н р а з в с<strong>е</strong>кунду.<br />

Щ <strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong> E v e n t s в окн<strong>е</strong> Properties<br />

(Н а п о м и н а <strong>е</strong> м , ч т о э т о к н о п к а со з н а ч к о м м о л н и и .) Т а й м <strong>е</strong> р у с о о т в <strong>е</strong> т - „ г ^<br />

с тв у <strong>е</strong> т в с <strong>е</strong> го о д н о с о б ы т и <strong>е</strong> T ic k . Щ <strong>е</strong> л ч к о м в ы д <strong>е</strong> л и т <strong>е</strong> з н а ч о к T i m e r в со^ытий'^можно<br />

к о н с т р у к т о р <strong>е</strong> , з а т <strong>е</strong> м д в а ж д ы щ <strong>е</strong> л к н и т <strong>е</strong> н а с т р о к <strong>е</strong> в о к н <strong>е</strong> Events. Б уд <strong>е</strong> т добавить двойа<br />

в т о м а т и ч <strong>е</strong> с к и с о зд а н о б р а б о т ч и к с о б ы т и й , с в я з а н н ы й со с в о й с тв о м , ным щ<strong>е</strong>лчком<br />

на значк<strong>е</strong> Tim er.<br />

К-но»^кй Events в окн<strong>е</strong><br />

p ro p erties да<strong>е</strong>т дост уп<br />

к событиям, связанным<br />

с выд<strong>е</strong>л<strong>е</strong>нным эл<strong>е</strong>м<strong>е</strong>нт ом<br />

управл<strong>е</strong>ния.<br />

Описани<strong>е</strong> события<br />

находится в нижн<strong>е</strong>й<br />

части окна.<br />

О<br />

Л<br />

Properties<br />

-iis^dl^^stenn.Wtndows.Forms.Timer<br />

Гкк<br />

Occurs whenever the specified inter^'al time<br />

elapses.<br />

- п X<br />

Код для события T i c k и кнопок<br />

В о т к о д , к о т о р ы й п о з в о л и т п о н я т ь п р и н ц и п р а б о т ы т а й м <strong>е</strong> р а :<br />

private void timerl_Tick(object sender, EventArgs e) {<br />

Эти кнопки no Console.WriteLine(DateTime.Now.ToString())<br />

звоАяют вам n } -<br />

играт ь CO с в о й ^ '^ ^ ^ ^ '^ ^ toggleEnabled_Click(object sender, EventArgs e) {<br />

ст вом Enabled и if (timerl.Enabled)<br />

м<strong>е</strong>тодами S ta r tQ<br />

и StopQ. П<strong>е</strong>рвая<br />

timerl .Enabled = false;-, й с и j<br />

Cooucmoo Enabled запуска<strong>е</strong>т<br />

м<strong>е</strong>ня<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

свойства Enabled timerl.Enabled = true;<br />

останавлива<strong>е</strong>т тайм<strong>е</strong>р,<br />

с tru e на false и T<br />

наоборот, дв<strong>е</strong> private void startTimer_Click(object sender, EventArgs e){<br />

остальны<strong>е</strong> вы - timerl.Start () ; ^ ------------ ----— ---- _<br />

S tartQ и StopQ<br />

Console.WriteLine("Enabled = " + timerl.Enabled)<br />

}<br />

private void stopTimer_Click(object sender, EventArgs e)<br />

timerl .Stop 0 ; -------------- ----------------<br />

Console.WriteLine("Enabled = " + timerl.Enabled);<br />

С эл<strong>е</strong>м<strong>е</strong>нт ом управл<strong>е</strong>ния<br />

Ъ т <strong>е</strong> г связано c o L m u e<br />

Т'ск.^Двойной щ<strong>е</strong>лчок н а<br />

этой ст рочк<strong>е</strong> приводит<br />

с о ^ Ь ! ^ ^ ^


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Тайм<strong>е</strong>|>ы используют обработчики событий<br />

К а к и м о б р а з о м т а й м <strong>е</strong> р у зн а <strong>е</strong> т, ч т о д <strong>е</strong>л ать в к а ж д о <strong>е</strong> м гн о в <strong>е</strong> н и <strong>е</strong> ?<br />

П о ч <strong>е</strong> м у м <strong>е</strong> т о д t i m e r l _ T i c k () за п у с к а <strong>е</strong> т с я п р и к а ж д о м о т с ч <strong>е</strong> т <strong>е</strong><br />

т а й м <strong>е</strong> р а ? Т у т м ы в о зв р а щ а <strong>е</strong> м с я к с о б ы т и я м и д <strong>е</strong> л <strong>е</strong> г а т а м , с к о ­<br />

т о р ы м и вы п о з н а к о м и л и с ь в п р <strong>е</strong> д ы д у щ <strong>е</strong> й гл ав<strong>е</strong>. В о с п о л ь зу й т<strong>е</strong> с ь<br />

ф у н к ц и <strong>е</strong> й G o Т о D e f in it io n , ч т о б ы в с п о м н и т ь п р и н ц и п р а б о т ы<br />

д <strong>е</strong> л <strong>е</strong> га т а E v e n t H a n d l e r :<br />

а с Д <strong>е</strong> н о й<br />

В пр<strong>е</strong>дыдущ<strong>е</strong>м прим <strong>е</strong>р<strong>е</strong><br />

использотлся ст а н ­<br />

дартный обработчик<br />

событий.<br />

Щ <strong>е</strong>лкнит<strong>е</strong> правой кнопкой ааыши на п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной t im e r l...<br />

... и в ы б <strong>е</strong> р и т<strong>е</strong> в м <strong>е</strong> н ю ко м а н д у G o То D e fin itio n для п <strong>е</strong> р <strong>е</strong> х о д а к у ч а с тку ко д а , в к о т о р о м зада<strong>е</strong>тся<br />

п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н а я t i m e r l . Н а й д и т <strong>е</strong> с тр о ч ку:<br />

t h i s . t i m e r l . T i c k -н= n e w S y s t e m . E v e n t H a n d l e r ( t h i s .t i m e r l _ T i c k ) ;<br />

T<br />

Э „ о T ic k э л <strong>е</strong> м <strong>е</strong> н т «<br />

r<br />

К<br />

Один из д<strong>е</strong>л<strong>е</strong>гатов класса<br />

напысаннш<br />

System : базовый обработчик Это t i ^ w e r 3 - Т .с к О -<br />

событии. Эт о д<strong>е</strong>л<strong>е</strong>гат ° им<strong>е</strong>нно<br />

а указат <strong>е</strong>ль на один или Д <strong>е</strong> л <strong>е</strong> гя » ^<br />

------------------- - 1 Л - 9 П<br />

н<strong>е</strong>сколько м<strong>е</strong>тодов.<br />

на н<strong>е</strong>го.<br />

Т<strong>е</strong>п<strong>е</strong>рь щ <strong>е</strong>лкнит<strong>е</strong> правой кнопкой мы ши на д <strong>е</strong>л <strong>е</strong>гат<strong>е</strong> E v en tH an d ler...<br />

... и с н о в а в ы б <strong>е</strong> р и т<strong>е</strong> в м <strong>е</strong> н ю ко м а н д у G o Т о D e fin itio n О б р а т и т <strong>е</strong> в н и м а н и <strong>е</strong> н а н а з в а н и <strong>е</strong> н о в о й<br />

в кл а д ки ; E v e n tH a n d le r [fro m m e t a d a ta ]. О н о о з н а ч а <strong>е</strong> т , ч т о к о д , о п р <strong>е</strong> д <strong>е</strong> л я ю щ и й E v e n t H a n d l e r ,<br />

н а п и с а н н <strong>е</strong> в ам и . Э т о в с т р о <strong>е</strong> н н ы й ко д .N E T F ra m e w o rk , а И С Р с г<strong>е</strong> н <strong>е</strong> р и р о в а л а с тр о ч к у , <strong>е</strong> го<br />

п р <strong>е</strong> д с та в л я ю щ у ю :<br />

p u b l i c d e l e g a t e v o i d E v e n t H a n d l e r ( o b j e c t s e n d e r , E v e n t A r g s e ) ;<br />

~V"<br />

Bom поч<strong>е</strong>му вс<strong>е</strong> события в С * им <strong>е</strong>ю т<br />

парам <strong>е</strong>т ры O bject и EventArgs, им<strong>е</strong>нно<br />

т акую ф орм у им<strong>е</strong><strong>е</strong>т д<strong>е</strong>л<strong>е</strong>гат, опр<strong>е</strong>д<strong>е</strong>ляющий<br />

обработку событий.<br />

Какой код нужно написать, чтобы запустить м<strong>е</strong>тод W orld’s G o ()<br />

10 раз в с<strong>е</strong>кунду?<br />

д а л ь ш <strong>е</strong> > 557


р а с п р <strong>е</strong> д <strong>е</strong> л <strong>е</strong> н и <strong>е</strong> п о в р <strong>е</strong> м <strong>е</strong> н и<br />

Тайм<strong>е</strong>р ддя симулятора<br />

Д обавим тай м <strong>е</strong>р в наш симулятор. У вас уж<strong>е</strong> <strong>е</strong>сть соотв<strong>е</strong>тствую щ ий<br />

эл<strong>е</strong>м <strong>е</strong>нт управл<strong>е</strong>ния, в<strong>е</strong>роятн о, с им <strong>е</strong>н<strong>е</strong>м t i m e r l . Вручную свяж<strong>е</strong>м<br />

<strong>е</strong>го с м<strong>е</strong>тодом обработчи ка собы тий R unFram e ():<br />

О бь<strong>е</strong>кт Tim eSpan облада<strong>е</strong>т т акими свойствами<br />

как Daus (Д ни), Hours (Часы ), Seconds<br />

(С<strong>е</strong>кунды) и Milliseconds (Миллис<strong>е</strong>кунды), что<br />

позволя<strong>е</strong>т изм<strong>е</strong>рят ь вр<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> п р о м <strong>е</strong> ж у т к и ^<br />

в различных <strong>е</strong>диницах.<br />

8 .N E T класс D ateTim e х р а ­<br />

нит информацию о вр<strong>е</strong>м<strong>е</strong>ни,<br />

а свойство Now возвраищ<strong>е</strong>т<br />

т&куищю дату и вр<strong>е</strong>мя.<br />

Вычислить р а з н и ц у двух дат<br />

позволя<strong>е</strong>т обь<strong>е</strong>кт Tim eSpan:<br />

он вычит а<strong>е</strong>т один обь<strong>е</strong>кт<br />

D ateTim e из другого и возвраща<strong>е</strong>т<br />

одь<strong>е</strong>кт Tim eS pan,<br />

сод<strong>е</strong>ржащий разницу.<br />

p u b l i c p a r t i a l c l a s s F o rm l : Form { „ \/Jnr!d.<br />

world world; ________ у 5»«»<br />

p r i v a t e Random ran d o m = new R andom { );<br />

p r i v a t e D a te T im e s t a r t = D a te T im e ,N o w ;<br />

p r i v a t e D a te T im e e n d ;<br />

___________________ _______—— _<br />

p r i v a t e i n t fra m esR u n 0 ;<br />

■Мы хот им<br />

сколько кадров<br />

p u b l i c F o r m l0 {<br />

уж<strong>е</strong> показано.<br />

I n i t i a l i z e C o m p o n e n t ()<br />

w o r ld = new W o r ld { );<br />

Зд<strong>е</strong>сь буд<strong>е</strong>т<br />

вычисляться<br />

вр<strong>е</strong>мя работы<br />

Запуск<br />

t i m e r l . I n t e r v a l = 5 0 ;<br />

M w связали обработчик<br />

t i m e r l . T i c k += n ew E v e n tH a n d le r (R u n F r a m e ); с собств<strong>е</strong>нным<br />

t i m e r l .E n a b l e d = f a l s e ; .ллпйм<strong>е</strong>ра. м<strong>е</strong>тодом RunFram e(). „<br />

Запуск mauMt-fy и в одной с<strong>е</strong>кунд<strong>е</strong><br />

U p d a t e S t a t s ( n e w T im e S p a n О ) ;<br />

Ю о о миллис<strong>е</strong>кунд,<br />

} обновля<strong>е</strong>м ст а т и ст и ки так что тайм<strong>е</strong>р<br />

^ с новым обь<strong>е</strong>кт ом T im eSpan ( ^ й<br />

о т сч<strong>е</strong>т вр<strong>е</strong>м<strong>е</strong>ни). ^ {мооыи буд<strong>е</strong>т срабатыбать<br />

2.0 раз в с<strong>е</strong>кунду.<br />

p r i v a t e v o i d U p d a te S ta ts ( T im e S p a n f r a m e D u r a tio n ) {<br />

// Пр<strong>е</strong>дыдущий код для обновл<strong>е</strong>ния статистики<br />

}<br />

p u b l i c v o i d R u n F r a m e (o b je c t s e n d e r , E v e n tA r g s e ) {<br />

}<br />

fra m esR u n + + ;<br />

у в<strong>е</strong>ли ч ьт <strong>е</strong> колич<strong>е</strong>ст во кадров<br />

w o r ld . Go (ran dom ) ; ^ ----------- на I за п уст и т <strong>е</strong> м <strong>е</strong>т од ио{)<br />

en d = D a te T im e .N o w ;<br />

обь<strong>е</strong>кт а world.<br />

T im eS p an f r a m e D u r a tio n = e n d - s t a r t } З а т <strong>е</strong> м м ы узна<strong>е</strong>м ,<br />

s t a r t = e n d ; --------<br />

— ~ сколько вр<strong>е</strong>м <strong>е</strong>ни проилло<br />

U p d a t e S t a t s ( f r a m e D u r a t i o n ) ;<br />

с м о м <strong>е</strong>н т а проигры вания<br />

посл<strong>е</strong>дн<strong>е</strong>го кадра.<br />

О бновит <strong>е</strong> ст а т и с т и к у с новой<br />

продолж ит <strong>е</strong>льност ью вр<strong>е</strong>м<strong>е</strong>ни.<br />

558 гл а в а 12


о б зо р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

н<strong>е</strong>ни<strong>е</strong><br />

Н апиш и т<strong>е</strong> обработчики собы тий для кнопок S ta rt S im u la tio n<br />

и R e s e t эл <strong>е</strong>м <strong>е</strong> н та ToolStrip, Вот что д <strong>е</strong>л аю т кнопки:<br />

Если вы <strong>е</strong>щ<strong>е</strong><br />

н<strong>е</strong> п <strong>е</strong>р<strong>е</strong>т а­<br />

щили эл<strong>е</strong>м<strong>е</strong>нт<br />

ы ToolStrip<br />

и S tatusS trip из<br />

окна toolbox на<br />

ф орм у, сд<strong>е</strong>лайт<strong>е</strong><br />

эт о с<strong>е</strong>йчас.<br />

1. И значал ьно на п<strong>е</strong>рвой кнопк<strong>е</strong> д о лж на быть надпись<br />

« S tart Sim ulation ». Щ <strong>е</strong>лчок на н<strong>е</strong>й за п уска<strong>е</strong>т сим улятор,<br />

а надпись м <strong>е</strong>ня<strong>е</strong>тся на _____ _____ ____________<br />

« P a u s e S im ulation». При ; Forml.cs [Design]<br />

постановк<strong>е</strong> сим улятора на<br />

паузу надпись м <strong>е</strong>ня<strong>е</strong>тся<br />

Beehive Simulator<br />

на «R e s u m e sim ulation».<br />

start Simulation Reset<br />

2. Н а второй кнопк<strong>е</strong> долж на<br />

#В<strong>е</strong><strong>е</strong>з<br />

’[Bees<br />

быть надпись « R e set»<br />

аАШ жм<strong>е</strong>....... ........... [ Ftowm<br />

Тсйй Ншт<strong>е</strong>у in the rtve і1HoneyhHve<br />

Щ <strong>е</strong>лчок на н<strong>е</strong>й приводит<br />

ТЫй пЩіг м f e іШ _! Nedwhfloweis<br />

к п<strong>е</strong>р<strong>е</strong>загр узк<strong>е</strong> м ира. При<br />

Frafti^ fitfi<br />

FramesRun<br />

поставл<strong>е</strong>нном на паузу<br />

Frenerate<br />

Рпда<strong>е</strong>Яй<strong>е</strong><br />

та й м <strong>е</strong> р <strong>е</strong> т<strong>е</strong>кст на п<strong>е</strong>рвой<br />

кнопк<strong>е</strong> долж <strong>е</strong>н м <strong>е</strong>няться<br />

! Simutetiort paused<br />

с « R e s u m e sim ulation» на<br />

« S tart S im ulation ».<br />

'■ а х<br />

Н а эт от вопрос н<strong>е</strong>т однозначного<br />

отв<strong>е</strong>та. Мы прост о ко т и М .ч т о б ь<br />

вы подумали над дальн<strong>е</strong>йшим<br />

пост ро<strong>е</strong>ни<strong>е</strong>м симулят ор .<br />

^ з ь м и в руку карандаш<br />

■ша tcfOlStripl<br />

Аважды щ<strong>е</strong>лкнит<strong>е</strong> на кнопк<strong>е</strong><br />

Г ооІЗ ігір в конст рукт ор<strong>е</strong>, чтобы<br />

добавить к н<strong>е</strong>й обработчик<br />

событий, как к обычной кнопк<strong>е</strong>.<br />

Как вы д ум а<strong>е</strong>т<strong>е</strong>, что осталось н<strong>е</strong>сд<strong>е</strong>ланны м на<br />

этом этап<strong>е</strong> работы над сим улятором ? Запусти т<strong>е</strong><br />

программу. З апиш ит<strong>е</strong>, каки<strong>е</strong> и зм <strong>е</strong>н<strong>е</strong>н ия нужно<br />

добавить, п<strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м как п<strong>е</strong>р<strong>е</strong>ходить к работ<strong>е</strong><br />

с граф икой.<br />

lisstatusStripi<br />

часш°<br />

_ З а д а в а <strong>е</strong> м ы <strong>е</strong> —<br />

Б оЦ |Э оС Ь 1<br />

В ч<strong>е</strong>м отличи<strong>е</strong> цикла от<br />

кадра?<br />

1); Отличи<strong>е</strong> чисто с<strong>е</strong>мантич<strong>е</strong>ско<strong>е</strong>.<br />

№ ша сист<strong>е</strong>ма работа<strong>е</strong>т циклич<strong>е</strong>ски.<br />

Но как только мы вставим в<br />

про<strong>е</strong>кт графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты,<br />

разговор пойд<strong>е</strong>т исключит<strong>е</strong>льно<br />

о кадрах.<br />

д а л ь ш <strong>е</strong> > 559


п у с т ь вс<strong>е</strong> за р а б о т а <strong>е</strong> т<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

В от как вы глядит код обработчиков<br />

собы тий для кнопок s ta rt Sim ulation<br />

и R eset.<br />

; Ротй.С5{О<strong>е</strong>$*дпЗ<br />

ТоМп<strong>е</strong>^агЩбШ 1 Nectsr^l^wers'<br />

Ргаипишп “ ^ IftamesRjn.....<br />

frame гш» ' ........'\ Ввга<strong>е</strong>Кгй<strong>е</strong><br />

Код ф ормы оста<strong>е</strong>тся б<strong>е</strong>з изм<strong>е</strong>н<strong>е</strong>ний.<br />

Stm yi^on paused<br />

^ to o fS trip l<br />

fcssstelusStripl<br />

С<br />

Уб<strong>е</strong>дит<strong>е</strong>сь,<br />

что им<strong>е</strong>на<br />

эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния<br />

ф орм ы с о ­<br />

впадают с<br />

т <strong>е</strong>ми, к о ­<br />

т оры<strong>е</strong> вы<br />

использу<strong>е</strong>т<strong>е</strong><br />

в сво<strong>е</strong>м код<strong>е</strong>.<br />

p r i v a t e v o i d s t a r t S i m u l a t i o n _ C l i c k ( o b j e c t s e n d e r , E v e n tA r g s e ) {<br />

i f ( t i m e r l . E n a b l e d ) {<br />

}<br />

t o o l S t r i p l . I t e m s [ 0 ] .T e x t = "R esum e s i m u l a t i o n " ;<br />

t i m e r l . S t o p 0 ;<br />

t o o l S t r i p l . I t e m s [0 ] .T e x t = " P a u se s i m u l a t i o n " ;<br />

^ t i m e r l . S t a r t 0 ; I ^JosSeHue-<br />

}<br />

p r i v a t e v o i d r e s e t _ C l i c k ( o b j e c t s e n d e r , E v e n tA r g s e )<br />

fr a m esR u n = 0 ;<br />

w o r ld = n ew W o rld 0 ; ~ —<br />

i f ( ! t i m e r l .E n a b l e d )<br />

t o o l S t r i p l . I t e m s [ 0 ] .T e x t = " S t a r t s i m u l a t i o n " ;<br />

М <strong>е</strong>т ку на п<strong>е</strong>рвой кнопк<strong>е</strong> сл<strong>е</strong>ди<strong>е</strong>т<br />

м<strong>е</strong>нят ь только в случа<strong>е</strong>, ког^а Та<br />

н<strong>е</strong>й написано «Resum e sim ulation»<br />

В случа<strong>е</strong> надписи «Pause slmi,ln+-<br />

^<br />

{ П<strong>е</strong>р<strong>е</strong>загрузка<br />

симулят ора<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

повт орным создани<strong>е</strong>м<br />

экз<strong>е</strong>мпляра<br />

W orld и п<strong>е</strong>р<strong>е</strong>загрузкой<br />

м<strong>е</strong>тода<br />

(ram esRun.<br />

560 гл а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Т<strong>е</strong>стировани<strong>е</strong><br />

П р о д <strong>е</strong> л а н а б о л ь ш ая р а б о т а . С к о м п и л и р у й т <strong>е</strong> ко д ,<br />

и с п р а в ь т <strong>е</strong> о п <strong>е</strong> ч а т к и и з а п у с т и т <strong>е</strong> с и м у л я т о р . Ч т о у<br />

вас получилось ?<br />

Д о л ж н ы ра5окнопки<br />

запуска сим улят<br />

ора, постановки<br />

на паузу и п <strong>е</strong>р<strong>е</strong>­<br />

загрузки-<br />

Beehive Simulât...<br />

^ I Start Simulation Reset<br />

# Bees 6<br />

# Rowers 10<br />

Total hon^ n the hive 3.200 J<br />

Total nectar in the fleld 15.СМЮ<br />

Frames run 0<br />

Frarrre rate<br />

N/A<br />

Simulation paused<br />

i \<br />

■<br />

я »<br />

н<strong>е</strong>плохо!<br />

‘проц<strong>е</strong>сс<strong>е</strong> работы-<br />

Каж <strong>е</strong>т ся, н<strong>е</strong> работ а<strong>е</strong>т<br />

только ст рока состояния-<br />

Ч^ажн<strong>е</strong>ни<strong>е</strong><br />

В от ш анс проявить свои зн ания. Н уж но сд<strong>е</strong>лать так, чтобы пч<strong>е</strong>лы отчиты<br />

вались симулятору, и эта и нф орм ация появлялась в строк<strong>е</strong> состояния,<br />

Н а этот раз вам пр<strong>е</strong>дстоит н<strong>е</strong> только написать ббльш ую часть кода, но и<br />

сам остоят<strong>е</strong>льно р<strong>е</strong>ш ить, что им <strong>е</strong>нно писать. В ам нуж<strong>е</strong>н м <strong>е</strong>тод, который<br />

буд<strong>е</strong>т вызы ваться при каж дом и зм <strong>е</strong>н<strong>е</strong>н ии состояния пч<strong>е</strong>лы.<br />

одна<br />

^цЗ<strong>е</strong>ился 8с<strong>е</strong><br />

'^ а с с ы , кроМ<strong>е</strong><br />

Чтобы н<strong>е</strong>м ного вам помочь, мы написали м <strong>е</strong>тод, который сл<strong>е</strong>ду<strong>е</strong>т д о б а- о д н о г о -<br />

вить к ф орм <strong>е</strong>. Кл асс в<strong>е</strong><strong>е</strong> д олж <strong>е</strong>н вызывать <strong>е</strong>го при и зм <strong>е</strong>н<strong>е</strong>н ии состояния<br />

пч<strong>е</strong>л;<br />

p r i v a t e v o i d S e n d M e s s a g e ( i n t ID, s t r i n g M e s s a g e ) {<br />

}<br />

s t a t u s S t r i p l . I t e m s [ 0 ] . T e x t = " B e e #" + ID + ": " + M e s s a g e ;<br />

д а л ь ш <strong>е</strong> ► 561


р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong> у п р а ж н <strong>е</strong> н и я<br />

пражн<strong>е</strong>нк<strong>е</strong><br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Тр<strong>е</strong>бовалось найти способ инф орм ировать сим улятор о д<strong>е</strong>йствиях<br />

пч<strong>е</strong>л.<br />

Эт о было добавл<strong>е</strong>но в класс В<strong>е</strong><strong>е</strong>.<br />

c l a s s В <strong>е</strong> <strong>е</strong> {<br />

// в <strong>е</strong> с ь у ж <strong>е</strong> с у щ <strong>е</strong> с т в у ю щ и й к о д<br />

p u b l i c B e e M e s s a g e M e s s a g e S e n d e r ;<br />

Мы воспользовались<br />

f вызовом для<br />

p u b l i c v o i d G o ( R a n d o m r a n d o m ) {<br />

A g e + + ;<br />

B e e s t a t e o l d S t a t e = C u r r e n t s t a t e ;<br />

s w i t c h ( c u r r e n t s t a t e ) {<br />

/ / о с т а л ь н а я ч а с т ь о п <strong>е</strong> р а т о р а s w it c h б <strong>е</strong> з и з м <strong>е</strong> н <strong>е</strong> н и й<br />

А <strong>е</strong>л<strong>е</strong>гат В<strong>е</strong><strong>е</strong>М<strong>е</strong>55ад<strong>е</strong> б<strong>е</strong>р<strong>е</strong>т<br />

б к а ч <strong>е</strong> с т в <strong>е</strong> парам <strong>е</strong>т ров н о ­<br />

м <strong>е</strong>р пч<strong>е</strong>лы и сообщ<strong>е</strong>ни<strong>е</strong> С <strong>е</strong>го<br />

пом ощ ью пч<strong>е</strong>ла отправля<strong>е</strong>т<br />

сообщ<strong>е</strong>ни<strong>е</strong> в форму.<br />

}<br />

i f<br />

( o l d S t a t e != C u r r e n t s t a t e<br />

&& M e s s a g e S e n d e r != n u l l )<br />

M e s s a g e S e n d e r (I D , C u r r e n t S t a t e . T o S t r i n g ( ) ) ;<br />

При изм<strong>е</strong>н<strong>е</strong>нии ст ат уса пч<strong>е</strong>лы<br />

вызыва<strong>е</strong>тся м <strong>е</strong>т од BeeMessaqe<br />

на который указыва<strong>е</strong>т д<strong>е</strong>л<strong>е</strong>гат.<br />

Изм<strong>е</strong>н<strong>е</strong>ния,,<br />

вн<strong>е</strong>с<strong>е</strong>нны<strong>е</strong> в<br />

Класс Hive.<br />

С c l a s s H i v e {<br />

// в <strong>е</strong> с ь у ж <strong>е</strong> с у щ <strong>е</strong> с т в у ю щ <strong>е</strong> й к о д<br />

p u b l i c B e e M e s s a g e M e s s a g e S e n d e r ;<br />

об ъ <strong>е</strong>кт у Hive такж<strong>е</strong><br />

т р<strong>е</strong>бу<strong>е</strong>т ся д<strong>е</strong>л<strong>е</strong>гат, ^<br />

чтобы п<strong>е</strong>р<strong>е</strong>дать каждой<br />

пч<strong>е</strong>л<strong>е</strong> м<strong>е</strong>тод, который<br />

буд<strong>е</strong>т вызываться посл<strong>е</strong><br />

- создания этой пч<strong>е</strong>лы<br />

м<strong>е</strong>т одом Ас1


о б зо р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т ат ы<br />

p u b l i c d e l e g a t e v o i d B e e M e s s a g e ( in t ID , s t r i n g M e s s a g e ) ;<br />

В класс W orld такж<strong>е</strong><br />

тр<strong>е</strong>бовалось вн<strong>е</strong>сти<br />

изм<strong>е</strong>н<strong>е</strong>ния.<br />

= Z iS F 4 .<br />

Z Z ^ O M SendMessaee6-<br />

c l a s s W o r l d {<br />

// в <strong>е</strong> с ь с у щ <strong>е</strong> с т в у ю щ и й к о д<br />

p u b l i c W o r l d (B e e M e ssa g e m e s s a g e S e n d e r ) {<br />

B e e s = n e w L i s t < B e e > ( ) ;<br />

F l o w e r s = n e w L i s t < F l o w e r > 0 ;<br />

^<br />

H iv e = n ew H i v e ( t h i s , m e s s a g e S e n d e r ) ;<br />

R a n d o m r a n d o m = n e w R a n d o m ();<br />

f o r (int i = 0 ; i < 10 ; i++)<br />

A d d F l o w e r ( r a n d o m ) ;<br />

К л ассу W orld д<strong>е</strong>л<strong>е</strong>гаты н<strong>е</strong><br />

1^р<strong>е</strong>дуются. Он прост о<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т лл<strong>е</strong>тод для<br />

оызова экз<strong>е</strong>мпляра Hive<br />

s T<br />

p u b l i c p a r t i a l c l a s s F o r m l<br />

// о б ъ я в л <strong>е</strong> н и <strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы х<br />

p u b l i c F o r m l О {<br />

}<br />

I n i t i a l i z e C o m p o n e n t O ;<br />

и , након<strong>е</strong>ц, нужно<br />

обновить ф орм у.<br />

F o r m {<br />

w o r ld = n ew W o r ld (n e w BeeMessage( S e n d M e s s a g e ) ) ;<br />

// о с т а л ь н а я ч а с т ь к о н с т р у к т о р а ф о р м ы<br />

p r i v a t e v o i d r e s e t _ C l i c k ( o b j e c t s e n d e r ,<br />

}<br />

Новый д<strong>е</strong>л<strong>е</strong>гат созда<strong>е</strong>тся из<br />

класса В<strong>е</strong><strong>е</strong> (уб<strong>е</strong>дит<strong>е</strong>сь, что<br />

м<strong>е</strong>т од BeeMessage явля<strong>е</strong>тся<br />

от кры т ы м ) и указыва<strong>е</strong>т на<br />

м<strong>е</strong>т од SendMessageQ.<br />

E v e n tA r g s <strong>е</strong> ) {<br />

fr a m e sR u n = 0;<br />

w o r ld = n ew W o r ld (n e w B e e M e s s a g e ( S e n d M e s s a g e ) ) ;<br />

i f (! t i m e r l .E n a b l e d )<br />

t o o l S t r i p l . I t e m s [ 0 ] .T e x t = " S t a r t s i m u l a t i o n " ;<br />

3<br />

Щ ^ " <strong>е</strong>т ся м 'и )Т м " <strong>е</strong>'<br />

p r i v a t e v o i d S e n d M e s s a g e ( in t ID , s t r i n g M e s s a g e ) {<br />

s t a t u s S t r i p l . I t e m s [ 0 ] .T e x t = " B ee #" + ID + "<br />

} f Это м <strong>е</strong>т од. KomopfMbie^M<br />

} -------дали... н<strong>е</strong> забудьт<strong>е</strong> вписать <strong>е</strong>го.<br />

+ M e s s a g e ;<br />

д а л ь ш <strong>е</strong> ► 563


с г р у п п и р у <strong>е</strong> м п ч <strong>е</strong> л<br />

Работа с группами пч<strong>е</strong>л<br />

П ч <strong>е</strong> л ы ж у ж ж а т в о к р у г улья и н а п о л <strong>е</strong> , с и м у л я т о р<br />

р а б о т а <strong>е</strong> т ! З д о р о в о ? Н о п о к а в и зуа л ь н а я ч а с ть сим у ­<br />

л я т о р а н <strong>е</strong> р а б о т а <strong>е</strong> т , э т и м м ы з а й м <strong>е</strong> м с я в с л <strong>е</strong> д у ю щ <strong>е</strong> й<br />

глав<strong>е</strong>. И н ф о р м а ц и ю м ы м о ж <strong>е</strong> м п о л у ч а ть т о л ь к о п о ­<br />

с р <strong>е</strong> д с т в о м с о о б щ <strong>е</strong> н и й , к о т о р ы <strong>е</strong> п ч <strong>е</strong> л ы о т п р а в л я ю т<br />

в ф о р м у п р и п о м о щ и о б р а т н о г о вы зо ва. Д о б а в и м д о ­<br />

п о л н и т <strong>е</strong> л ь н у ю и н ф о р м а ц и ю о б и х д <strong>е</strong> я т <strong>е</strong> л ь н о с т и .<br />

Ф орм а о б н о вля<strong>е</strong>т с т а ­<br />

т и с т и ч <strong>е</strong> с к и <strong>е</strong> данны<strong>е</strong> и<br />

от ображ а<strong>е</strong>т сообщ <strong>е</strong>ния,<br />

к о т о р ы <strong>е</strong> пч<strong>е</strong>лы п о с ы л а ­<br />

ю т как о т ч <strong>е</strong> т о п р о д <strong>е</strong> ­<br />

ла н н о й работ <strong>е</strong>.<br />

С<br />

»У Beehive Simulator<br />

Pause simulation<br />

Reset<br />

#Bees 6<br />

# Rowers 11<br />

Total hofwy in the hive 1.Ш<br />

Told nectar in the Add<br />

frames Rjn<br />

34.330<br />

Frame rate<br />

16(K.5ms)<br />

kte: 1 bee<br />

FlyingToRower: 2tjees<br />

GatheringNectar: 1 bee<br />

ReturningToHive: 2 bees<br />

Добавим эл<strong>е</strong>м<strong>е</strong>нт ListBox для<br />

отображ<strong>е</strong>ния дополнит<strong>е</strong>льной<br />

информации о пч<strong>е</strong>лах.<br />

Bee #1; Idle<br />

\<br />

_<br />

U одна нич<strong>е</strong>го н<strong>е</strong> д <strong>е</strong>ла <strong>е</strong>т .<br />

ШТУРМ<br />

Вы зна<strong>е</strong>т<strong>е</strong> достаточно для вставки в ф орму эл<strong>е</strong>м <strong>е</strong>нта ListBox. Подумайт<strong>е</strong>, как<br />

им<strong>е</strong>нно он функциониру<strong>е</strong>т. Э то сложн<strong>е</strong><strong>е</strong>, ч<strong>е</strong>м каж<strong>е</strong>тся на п<strong>е</strong>рвый взгляд. Что<br />

нужно сд<strong>е</strong>лать, чтобы опр<strong>е</strong>д<strong>е</strong>лить колич<strong>е</strong>ство пч<strong>е</strong>л в каждом из состояний В<strong>е</strong><strong>е</strong><br />

s t a t e ?<br />

564 г л а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

Колл<strong>е</strong>кция колл<strong>е</strong>кциониру<strong>е</strong>т... ДАННЫЕ<br />

П ч<strong>е</strong>лы сохран<strong>е</strong>ны в колл<strong>е</strong>кции L is t< B e e > . К олл<strong>е</strong>кции пр<strong>е</strong>дназнач<strong>е</strong>ны<br />

для хран <strong>е</strong>н и я данны х... практи ч<strong>е</strong>ски , как базы данны х. Каждую пч<strong>е</strong>лу<br />

м ож но пр<strong>е</strong>дстави ть в вид<strong>е</strong> строки, в к о то р о й указано состоян и<strong>е</strong>, ид<strong>е</strong>нти<br />

ф и като р и т. п. В от как вы глядят пч<strong>е</strong>лы в вид<strong>е</strong> колл<strong>е</strong>кции:<br />

®Pe4eHV»<br />

П оля объ<strong>е</strong>кта В <strong>е</strong><strong>е</strong> сод<strong>е</strong>рж ат м нож <strong>е</strong>ство данны х. К олл<strong>е</strong>кцию объ<strong>е</strong>ктов<br />

можно пр<strong>е</strong>дстави ть в вид<strong>е</strong> строк базы данны х. К аж ды й объ<strong>е</strong>кт сод<strong>е</strong>рж<br />

и т дан ны <strong>е</strong> в полях, так ж <strong>е</strong> как каж дая строка базы сод<strong>е</strong>рж ит данны <strong>е</strong><br />

в столбцах.<br />

Ш ID = 987 1 currentstate = MakingHoney ^<br />

П Ю = 1 2 І (currentstate = FlyingToFlower ^<br />

ID = 1 9 8 2 currentstate = GatheringNectar t<br />

База данных<br />

<strong>е</strong> с т ь<br />

^ а б л ц ц а с названи<strong>е</strong>м<br />

В<strong>е</strong><strong>е</strong> со ст олбцам и ID<br />

« c u rre n tsta te.<br />

Большинство колл<strong>е</strong>кций,<br />

особ<strong>е</strong>нно сод<strong>е</strong>ржащих<br />

объ<strong>е</strong>кты, можно пр<strong>е</strong>дставить<br />

как сво<strong>е</strong>го рода базу<br />

данных.<br />

д а л ь ш <strong>е</strong> * 565


в с т р о <strong>е</strong> н н ы й я з ы к з а п р о с о в<br />

Какая разница, в каком<br />

вид<strong>е</strong> м ы м о ж <strong>е</strong> м пр<strong>е</strong>дставить<br />

ко л л <strong>е</strong> кц и ю , <strong>е</strong>сли мы н<strong>е</strong> м о ж <strong>е</strong>м<br />

использовать <strong>е</strong><strong>е</strong> как базу данны х?<br />

Пр<strong>е</strong>дставьт<strong>е</strong> запросы к колл<strong>е</strong>кциям, базам<br />

данны х и даж <strong>е</strong> к X M L -докум <strong>е</strong>нтам с одинаковы м<br />

синтаксисом!<br />

В C # и м <strong>е</strong> <strong>е</strong> т с я п о л <strong>е</strong> з н а я ф у н к ц и я L I N Q (L a n g u a g e<br />

I N t e g r a t e d Q u e r y — в с т р о <strong>е</strong> н н ы й я з ы к з а п р о с о в ). Э т а<br />

ф у н к ц и я д а <strong>е</strong> т вам в о з м о ж н о с т ь р а б о т а т ь с д а н н ы м и и з<br />

м а с с и в о в , с п и с к о в , с т <strong>е</strong> к а , о ч <strong>е</strong> р <strong>е</strong> д <strong>е</strong> й и д р у ги х к о л л <strong>е</strong> к ц и й<br />

п р и п о м о щ и <strong>е</strong> д и н ы х о п <strong>е</strong> р а ц и й .<br />

L I N Q п о з в о л я <strong>е</strong> т и с п о л ь зо в а ть п р и р а б о т <strong>е</strong> с к о л л <strong>е</strong> к ц и я м и<br />

т о т ж <strong>е</strong> с и н т а к с и с , ч т о и п р и р а б о т <strong>е</strong> с б а за м и д а н н ы х .<br />

З а п р о с ы L I N Q о а м н а к о б о<br />

З о т а ю т с к о л л <strong>е</strong> к ц и я м и<br />

и с базами данныхvar<br />

beeGroups =<br />

from bee in world.Bees<br />

group bee by bee.Currentstate<br />

into beeGroup<br />

orderby beeGroup.Key<br />

select beeGroup;<br />

База данных<br />

1 currentstate = MakingHoney L<br />

ID = 12 1 currentstate = FIvinaToFlower B F<br />

1 1 ID = 1982 j currentstate = GatheringNectar [,<br />

Если бы данны<strong>е</strong> о пч<strong>е</strong>лах находились<br />

в баз<strong>е</strong> (или в файл<strong>е</strong> X M L)? UN Q<br />

работал бы с ними т <strong>е</strong>м ж<strong>е</strong> способом.<br />

566<br />

гл а в а 12<br />


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

LINQ упроща<strong>е</strong>т работу с колл<strong>е</strong>кциями и базами данных<br />

L I N Q б уд<strong>е</strong>т п о с в я щ <strong>е</strong> н а ц <strong>е</strong> л а я гл ав а, а п о к а вы м о ж <strong>е</strong> т <strong>е</strong> в о с п о л ь ­<br />

зо в а ть с я <strong>е</strong> г о в о з м о ж н о с т я м и и д о б а в и ть в с и м у л я т о р д о п о л ­<br />

н и т <strong>е</strong> л ь н ы <strong>е</strong> ф у н к ц и и . В в <strong>е</strong> д и т<strong>е</strong> э т о т ко д . Н и ч <strong>е</strong> г о с т р а ш н о г о ,<br />

<strong>е</strong> сл и вы н <strong>е</strong> п о н и м а <strong>е</strong> т <strong>е</strong> <strong>е</strong> го . О т о м , к а к о н р а б о т а <strong>е</strong> т , м ы п о го в о ­<br />

р и м в гл ав<strong>е</strong> 15.<br />

j^oTOoBo<br />

К IjIlo IrlJ > e й Л e н U Io<br />

p r i v a t e v o i d S e n d M e s s a g e { i n t ID, s t r i n g M e s s a g e ) {<br />

s t a t u s S t r i p l .I t e m s [ 0 ] .Text = " B e e #" + I D + ":<br />

v a r b e e G r o u p s =<br />

f r o m b e e i n w o r l d . B e e s<br />

g r o u p b e e b y b e e . C u r r e n t s t a t e i n t o b e e G r o u p<br />

o r d e r b y b e e G r o u p . K e y<br />

К - л ю ч о м явля<strong>е</strong>тся свойство пч<strong>е</strong>лы<br />

s e l e c t b e e G r o u p ;<br />

l i s t B o x l .I t e m s .C l e a r {);<br />

уб<strong>е</strong>Зит<strong>е</strong>сь.f o r e a c h (v a r . . a r g u E i J j L b e g g ^ ^ )<br />

ч т о эт о<br />

совпада<strong>е</strong>т<br />

с им<strong>е</strong>н<strong>е</strong>м<br />

эл<strong>е</strong>м<strong>е</strong>нт а<br />

listbox ваш<strong>е</strong>й<br />

формы<br />

" + M e s s a g e ;<br />

Э т о запрос UNQ, грц ппирцю<br />

щ ш вс<strong>е</strong>х пч<strong>е</strong>л колл<strong>е</strong>кции по<br />

свойст ву C u rren tsta te.<br />

■<br />

C u rre n tsta te , т ак что состояния будут о т о -<br />

бражатьсй в ф орм <strong>е</strong> им<strong>е</strong>нно в т аком порядк<strong>е</strong>.<br />

{<br />

s t r i n g S;<br />

^^^^'^oups появилась из за п р о ­<br />

i f (g r o u p .C o u n t () = = 1 )<br />

са UNQ. Мы мож<strong>е</strong>м посчит ат ь чл<strong>е</strong>нов этой эт,<br />

группы и по оч<strong>е</strong>р<strong>е</strong>ди п росм от р<strong>е</strong>т ь их.<br />

s =<br />

Э т от код об<strong>е</strong>сп<strong>е</strong>чива<strong>е</strong>т правильно<strong>е</strong> упот р<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong><br />

английского слова «п ч<strong>е</strong>ла» во множ <strong>е</strong>ств<strong>е</strong>нном числ<strong>е</strong>.<br />

^<br />

л nSa6uM в т <strong>е</strong>кст ово<strong>е</strong><br />

l i s t B o x l . Items. A d d (group. Key. T o S t r i n g О + ^ группы<br />

if ( g r o u p . K e y == B e e S t a t e .I d l e<br />

+ g r o u p . C o u n t 0 + " b e e " + s) ; ( <strong>е</strong> <strong>е</strong> к л н з ч ) u см<strong>е</strong>тчик.<br />

& & g r o u p .C o u n t () == w o r l d .B e e s .C o u n t () Так как колич<strong>е</strong>ство<br />

н<strong>е</strong>занятых<br />

& & f r a m e s R u n > 0 ) { ~ изв<strong>е</strong>стно...<br />

l i s t B o x l . I t e m s . A d d ( " S i m u l a t i o n e n d e d : a l l b e e s a r e i d l e " ) ;<br />

t o o l S t r i p l .I t e m s [0] .Text = " S i m u l a t i o n e n d e d " ;<br />

s t a t u s S t r i p l .I t e m s [ 0 ] .Text = " S i m u l a t i o n ended",<br />

t i m e r l .E n a b l e d = false;<br />

L I N Q б у д <strong>е</strong> т п о д р о б н о р а с с м о т р <strong>е</strong> н в с л <strong>е</strong> д у ю щ и х<br />

гл а в а х .<br />

П о э т о м у п о к а н <strong>е</strong> с т а р а й т <strong>е</strong> с ь п о н я т ь и з а п о м н и т ь с и н ­<br />

т а к с и с .<br />

-можно пров<strong>е</strong>рить^<br />

н<strong>е</strong> являются ли вс<strong>е</strong><br />

пч<strong>е</strong>лы н<strong>е</strong>занятыми.<br />

и з положит<strong>е</strong>льного<br />

р<strong>е</strong>зульт ат а<br />

пров<strong>е</strong>рки сл<strong>е</strong>ду<strong>е</strong>т<br />

от сут ст ви<strong>е</strong> в уль<strong>е</strong><br />

м <strong>е</strong>да, а значит,<br />

зав<strong>е</strong>рш<strong>е</strong>ни<strong>е</strong> работ ы<br />

Симулятора.<br />

д а л ь ш <strong>е</strong> ► 567


с о х р а н я <strong>е</strong> м м и р<br />

Т<strong>е</strong>стировани<strong>е</strong> (Вторая попытка)<br />

С к о м п и л и р у й т <strong>е</strong> к о д и з а п у с т и т <strong>е</strong> п р о <strong>е</strong> к т . В случа<strong>е</strong><br />

о ш и б о к п р о в <strong>е</strong> р ь т <strong>е</strong> с и н т а к с и с , о с о б <strong>е</strong> н н о н о в ы й<br />

к о д с L I N Q . П о с м о т р и м , к а к р а б о т а <strong>е</strong> т н а ш си м у­<br />

л я т о р !<br />

Связанный<br />

с ф орм ой<br />

илайм<strong>е</strong>р<br />

упрйбля<strong>е</strong>!^<br />

1Л.рОЦйССОМ<br />

юаЬотм\ C W -<br />

м у л я то р й .<br />

Эти данны<strong>е</strong><br />

получаются<br />

пут <strong>е</strong>м за -<br />

просов LINQ<br />

к колл<strong>е</strong>кциям,<br />

Которы<strong>е</strong><br />

происходят в<br />

каждом Кадр<strong>е</strong>.<br />

Hj? Beehive Simylator<br />

Pause Simulation Reset Я |<br />

+? Bees 6 ^<br />

# Rowers 11<br />

Total honey in the hive 1.ЖЮ<br />

Total nectar in the field М.Ш / ^<br />

Frames run Ш<br />

Frame rate ie (e ,5 m s )i<br />

IcBe; 1 bee<br />

R'/ngTonower; 2 bees<br />

Gathering Nedar: 1 bee<br />

ReturningToHive; 2 bees<br />

Bee ^ 5 Idle<br />

Пч<strong>е</strong>лы выполняют обратный вызов ф орм ы ,<br />

что позволя<strong>е</strong>т оп<strong>е</strong>ративно м<strong>е</strong>нят ь инф ормацию<br />

при изм<strong>е</strong>н<strong>е</strong>нии ик ст ат уса.<br />

'<br />

Вы добавит<strong>е</strong> эти эл<strong>е</strong>м<strong>е</strong>нты<br />

и обработчики событий для них<br />

Ст ат ист ика явля<strong>е</strong>тся<br />

^ р<strong>е</strong>зульт ат ом запросов^<br />

которы<strong>е</strong> ф орм а посыла<strong>е</strong>т<br />

одь<strong>е</strong>кт у World.<br />

Объ<strong>е</strong>кт ы , им<strong>е</strong>ющи<strong>е</strong> м<strong>е</strong>тоды,<br />

которы<strong>е</strong> связаны с д<strong>е</strong>л<strong>е</strong>гатами<br />

или обработчиками<br />

событий другого объ<strong>е</strong>кта,<br />

пр<strong>е</strong>дст авляют собой ссылку,<br />

по которой буд<strong>е</strong>т сл<strong>е</strong>довать<br />

с<strong>е</strong>риализатор.<br />

\ Г<br />

Объ<strong>е</strong>кт ы , связанны<strong>е</strong> с обработ ­<br />

чиком событий, вызыва<strong>е</strong>мых эл<strong>е</strong>м<strong>е</strong>нт<br />

ам и управл<strong>е</strong>ния, нужно п о ­<br />

м<strong>е</strong>чат ь как [NonSerialized]. Инач<strong>е</strong><br />

вы попыт а<strong>е</strong>т <strong>е</strong>сь с<strong>е</strong>риализовать<br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния и, как сл<strong>е</strong>дстви<strong>е</strong>,<br />

получит <strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong><br />

SerializationException.<br />

V<br />

Иногда тр<strong>е</strong>бу<strong>е</strong>тся с<strong>е</strong>риализовать н<strong>е</strong> в<strong>е</strong>сь объ<strong>е</strong>кт, а <strong>е</strong>го часть. Напшм<strong>е</strong>р вы cmt^oum.<br />

сист<strong>е</strong>му, в которой р<strong>е</strong>гистриру<strong>е</strong>тся пользоват<strong>е</strong>ль, и нужно сохранить в файл обь~<br />

Пол<strong>е</strong> password можно пом<strong>е</strong>тить атрибутом<br />

[NonSmaUzed]. В этом случа<strong>е</strong> м<strong>е</strong>тод SeriahzeO пропустит это пол<strong>е</strong>.<br />

Атрибут iNonSerialized] особ<strong>е</strong>нно пол<strong>е</strong>з<strong>е</strong>н, когда объ<strong>е</strong>кт ссыла<strong>е</strong>тся на н<strong>е</strong>с<strong>е</strong>шализи^<br />

попытка с<strong>е</strong>риализаими формы стан<strong>е</strong>т причиной исключ<strong>е</strong>ния<br />

Ser alizat,onExcepbon. Им<strong>е</strong>нно это исключ<strong>е</strong>ни<strong>е</strong> поит ся, <strong>е</strong>сли вы ^ p u a Z u e Z oS^^^<br />

ссылающийся на форму. Но пом<strong>е</strong>тив пол<strong>е</strong> с этой ссылкой атрибутом [NonSeriatizedl '<br />

вы пр<strong>е</strong>дотвратит<strong>е</strong> п<strong>е</strong>р<strong>е</strong>ход м<strong>е</strong>тода SerializeQ по ссылк<strong>е</strong>.<br />

LNonseriaUzedJ.<br />

I<br />

568 глава 12


р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong> у п р а ж н <strong>е</strong> н и я<br />

н<strong>е</strong>нк<strong>е</strong><br />

|^<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот код, заставляющий работать кнопки Save и Open.<br />

u s i n g S y s t e m . l O ;<br />

Н <strong>е</strong> забудьт<strong>е</strong> про дополнит<strong>е</strong>льны<strong>е</strong><br />

оп<strong>е</strong>рат оры using.<br />

u s i n g S y s t e m . R u n t i m e .S e r i a l i z a t i o n .F o r m a t t e r s .B i n a r y ;<br />

Классы WoHd, HivCj Flow er и Bee<br />

нужно сд<strong>е</strong>лать с<strong>е</strong>риализу<strong>е</strong>мыми.<br />

В проц<strong>е</strong>сс<strong>е</strong> с<strong>е</strong>риализации объ<strong>е</strong>кта<br />

W orld .N ET обнаружит ссылки на<br />

объ<strong>е</strong>кты Hive. Flow er и В<strong>е</strong><strong>е</strong> и с <strong>е</strong> ­<br />

риализу<strong>е</strong>т ик.<br />

[ N o n S e r i a l i z e d ]<br />

p u b l i c B e e M e s s a g e M e s s a g e S e n d e r ;<br />

[ S e r i a l i z a b l e ]<br />

c l a s s W o r l d {<br />

[ S e r i a l i z a b l e ]<br />

c l a s s H i v e {<br />

[ S e r i a l i z a b l e ]<br />

c l a s s F l o w e r {<br />

[ S e r i a l i z a b l e ]<br />

c l a s s B e e f<br />

, Уб<strong>е</strong>дит<strong>е</strong>сь, что пол<strong>е</strong><br />

MessageSender в классах<br />

Hive и Bee пом<strong>е</strong>ч<strong>е</strong>но<br />

ат рибут ом [NonSerialized].<br />

К од для кнопки Save.<br />

nT<br />

private void sa v e T o o lS tr ip B u tto n _ C X ic k (object sender, EventArgs e) {<br />

bool enabled = timerl.Enabled;<br />

if (enabled) Для файлов, в к о -<br />

timerl.Stop () ;<br />

т оры<strong>е</strong> записы ва<strong>е</strong>тся<br />

информация<br />

из сим улят ора, мы<br />

SaveFileDialog saveDialog = new SaveFileDialog () ; использу<strong>е</strong>м расш и-<br />

saveDialog.Filter = "Simulator File (*.bees)|*.bees"; pCHue .bees.<br />

saveDialog.CheckPathExists = true;<br />

saveDialog.Title = "Choose a file to save the current simulation";<br />

if (saveDialog.ShowDialog{) == DialogResult.OK) {<br />

try {<br />

Им<strong>е</strong>нно<br />

зд<strong>е</strong>сь мир<br />

сохраня<strong>е</strong>тся<br />

в<br />

файл.<br />

}<br />

if<br />

BinaryFormatter bf = new BinaryFormatter();<br />

using (Stream output = File.OpenWrite(saveDialog.FileName)) {<br />

bf .Serialize (output, world)<br />

Помнит<strong>е</strong>, что вм<strong>е</strong>ст<strong>е</strong> с объ<strong>е</strong>ктолл<br />

bf.Serialize(output, framesRun);<br />

}<br />

}<br />

catch (Exception ex) {<br />

}<br />

MessageBox.Show("Unable to save the simulator file\r\n" + ex.Message,<br />

"Bee Simulator Error" MessageBoxButtons.OK, MessageBoxIcon.Error);<br />

(enabled)<br />

timerl.Start<br />

570 г л а в а 12


о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р<strong>е</strong>зультаты<br />

Посл<strong>е</strong>дни<strong>е</strong> штрихи: Open и Save<br />

В с<strong>е</strong> у ж <strong>е</strong> п р а к т и ч <strong>е</strong> с к и го т о в о д ля п <strong>е</strong> р <strong>е</strong> х о д а к с л <strong>е</strong>д у ю щ <strong>е</strong> м у э т а п у — д о ­<br />

б а в л <strong>е</strong> н и ю в н а ш с и м у л я т о р г р а ф и к и . О с т а л о с ь п р <strong>е</strong> д у с м о т р <strong>е</strong> т ь в о з м о ж ­<br />

н о с т ь з а гр у ж а т ь д а н н ы <strong>е</strong> , с о х р а н я т ь и х и в ы в о д и ть с т а т и с т и к у .<br />

О<br />

Значки Open, Save и Print<br />

Э л <strong>е</strong> м <strong>е</strong> н т T o o lS trip у м <strong>е</strong> <strong>е</strong> т а в т о м а т и ч <strong>е</strong> с к и в с тав л я ть с т а н д а р т н ы <strong>е</strong> з н а ч ­<br />

к и : new , o p e n , save, p r in t , c u t, copy, paste и h e lp . Щ <strong>е</strong> л к н и т <strong>е</strong> н а э л <strong>е</strong> м <strong>е</strong> н т <strong>е</strong><br />

T o o lS trip п р а в о й к н о п к о й м ы ш и и в ы б <strong>е</strong> р и т <strong>е</strong> к о м а н д у Insert Standard<br />

' Items. В в <strong>е</strong> р х н <strong>е</strong> й ч а с т и ф о р м ы п о я в и т с я п а н <strong>е</strong> л ь с к н о п к а м и . Щ <strong>е</strong> л к н и т <strong>е</strong><br />

н а п <strong>е</strong> р в о й и з н и х — э т о к н о п к а n e w — и у д а л и т<strong>е</strong> <strong>е</strong><strong>е</strong>. Т р и с л <strong>е</strong> д у ю щ и <strong>е</strong> к н о п ­<br />

к и (o p e n , save и p r in t ) н а м н у ж н ы . Р а з д <strong>е</strong> л и т<strong>е</strong> л ь и о с та л ь н ы <strong>е</strong> к н о п к и т а к ­<br />

ж <strong>е</strong> т р <strong>е</strong> б у <strong>е</strong> т с я уд ал и ть . С в о й с т в о CanOverflow э л <strong>е</strong> м <strong>е</strong> н т а T o o lS trip д о л ж н о<br />

и м <strong>е</strong> т ь з н а ч <strong>е</strong> н и <strong>е</strong> false (ч т о б ы к н о п к и с п р а в о й с т о р о н ы п а н <strong>е</strong> л и и н с т р у ­<br />

м <strong>е</strong> н т о в н <strong>е</strong> д о б ав л ялись в м <strong>е</strong> н ю п <strong>е</strong> р <strong>е</strong> п о л н <strong>е</strong> н и я ), а с в о й с тв о GripStyle<br />

- з н а ч <strong>е</strong> н и <strong>е</strong> H id d e n (ч т о б ы с кр ы т ь р а с п о л о ж <strong>е</strong> н н ы й сл<strong>е</strong>ва д <strong>е</strong> с к р и п т о р<br />

п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> щ <strong>е</strong> н и я ).<br />

О кнопк<strong>е</strong> Print<br />

разговор пойд<strong>е</strong>т<br />

в сл<strong>е</strong>дующ<strong>е</strong>й глав<strong>е</strong>.<br />

Обработчики событий для кнопок<br />

Н о в ы <strong>е</strong> к н о п к и н а зы в а ю тс я o p e n T o o l S t r i p B u t t o n , s a v e T o o l S t r i p B u t t o n и p r i n t T o o l -<br />

S t r i p B u t t o n . Д в о й н ы м щ <strong>е</strong> л ч к о м д о б ав ь т<strong>е</strong> к н и м о б р а б о т ч и к и с о б ы т и й .<br />

Добавьт<strong>е</strong> код, заставляющий работать кнопки Open и Save.<br />

)а ж н ш <strong>е</strong><br />

1. Кнопка Save должна с<strong>е</strong>риализовать объ<strong>е</strong>кт world в файл. Она должна останавливать тайм<strong>е</strong>р (<strong>е</strong>сли симулятор<br />

вс<strong>е</strong> <strong>е</strong>щ<strong>е</strong> работа<strong>е</strong>т, тайм<strong>е</strong>р мож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>запуститься посл<strong>е</strong> сохран<strong>е</strong>ния) и вызывать окно диалога Save.<br />

С<strong>е</strong>риализации долж<strong>е</strong>н подв<strong>е</strong>ргаться н<strong>е</strong> только объ<strong>е</strong>кт world, но и колич<strong>е</strong>ство кадров, прожитых симулятором.<br />

Сначала вы получит<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> S e r i a l i z a t i o n E x c e p t i o n с т<strong>е</strong>кстом Тур<strong>е</strong> 'Forml'is not marked as<br />

serializable. В<strong>е</strong>дь д<strong>е</strong>л<strong>е</strong>гат B e e M e s s a g e связан С формой, значит, <strong>е</strong><strong>е</strong> пытаются с<strong>е</strong>риализовать.<br />

Добавьт<strong>е</strong> полям M e s s a g e S e n d e r в классах Hive и В<strong>е</strong><strong>е</strong> атрибут [ N o n S e r i a l i z e d ] .<br />

2. Кнопка Open д<strong>е</strong>с<strong>е</strong>риализу<strong>е</strong>т мир из файла. Тайм<strong>е</strong>р в<strong>е</strong>д<strong>е</strong>т с<strong>е</strong>бя так ж<strong>е</strong>, как при щ<strong>е</strong>лчк<strong>е</strong> на кнопк<strong>е</strong> Save. Должно<br />

открываться окно диалога Open и происходить д<strong>е</strong>с<strong>е</strong>риализация указанного пользоват<strong>е</strong>л<strong>е</strong>м файла. Посл<strong>е</strong> ч<strong>е</strong>го<br />

можно снова связать д<strong>е</strong>л<strong>е</strong>гат M e s s a g e S e n d e r с формой и при н<strong>е</strong>обходимости п<strong>е</strong>р<strong>е</strong>запустить тайм<strong>е</strong>р.<br />

3. Н<strong>е</strong> забудьт<strong>е</strong> про обработку исключ<strong>е</strong>ний! Уб<strong>е</strong>дит<strong>е</strong>сь, что пробл<strong>е</strong>мы с чт<strong>е</strong>ни<strong>е</strong>м и записью в файл н<strong>е</strong> влияют<br />

на состояни<strong>е</strong> мира. Создайт<strong>е</strong> всплывающи<strong>е</strong> окна с сообщ<strong>е</strong>ниями об ошибк<strong>е</strong>.<br />

д а л ь ш <strong>е</strong> > 569


\сод<br />

p r i v a t e v o i d o p e n T o o l S t r i p B u t t o n _ C l i c k ( o b j e c t s e n d e r , E v e n tA rg s e) {<br />

W o rld c u r r e n tW o r ld = w o r ld ;<br />

i n t c u r r e n tF r a m e s R u n = fra m e s R u n ;<br />

b o o l e n a b l e d = t i m e r l . E n a b le d ;<br />

i f ( e n a b le d )<br />

t i m e r l . S t o p ( ) ;<br />

о б з о р и п р <strong>е</strong> д в а р и т <strong>е</strong> л ь н ы <strong>е</strong> р <strong>е</strong> зул ь т а т ы<br />

П<strong>е</strong>р<strong>е</strong>д т <strong>е</strong>м как от кры т ь и прочит ат ь<br />

ф айл, сд<strong>е</strong>ла<strong>е</strong>м копию т <strong>е</strong>кущ <strong>е</strong>го состояния<br />

м ира и парам <strong>е</strong>т ра framesRun. В случа<strong>е</strong><br />

пробл<strong>е</strong>м м ир буд<strong>е</strong>т восстановл<strong>е</strong>н из эт ой<br />

копии.<br />

O p e n F ile D ia lo g o p e n D ia lo g = new O p e n F i l e D i a l o g ( ) ;<br />

o p e n D i a l o g . F i l t e r = " S i m u l a t o r F i l e ( * . b e e s ) | * . b e e s " ;<br />

o p e n D ia lo g . C h e c k P a th E x is ts = t r u e ;<br />

o p e n D i a l o g .C h e c k F i l e E x i s t s = t r u e ;<br />

o p e n D i a l o g . T i t l e = "C h o o se a f i l e w i t h a s i m u l a t i o n t o<br />

i f ( o p e n D ia lo g . S h o w D ia lo g () == D i a l o g R e s u l t . OK) {<br />

t r y {<br />

B i n a r y F o r m a t t e r b f = new B i n a r y F o r m a t t e r ( ) ;<br />

O n cp a m o p___ m u s in g (S tre a m i n p u t = F i l e . O penR ead ( o p e n D ia lo g . F ile N a m e ) )<br />

2A f —<br />

panm upye-m w o r ld = (W orld) b f . D e s e r i a l i z e ( i n p u t ) ;<br />

mOKa.<br />

J<br />

fra m e s R u n = ( i n t ) b f . D e s e r i a l i z e ( i n p u t ) ;<br />

H a c m p o u K u<br />

u вызов окна<br />

диалога<br />

Open File.<br />

Зд<strong>е</strong>сь происходит<br />

д<strong>е</strong>с<strong>е</strong>риализация м ира<br />

и колич<strong>е</strong>ства кадров.<br />

c a t c h ( E x c e p tio n ex ) {<br />

M e s s a g e B o x .S h o w (" U n a b le t o r e a d t h e s i m u l a t o r f i l e \ r \ n " + e x .M e s s a g e ,<br />

"B ee S i m u l a t o r E r r o r " , M e s s a g e B o x B u tto n s . OK, M e s s a g e B o x I c o n .E r r o r ) ;<br />

}<br />

w o r ld = c u r r e n t W o r l d ; «as---------<br />

fra m e s R u n = c u r r e n tF r a m e s R u n ;<<br />

При появл<strong>е</strong>нии исключ<strong>е</strong>ния мы<br />

восстанавлива<strong>е</strong>м посл<strong>е</strong>днюю<br />

сохран<strong>е</strong>нную в<strong>е</strong>рсию мира<br />

и парам <strong>е</strong>т ра framesRun.<br />

w o r l d . H i v e . M e s s a g e S e n d e r = new B e e M e s s a g e (S e n d M e s s a g e );<br />

f o r e a c h (B ee b e e i n w o r ld .B e e s )<br />

b e e .M e s s a g e S e n d e r = new B e e M e s s a g e (S e n d M e s s a g e );<br />

i f ( e n a b le d )<br />

t i m e r l . S t a r t 0 ; ^ ~<br />

Посл<strong>е</strong> загрузки мы<br />

подсо<strong>е</strong>диня<strong>е</strong>м Э <strong>е</strong> л <strong>е</strong>гот u<br />

п<strong>е</strong>р<strong>е</strong>запуска<strong>е</strong>м тайм<strong>е</strong>р-<br />

Рабочую в<strong>е</strong>рсию этого файла можно получить на сайт<strong>е</strong> Head<br />

First Labs: www.headlirstlabs.com/books/hfcshaip/<br />

д а л ь ш <strong>е</strong> у 571


1 3 э л <strong>е</strong> м <strong>е</strong> н т ы управл<strong>е</strong>н ия и Гра'^иЧ <strong>е</strong>сК и<strong>е</strong> ‘^’р а Ш <strong>е</strong> н ш ы<br />

Ф<br />

Ф<br />

^1^<br />

Наводим красоту ^<br />

И н о гд а у п р а в л <strong>е</strong> н и <strong>е</strong> гр а ф и к о й п р и х о д и т с я брать в св о и р у к и .<br />

До этого мом<strong>е</strong>нта визуальный асп<strong>е</strong>кт наших прилож<strong>е</strong>ний был отдан на откуп<br />

эл<strong>е</strong>м<strong>е</strong>нтам управл<strong>е</strong>ния. Но иногда этого н<strong>е</strong>достаточно, наприм<strong>е</strong>р, <strong>е</strong>сли<br />

вы хотит<strong>е</strong> анимировать изображ<strong>е</strong>ни<strong>е</strong>. Вам пр<strong>е</strong>дстоит научиться создавать<br />

свои эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния для .NET, прим<strong>е</strong>нять двойную буф<strong>е</strong>ризацию<br />

и даж<strong>е</strong> рисовать н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно на формах.


в <strong>е</strong> зд <strong>е</strong> о б ъ <strong>е</strong> кт ы<br />

Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния как ср<strong>е</strong>дстбо Взаимод<strong>е</strong>йствия с программой<br />

Э л <strong>е</strong> м <strong>е</strong> н т ы T e x tB o x , P ic tu r e B o x , L a b e l... вы у ж <strong>е</strong> д ав н о и м <strong>е</strong> <strong>е</strong> т <strong>е</strong><br />

п р <strong>е</strong> д с т а в л <strong>е</strong> н и <strong>е</strong> о р а б о т <strong>е</strong> с н и м и . Н о ч т о им<strong>е</strong>нно вы о н и х зн а<strong>е</strong>т<strong>е</strong>?<br />

(К р о м <strong>е</strong> т о г о , ч т о и х м о ж н о п <strong>е</strong> р <strong>е</strong> т а с к и в а т ь и з о к н а Т о о Ш о х н а<br />

ф о р м у ).<br />

Создани<strong>е</strong> пользоват<strong>е</strong>льских эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

Э л <strong>е</strong> м <strong>е</strong> н т ы Т о о Ш о х б <strong>е</strong> с ц <strong>е</strong> н н ы п р и п о с т р о <strong>е</strong> н и и ф о р м и п р и л о ­<br />

ж <strong>е</strong> н и й , н о н и ч <strong>е</strong> г о т а и н с т в <strong>е</strong> н н о г о в н и х н <strong>е</strong> т. Э т о в с <strong>е</strong> го л и ш ь<br />

кл асс ы , а л ю б о й кл а сс вы м о ж <strong>е</strong> т <strong>е</strong> н а п и с а т ь с а м о с то я т<strong>е</strong> л ь н о .<br />

В С # с о зд ать п о л ь з о в а т <strong>е</strong> л ь с к и й э л <strong>е</strong> м <strong>е</strong> н т у п р а в л <strong>е</strong> н и я к р а й н <strong>е</strong><br />

л <strong>е</strong> гк о . Д о с т а т о ч н о н у ж н о г о б а з о в о го кл а с с а и ф у н к ц и и н а с л <strong>е</strong> ­<br />

д о в а н и я .<br />

Ваши эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния в окн<strong>е</strong> ToolBox<br />

Н и ч <strong>е</strong> г о т а и н с т в <strong>е</strong> н н о г о н <strong>е</strong> т и в о к н <strong>е</strong> Т о о Ш о х . О н о п р о с м а т р и ­<br />

в а <strong>е</strong> т классы п р о <strong>е</strong> к т а и в с т р о <strong>е</strong> н н ы <strong>е</strong> кл ассы .N E T в п о и с к а х эл<strong>е</strong>м<br />

<strong>е</strong> н т о в у п р а в л <strong>е</strong> н и я . П р и о б н а р у ж <strong>е</strong> н и и кл а сса, р <strong>е</strong> а л и з у ю щ <strong>е</strong> го<br />

н у ж н ы й и н т <strong>е</strong> р ф <strong>е</strong> й с , о т о б р а ж а <strong>е</strong> т с я з н а ч о к . В а ш и э л <strong>е</strong> м <strong>е</strong> н т ы М о ж н о создат ь<br />

т а к ж <strong>е</strong> о т о б р а з я т с я в э т о м о к н <strong>е</strong> . ^ насл<strong>е</strong>дующий ^ласся<br />

в окн<strong>е</strong> toolboK<br />

Код, добавляю щий к цюрм<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния и даж<strong>е</strong><br />

удаляю щ ий и х в проц<strong>е</strong>сс<strong>е</strong> работы програллмы<br />

Ф о р м <strong>е</strong> в к о н с т р у к т о р <strong>е</strong> м о ж н о п р и д а т ь и д р у го й вид. В ы у ж <strong>е</strong> р а б о т а ­<br />

л и с э л <strong>е</strong> м <strong>е</strong> н т а м и P ic tu r e B o x . И х м о ж н о т а к ж <strong>е</strong> д о б а в л я ть и удалять.<br />

В к о н ц <strong>е</strong> к о н ц о в , п р и п о с т р о <strong>е</strong> н и и в ам и ф о р м ы , И С Р д о б а в л я <strong>е</strong> т<br />

к н <strong>е</strong> й э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и я ... э т о о з н а ч а <strong>е</strong> т , ч т о вы м о ж <strong>е</strong> т <strong>е</strong> н а п и ­<br />

сать а н а л о ги ч н ы й к о д и и с п о л ь зо в а ть <strong>е</strong> го п о м <strong>е</strong> р <strong>е</strong> н <strong>е</strong> о б х о д и м о с т и .<br />

574 г л а в а 13


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и г р а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния - это то>к<strong>е</strong> объ<strong>е</strong>кты<br />

Вы уж<strong>е</strong> осв<strong>е</strong>дом л<strong>е</strong>ны о важ ности эл <strong>е</strong>м <strong>е</strong> н т о в уп р ав л <strong>е</strong>н и я . Вы пользовались кнопкам и, т<strong>е</strong>кстовы м и полям<br />

и, ф лаж кам и, м <strong>е</strong>ткам и и другими эл<strong>е</strong>м <strong>е</strong>нтам и начиная с главы 1. И вот приш ла п о р а узнать, что это<br />

таки<strong>е</strong> ж <strong>е</strong> объ<strong>е</strong>кты , как и вс<strong>е</strong> остальны <strong>е</strong>.<br />

Э л<strong>е</strong>м <strong>е</strong>нты управл<strong>е</strong>ния просто ум<strong>е</strong>ют рисовать сами с<strong>е</strong>бя. О бъ<strong>е</strong>кт Form сл<strong>е</strong>дит за их состоян и<strong>е</strong>м при<br />

помош;и сп<strong>е</strong>циальной колл<strong>е</strong>кции C o n t r o l s . Эта колл<strong>е</strong>кция да<strong>е</strong>т вам возм ож ность добавлять эл<strong>е</strong>м <strong>е</strong>нты<br />

управл<strong>е</strong>ния в ваш код и удалять их.<br />

' C V .<br />

Б о т ф орм а для н<strong>е</strong>сложного<br />

прилож <strong>е</strong>ния. Колл<strong>е</strong>кция<br />

Controls сод<strong>е</strong>рж ит ссылки<br />

на б<strong>е</strong><strong>е</strong> эл<strong>е</strong>м <strong>е</strong>нт ы у п р а в л <strong>е</strong> ­<br />

ния формыформ<br />

а им<strong>е</strong><strong>е</strong>т я эл<strong>е</strong>м<strong>е</strong>нт<br />

ов управл<strong>е</strong>ния,<br />

поэт ом у в колл<strong>е</strong>кции<br />

Controls сод<strong>е</strong>ржится<br />

^ ссылок на с о о т ­<br />

в<strong>е</strong>т ст вую щ и<strong>е</strong> объ<strong>е</strong>кты.<br />

Т р <strong>е</strong> м<br />

ф о р м <strong>е</strong> ^ roo>^6evv\"<br />

t o n t r o is<br />

1ЛЛЙ Lahelд<br />

а л ь ш <strong>е</strong> > 575


к а к м и л о !<br />

Анимиру<strong>е</strong>м симулятор улья<br />

Н а ш з а м <strong>е</strong> ч а т <strong>е</strong> л ь н ы й с и м у л я т о р н <strong>е</strong> р а д у <strong>е</strong> т гл аз. П р и ш л о в р <strong>е</strong> м я с о зд ать в изуал<br />

и з а ц и ю , д <strong>е</strong> м о н с т р и р у ю щ у ю п ч <strong>е</strong> л в д <strong>е</strong> й с т в и и . А н и м и р у <strong>е</strong> м у л <strong>е</strong> й п р и п о м о щ и<br />

э л <strong>е</strong> м <strong>е</strong> н т о в у п р а в л <strong>е</strong> н и я .<br />

О Происходящ <strong>е</strong><strong>е</strong> показыва<strong>е</strong>т пользоват<strong>е</strong>льский инт<strong>е</strong>рф <strong>е</strong>йс<br />

С и м у л я т о р б уд<strong>е</strong>т с о с т о я т ь и з т р <strong>е</strong> х о к о н . О с н о в н о <strong>е</strong> , о т о б р а ж а ю щ <strong>е</strong> <strong>е</strong> с т а т и с т и к у , у ж <strong>е</strong> го т о в о .<br />

О с т а л о с ь д о б а в и ть о к н о , в к о т о р о м м о ж н о н а б л ю д а ть за п р о и с х о д я щ и м в н у т р и улья, и о к н о<br />

с и з о б р а ж <strong>е</strong> н и <strong>е</strong> м ц в <strong>е</strong> т о ч н о г о п о л я , н а к о т о р о м п ч <strong>е</strong> л ы с о б и р а ю т н <strong>е</strong> к т а р .<br />

Постро<strong>е</strong>нная<br />

?я Аликродиспл<strong>е</strong>-<strong>е</strong>м<br />

наш <strong>е</strong>го с и м у л я ­<br />

т о р а .<br />

^ B eeteveSm uiebr<br />

Pause «m utatton Res^<br />

#Boes 6<br />

SRonwfS 11<br />

І|вІ ^<br />

Totai nectarine» fidd 3 4 - ^<br />

Rwneatun 983<br />

frame (Bte<br />

1€^б2.5ги)<br />

kle:1bee<br />

f^ngToRower: 2 bees<br />

HetumrigToHive: 2bees<br />

Bee #1; Idle<br />

Эт о окно показыва<strong>е</strong>т<br />

происходящ<strong>е</strong><strong>е</strong> внутри<br />

улья.<br />

В эт ом окн<strong>е</strong> вы<br />

видит<strong>е</strong> цв<strong>е</strong>точно<strong>е</strong><br />

пол<strong>е</strong> и собираюш^их<br />

н<strong>е</strong>кт ар пч<strong>е</strong>л. " — ^<br />

^О'^^Рки<strong>е</strong> окна, при<br />

сворачивании осЯ^вно -<br />

го окна они исч<strong>е</strong>зают.<br />

К р о м <strong>е</strong> того, они сл<strong>е</strong>дик>т<br />

зд основным окном<br />

при <strong>е</strong>го п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ниях<br />

по экрану.<br />

О<br />

Заставим работать кнопку Print<br />

О к н о с т а т и с т и к и и м <strong>е</strong> <strong>е</strong> т р а б о т а ю щ и <strong>е</strong> к н о п к и O p e n и Save, в т о в р <strong>е</strong> м я к а к к н о п к а P r in t п о к а н <strong>е</strong><br />

ф у н к ц и о н и р у <strong>е</strong> т . С д <strong>е</strong> л а <strong>е</strong>м т а к , ч т о б ы щ <strong>е</strong> л ч о к н а н <strong>е</strong> й п р и в о д и л к р а с п <strong>е</strong> ч а т к <strong>е</strong> д <strong>е</strong> й с т в и й сим у л я ­<br />

т о р а .<br />

Beehive Simuiator<br />

Pause simulation Reset ^ ^<br />

#Є<strong>е</strong><strong>е</strong>з 6<br />

#Fl0wers 11<br />

Te«dhone>'inthehive 1.200_<br />

576 гл а в а 13


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и г р а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

О О кно Hive<br />

П ч <strong>е</strong> л ы л <strong>е</strong> т а ю т п о вс<strong>е</strong>м у п р о с т р а н с т в у с и м у л я то р а . К о г д а о н и<br />

з а л <strong>е</strong> т а ю т в у л <strong>е</strong> й , п р о и с х о д я щ <strong>е</strong> <strong>е</strong> о т о б р а ж а <strong>е</strong> т с я в э т о м о к н <strong>е</strong> .<br />

The Hive<br />

Сбор н<strong>е</strong>ктара происходит в окн<strong>е</strong> Field<br />

О с н о в н ы м з а н я т и <strong>е</strong> м п ч <strong>е</strong> л я в л я <strong>е</strong> т с я с б о р н <strong>е</strong> к т а р а , к о т о р ы й<br />

б уд<strong>е</strong>т п <strong>е</strong> р <strong>е</strong> р а б о т а н в м <strong>е</strong>д. П о <strong>е</strong> д а н и <strong>е</strong> э т о г о м <strong>е</strong>да д а <strong>е</strong> т п ч <strong>е</strong> л а м<br />

э н <strong>е</strong> р г и ю для с б о р а н о в о го н <strong>е</strong> к т а р а .<br />

В уль<strong>е</strong> выд<strong>е</strong>л<strong>е</strong>ны м ри точки. Пч<strong>е</strong>лы п о ­<br />

являются в пит омник<strong>е</strong>, пользуются<br />

выходом, когда приходит вр<strong>е</strong>мя л <strong>е</strong>­<br />

т <strong>е</strong>т ь на цв<strong>е</strong>точно<strong>е</strong> пол<strong>е</strong>, зат <strong>е</strong>м они<br />

(юзора1ц аю т ся и от правляют ся на<br />

срадрику по п<strong>е</strong>р<strong>е</strong>работ к<strong>е</strong> н<strong>е</strong>ктара.<br />

Выход из улья находится в ф о р ­<br />

м<strong>е</strong> hive, а вход - в ф о р т held.<br />

(П оэт ом у оба знач<strong>е</strong>ния были п о ­<br />

м<strong>е</strong>щ<strong>е</strong>ны о словарь.)<br />

\<br />

Эт о вход в ул<strong>е</strong>й. /Достигнув<br />

этой точки,<br />

пч<strong>е</strong>лы исч<strong>е</strong>зают с поля<br />

и появляются у выхода<br />

в окн<strong>е</strong> hive.<br />

д а л ь ш <strong>е</strong> у 577


з а м <strong>е</strong> ч а т <strong>е</strong> л ь н о <strong>е</strong> п р <strong>е</strong> д с т а в л <strong>е</strong> н и <strong>е</strong><br />

Визуализатор<br />

Н а м т р <strong>е</strong> б у <strong>е</strong> т с я кл а сс , к о т о р ы й н а о с н о в <strong>е</strong> и н ф о р м а ­<br />

ц и и и з н а ш <strong>е</strong> г о м и р а буд<strong>е</strong>т р и с о в а т ь в двух н о в ы х<br />

ф о р м а х у л <strong>е</strong> й п ч <strong>е</strong> л и ц в <strong>е</strong> ты . С э т о й задач<strong>е</strong>й о т л и ч н о<br />

с п р а в и т с я кл а сс Я <strong>е</strong> п д <strong>е</strong> г <strong>е</strong> г . Б л а го д а р я и н к а п с у л я ­<br />

ц и и у ж <strong>е</strong> и м <strong>е</strong> ю щ и х с я кл а сс о в н а м н <strong>е</strong> п о т р <strong>е</strong> б у <strong>е</strong> т с я<br />

с и л ь н о м <strong>е</strong> н я т ь ко д .<br />

Эт и о б ш к т ы у ж <strong>е</strong> пост ро<strong>е</strong>ны .<br />

О бъ<strong>е</strong>кт W orld отсл<strong>е</strong>жива<strong>е</strong>т вс<strong>е</strong>. ч т о ^<br />

состояни<strong>е</strong><br />

улья, каждой пч<strong>е</strong>лы и каждого цв<strong>е</strong>тка<br />

Эт от объ<strong>е</strong>кт зада<strong>е</strong>т<br />

главно<strong>е</strong> окно. Вы <strong>е</strong>го<br />

уж<strong>е</strong> построили.<br />

об ъ <strong>е</strong>кт ы Hive<br />

и Field являют<br />

ся ф орм а<br />

м и, связанны^<br />

ми с основной<br />

формой.<br />

в и -з у -а -л и -з и -р о -в а т ь , гл а г.<br />

пр<strong>е</strong>дставлять или изображать.<br />

Учит<strong>е</strong>ль попросил визуалижровать<br />

линии мод<strong>е</strong>ли на лист<strong>е</strong> бумаги.<br />

Визуализатор б<strong>е</strong>р<strong>е</strong>т<br />

информацию<br />

от объ<strong>е</strong>кта W orld<br />

и обновля<strong>е</strong>т дв<strong>е</strong> доч<strong>е</strong>рни<strong>е</strong><br />

формы.<br />

Каждая пч<strong>е</strong>ла зн а-<br />

<strong>е</strong>т сво<strong>е</strong> полож<strong>е</strong>ни<strong>е</strong><br />

о прост ранст в<strong>е</strong>,<br />

м ы ж<strong>е</strong> мож<strong>е</strong>м<br />

<strong>е</strong>го использовать,<br />

'^'^обы нарисовать<br />

пч<strong>е</strong>лу в форм<strong>е</strong>.<br />

Благодаря инкапсуляции<br />

классов<br />

В<strong>е</strong><strong>е</strong>, Hive, Flower<br />

и World добавл<strong>е</strong>ни<strong>е</strong><br />

класса, визуализирующ<strong>е</strong>го<br />

эти<br />

объ<strong>е</strong>кты, н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>т<br />

значит<strong>е</strong>льного<br />

р<strong>е</strong>дактирования<br />

кода.<br />

578 г л а в а 13


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и г р а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

формы для Визуализации<br />

О бъ<strong>е</strong>кт W o rld отсл<strong>е</strong>ж ива<strong>е</strong>т вс<strong>е</strong> происходящ <strong>е</strong><strong>е</strong> в сим улятор<strong>е</strong>, н о н<strong>е</strong> в состоян и и наглядно показать р<strong>е</strong>зультат.<br />

Эту работу вы полня<strong>е</strong>т объ<strong>е</strong>кт R e n d e r e r . О н счи ты ва<strong>е</strong>т инф орм ац и ю с объ<strong>е</strong>ктов W o rld , H iv e ,<br />

B ee и F lo w e r и пр<strong>е</strong>дставля<strong>е</strong>т <strong>е</strong><strong>е</strong> в граф и ч<strong>е</strong>ском вид<strong>е</strong>.<br />

•состояни<strong>е</strong><br />

объ<strong>е</strong>ктов<br />

о б ъ <strong>е</strong> к т W orld инкапсулирован, поэт ом у<br />

объ<strong>е</strong>кт R en d erer использу<strong>е</strong>т для получ<strong>е</strong>ния<br />

информации свойства этого объ<strong>е</strong>кта<br />

и вс<strong>е</strong>х, объ<strong>е</strong>ктов, которы<strong>е</strong> с ним связаны.<br />

Визуализиру<strong>е</strong>тся каждый кадр<br />

В ы званны й основн ой ф орм ой м<strong>е</strong>тод Go () объ<strong>е</strong>кта W orld долж <strong>е</strong>н вы зы вать м<strong>е</strong>тод R e n d e r () объ<strong>е</strong>кта<br />

R en d erer для обновл<strong>е</strong>ния граф и ч<strong>е</strong>ской и н ф орм ац и и . Ц в<strong>е</strong>ты отображ аю тся п ри пом ощ и эл<strong>е</strong>м <strong>е</strong>нта<br />

P ic tu r e B o x . Д ля пч<strong>е</strong>л мы создадим ан и м и рован н ы й эл<strong>е</strong>м <strong>е</strong>нт управл<strong>е</strong>ния B e e C o n tr o l.<br />

д а л ь ш <strong>е</strong> ► 579


у п р а в л я <strong>е</strong> м г р а ф и ч <strong>е</strong> с к и м и ф р а г м <strong>е</strong> н т а м и<br />

Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния пр<strong>е</strong>красно подходят для визуализации<br />

С о з д а н и <strong>е</strong> н о в о й п ч <strong>е</strong> л ы д о л ж н о с о п р о в о ж д а т ь с я п о я в л <strong>е</strong> н и <strong>е</strong> м н о в о го э л <strong>е</strong> м <strong>е</strong> н ­<br />

т а B e e C o n tr o l в ф о р м <strong>е</strong> о б ъ <strong>е</strong> к т а H iv e . Э т о т э л <strong>е</strong> м <strong>е</strong> н т буд<strong>е</strong>т м <strong>е</strong> н я т ь п о л о ж <strong>е</strong> н и <strong>е</strong><br />

п р и п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> щ <strong>е</strong> н и я х п ч <strong>е</strong> л ы . В ы л <strong>е</strong> т и з улья о з н а ч а <strong>е</strong> т у д а л <strong>е</strong> н и <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т а и з ф о р ­<br />

м ы H iv e и д о б а в л <strong>е</strong> н и <strong>е</strong> <strong>е</strong> го в ф о р м у F i e l d . В о з в р а щ <strong>е</strong> н и <strong>е</strong> в у л <strong>е</strong> й с о п р о в о ж д а <strong>е</strong> т ­<br />

ся о б р а т н ы м п р о ц <strong>е</strong> с с о м . И вс<strong>е</strong> э т о в р <strong>е</strong> м я кр ы л ь я п ч <strong>е</strong> л ы д о л ж н ы д в и га ть с я . Э т у<br />

за д а ч у л <strong>е</strong> г к о р <strong>е</strong> ш и т ь п р и п о м о щ и э л <strong>е</strong> м <strong>е</strong> н т о в у п р а в л <strong>е</strong> н и я .<br />

Q П р и п о я в л <strong>е</strong> н и и н о в о й п ч <strong>е</strong> л ы с о зд а <strong>е</strong> тс я B e e C o n tr o l, к о т о р ы й<br />

д о б а в л я <strong>е</strong>тся в к о л л <strong>е</strong> к ц и ю C o n t r o l s ф о р м ы H iv e .<br />

Controls.Add(new BeeControl()<br />

О б ъ <strong>е</strong>^<br />

О<br />

П р и п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> щ <strong>е</strong> н и и п ч <strong>е</strong> л ы и з улья н а п о л <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т у д а л я <strong>е</strong> тс я и з<br />

к о л л <strong>е</strong> к ц и и C o n t r o l s улья и д о б а в л я <strong>е</strong> тся в о д н о и м <strong>е</strong> н н у ю к о л л <strong>е</strong> к ­<br />

ц и ю ф о р м ы F i e l d .<br />

о С<br />

о с т а р и в ш и с ь , п ч <strong>е</strong> л ы в ы х о д я т н а п <strong>е</strong> н с и ю . Е с л и п р и п р о в <strong>е</strong> р к <strong>е</strong><br />

о б ъ <strong>е</strong> к т о м R e n d e r e r с п и с к а B e e s о б н а р у ж и в а <strong>е</strong> т с я о т с у т с т в и <strong>е</strong> п ч <strong>е</strong> ­<br />

лы , о н уд а л я <strong>е</strong>т <strong>е</strong> <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т у п р а в л <strong>е</strong> н и я и з ф о р м ы H iv e .<br />

Q<br />

Controls.Remove(theBee<br />

580 гл а в а 13


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и г р а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

^ з ь м и в руку карандаш_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br />

О пр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong> назнач<strong>е</strong>ни<strong>е</strong> каждого из ф рагм<strong>е</strong>нтов кода. Вс<strong>е</strong> эти<br />

ф рагм<strong>е</strong>нты принадл<strong>е</strong>жат форм<strong>е</strong>.<br />

this. Controls. Add (new ButtonO); ................................<br />

Form2 childWindow = new Form2(); .......................................<br />

childWindow.Backgroundlmage = .................................<br />

Properties.Resources.Mosaic; .................................<br />

childWindow.BackgroundlmageLayout = .................................<br />

ImageLayout.Tile; .......................................<br />

C h i l d W i n d o w .S h o w (); .......................................<br />

ф о р м й снабж<strong>е</strong>на эл<strong>е</strong>м <strong>е</strong>нт ом ListBox<br />

для добавл<strong>е</strong>ния эл<strong>е</strong>м <strong>е</strong>нт ов в список можно<br />

использоват ь м <strong>е</strong>т од AddRangeQ.<br />

Label rayLabel = new L a b e l {); ^ .......................................<br />

myLabel.Text = "Тво<strong>е</strong> любимо<strong>е</strong> животно<strong>е</strong>"; .......................................<br />

myLabel .Location = new P o i n t d O , 10); .......................................<br />

ListBox myList = new L i s t B o x (); .......................................<br />

m y L i s t .Items.AddRange( new o b j e c t [] .......................................<br />

{ "Кот", "П<strong>е</strong>с", "Рыбка", "Н<strong>е</strong>т" } ); .......................................<br />

myList.Location = new Point(10, 40);<br />

^<br />

Controls .Add (myLabel) ;<br />

controls .Add (myList) ;<br />

иоъяснят ь назнач<strong>е</strong>ни<strong>е</strong> каждой<br />

Строки н<strong>е</strong> т р<strong>е</strong>бу<strong>е</strong>т ся, достаточно<br />

записат ь, какую функцию вы полня<strong>е</strong>т<br />

ф рагм <strong>е</strong>нт .<br />

Label controlToRemove = null; .......................................<br />

foreach (Control control in Controls) { .......................................<br />

}<br />

if (control is Label .......................................<br />

&& control.Text == "Bobby") .......................................<br />

controlToRemove = control as Label; ......................................<br />

C o n t r o l s .Remove (controlToRemove) ;<br />

controlToRemove.Dispose О ;<br />

Что получится, <strong>е</strong>сли т ак сд<strong>е</strong>лат ь, вы мож<strong>е</strong>т<strong>е</strong><br />

посм от р<strong>е</strong>т ь сами. Попытайт<strong>е</strong>сь понять, поч<strong>е</strong>м<br />

у получа<strong>е</strong>тся им<strong>е</strong>нно такой р<strong>е</strong>зульт ат !<br />

Дополнит<strong>е</strong>льны й вопрос: Как вы дум а<strong>е</strong>т<strong>е</strong>,<br />

поч<strong>е</strong>му оп<strong>е</strong>ратор c o n t r o l s . R em ove () н<strong>е</strong><br />

бы л пом <strong>е</strong>щ <strong>е</strong>н в цикл foreach?<br />

д а л ь ш <strong>е</strong> ► 581


\шг \ж<strong>е</strong> \щг<br />

/ш\ Уш\ / П Уш\щшш<br />

ОЗЬМИ в руку карандаш<br />

'<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот какую ф ункцию выполня<strong>е</strong>т каждый из ф рагм<strong>е</strong>нтов кода:<br />

this .Controls .Add (new ButtonO) ;<br />

Form2 childWindow = new Form2();<br />

childWindow.Backgroundlmage =<br />

Properties.Resources.Mosaic;<br />

childWindow.BackgroundlmageLayout =<br />

ImageLayout.Tile;<br />

childWindow.ShowO ;<br />

Созда<strong>е</strong>м кнопку и добавля<strong>е</strong>м <strong>е</strong><strong>е</strong> к форм<strong>е</strong>.<br />

Им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ния по умолчанию (наприм<strong>е</strong>р,<br />

сбойсмво Text буд<strong>е</strong>т пусм ы м ).<br />

Созда<strong>е</strong>мся вторая ф орм а Рогм 2,<br />

загруж а<strong>е</strong>мся фоново<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong><br />

из файла Mosaic, ком оро<strong>е</strong> заполня<strong>е</strong>м<br />

ёсю ф орм у. З ам <strong>е</strong>м получ<strong>е</strong>нно<strong>е</strong> окно<br />

Ь<strong>е</strong>м онсм риру<strong>е</strong>м ся пользовам<strong>е</strong>лю...................<br />

Label myLabel = new LabelO;<br />

myLabel.Text = "Тво<strong>е</strong> любимо<strong>е</strong> животно<strong>е</strong>";<br />

myLabel.Location = new PointdO, 10);<br />

ListBox myList = new ListBox();<br />

myList.Items.AddRange( new object []<br />

{ "Кот", "П<strong>е</strong>с", "Рыбка", "Н<strong>е</strong>т" } );<br />

myList.Location = new PointdO, 40);<br />

Controls.Add(myLabel);<br />

Controls.Add(myList);<br />

Label controlToRemove = null;<br />

foreach (Control control in Controls) {<br />

if (control is Label<br />

&& control.Text == "Bobby")<br />

controlToRemove = control as Label;<br />

}<br />

Controls.Remove(controlToRemove);<br />

controlToRemove.Dispose();<br />

Созда<strong>е</strong>мся м <strong>е</strong>м ка, зада<strong>е</strong>мся <strong>е</strong><strong>е</strong> м <strong>е</strong> к с м<br />

и полож<strong>е</strong>ни<strong>е</strong>. З ам <strong>е</strong>м созда<strong>е</strong>мся<br />

м<strong>е</strong>кст ово<strong>е</strong> пол<strong>е</strong>, в н<strong>е</strong>го добавляются<br />

ч<strong>е</strong>м ы р<strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т а , и пол<strong>е</strong> пом <strong>е</strong>щ а<strong>е</strong>м ся<br />

под м <strong>е</strong>м кой. М <strong>е</strong>м ка и м <strong>е</strong>ксм ово<strong>е</strong><br />

пол<strong>е</strong> добабляюмся к ф орм <strong>е</strong><br />

и ом ображ аюмся.<br />

Чт о произойд<strong>е</strong>т при<br />

о м сум ст вии эл<strong>е</strong>м<strong>е</strong>нта<br />

ВоЬВу в колл<strong>е</strong>кции<br />

Controls? '~ \<br />

и^икл просм ам рива<strong>е</strong>м вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

,!^правл<strong>е</strong>ния ф орм ы в поисках м<strong>е</strong>т ки<br />

с т <strong>е</strong>кст ом «ВоЬЬу». Посл<strong>е</strong> обнаруж <strong>е</strong>-<br />

ния м <strong>е</strong>т ка удаля<strong>е</strong>тся из формы.<br />

Попытавшись т ак сд<strong>е</strong>лать, вы получит<strong>е</strong><br />

исключ<strong>е</strong>ни<strong>е</strong>. В<strong>е</strong>дь наруш<strong>е</strong>ни<strong>е</strong> ц<strong>е</strong>лост ­<br />

ности колл<strong>е</strong>кции в<strong>е</strong>д<strong>е</strong>м к н<strong>е</strong>пр<strong>е</strong>дсказу -<br />

<strong>е</strong>мым р<strong>е</strong>зульт ат ам. Им<strong>е</strong>нно поэт ому<br />

использу<strong>е</strong>мся цикл for.<br />

Д ополнит<strong>е</strong>льны й вопрос: Как вы дум а<strong>е</strong>т<strong>е</strong>,<br />

поч<strong>е</strong>му оп<strong>е</strong>ратор C o n t r o l s . R em ove ()<br />

н<strong>е</strong> бы л пом <strong>е</strong>щ <strong>е</strong>н в цикл foreach?<br />

Колл<strong>е</strong>кции н<strong>е</strong>льзя р<strong>е</strong>дакм ировам ь<br />

.^fJP.^duHe цикла foreach.<br />

Ч/*<br />

^<br />

582 г л а в а 13


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и гр а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

П<strong>е</strong>рвый анимированный эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

М ы с о б и р а <strong>е</strong> м с я п о с т р о и т ь с о б с т в <strong>е</strong> н н ы й э л <strong>е</strong> м <strong>е</strong> н т у п р а в л <strong>е</strong> н и я с а н и м и р о в а н н ы м и з о б р а ж <strong>е</strong> н и <strong>е</strong> м п ч <strong>е</strong> ­<br />

лы . П о л у ч и т ь а н и м а ц и ю н <strong>е</strong> т а к т я ж <strong>е</strong> л о , к а к к а ж <strong>е</strong> т с я : р и с у <strong>е</strong> т с я р я д и з о б р а ж <strong>е</strong> н и й , к о т о р ы й п р и посл<strong>е</strong>д о ­<br />

в а т<strong>е</strong>л ь н ы м п о к а з <strong>е</strong> с о зд а<strong>е</strong>т и л л ю з и ю д в и ж <strong>е</strong> н и я . Э т о н <strong>е</strong> с л о ж н о сд <strong>е</strong>л ать с р <strong>е</strong> д с т в а м и C # и .N E T .<br />

каз<strong>е</strong><br />

изображ<strong>е</strong>ний возника<strong>е</strong>т иллюзия движ<strong>е</strong>ния к р ы л ь <strong>е</strong> в ‘^Р^^кта. При быст ром п о ­<br />

Пом<strong>е</strong>стим эл<strong>е</strong>м<strong>е</strong>нт б окно Toolbox<br />

Е с л и вы к о р р <strong>е</strong> к т н о п о с т р о и т <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т у п р а в л <strong>е</strong> ­<br />

н и я B e e C o n t r o l , т о с м о ж <strong>е</strong> т <strong>е</strong> п <strong>е</strong> р <strong>е</strong> т а с к и в а т ь <strong>е</strong> го<br />

н а ф о р м у и з о к н а T o o lb o x . О н вы глядит? к а к у ж <strong>е</strong><br />

з н а к о м ы й вам э л <strong>е</strong> м <strong>е</strong> н т P i c t u r e B o x , д <strong>е</strong> м о н с т р и ­<br />

р о в а в ш и й и з о б р а ж <strong>е</strong> н и <strong>е</strong> п ч <strong>е</strong> л ы , п р о с т о н а э т о т<br />

р а з к а р т и н к а а н и м и р о в а н а .<br />

T o o lb o x<br />

л \ B eeC ontro l on а fo rm C o m p o n e n ts<br />

P o in te r<br />

B e e C o n tro l -<br />

. £>.All vVindovvs Form s<br />

л C o m m o n C ontrols<br />

» D X<br />

—----------------------- □<br />

1*“ !<br />

Скачать изображ<strong>е</strong>ния для этой<br />

главы можно по адр<strong>е</strong>су:<br />

www.headfirstlabs.com / books/<br />

hfcsharp/<br />

Если<br />

КЛЙСС<br />

(„,.д„1ллля О том,<br />

‘ F o rm l<br />

P o in te r<br />

1 B u tto n<br />

k i C heckB ox<br />

H C h eckedL istB ox w<br />

я в л ,<strong>е</strong> т „<br />

i<br />

i<br />

B u C o n tro l<br />

д а л ь ш <strong>е</strong> ► 583


п о л ь з о в а т <strong>е</strong> л ь с к и <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и я<br />

Базовый класс PictureBox<br />

Т а к к а к вс<strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т ы в о к н <strong>е</strong> to o lb o x я в л я ю тс я о б ъ <strong>е</strong> к т а м и , п о л у ч и т ь<br />

н о в ы й э л <strong>е</strong> м <strong>е</strong> н т л <strong>е</strong> гк о . Д о с т а т о ч н о д о б а в и ть к п р о <strong>е</strong> к т у кл а сс, насл <strong>е</strong>д у­<br />

ю щ и й о т о д н о го и з с у щ <strong>е</strong> с тв у ю щ и х кл а сс о в , задав з а т<strong>е</strong> м п о в <strong>е</strong> д <strong>е</strong> н и <strong>е</strong> н о ­<br />

в о го э л <strong>е</strong> м <strong>е</strong> н та .<br />

П р и с в о и м н о в о м у э л <strong>е</strong> м <strong>е</strong> н ту у п р а в л <strong>е</strong> н и я и м я B e e C o n t r o l. С н а ч а л а<br />

с в я ж <strong>е</strong> м с н и м с т а т и ч н у ю к а р т и н к у , к к о т о р о й п о т о м б уд<strong>е</strong>т д о б а в л <strong>е</strong> н а<br />

а н и м а ц и я , т о <strong>е</strong> с ть н а ч н <strong>е</strong> м с у ж <strong>е</strong> з н а к о м о г о э л <strong>е</strong> м <strong>е</strong> н т а P i c t u r e B o x .<br />

%<br />

%<br />

Днимиру<br />

*<br />

й ш <strong>е</strong> э щ о<br />

Создайт<strong>е</strong> новый про<strong>е</strong>кт и д о б ав ь т<strong>е</strong> к <strong>е</strong> го р <strong>е</strong> с у р с а м ч <strong>е</strong> т ы р <strong>е</strong> а н и м и р о в а н н ы <strong>е</strong> я ч <strong>е</strong> й к и . П о м ­<br />

н и т <strong>е</strong> , к а к вы д о б ав л я л и л о г о т и п о б ъ <strong>е</strong> к т в и л ь с к о й к о м п а н и и в глав<strong>е</strong> 1? Н о в д а н н о м случа<strong>е</strong><br />

вас и н т <strong>е</strong> р <strong>е</strong> с у ю т н <strong>е</strong> р <strong>е</strong> сурсы формы, а р <strong>е</strong> сурс ы про<strong>е</strong>кт а. Н а й д и т <strong>е</strong> ф а й л R esources.resx про<strong>е</strong>кта<br />

в о к н <strong>е</strong> S o lu tio n E x p lo r e r (к а к п о к а з а н о н а р и с у н к <strong>е</strong> ) и д в аж д ы щ <strong>е</strong> л к н и т <strong>е</strong> н а н <strong>е</strong> м д ля<br />

п <strong>е</strong> р <strong>е</strong> х о д а н а в кл а д ку R esources.<br />

8 глйб<strong>е</strong> 1 М(з( добавляли логот<br />

ип к файлу ф орм ы Resources.<br />

На эт от р а з изображ<strong>е</strong>ния<br />

будут добавл<strong>е</strong>ны в общук)<br />

к о л л <strong>е</strong> кц и ю р<strong>е</strong>сурсов, благодаря<br />

ч<strong>е</strong>му они ст анут доступны<br />

для вс<strong>е</strong>х классов про<strong>е</strong>кта.<br />

В<strong>е</strong>рнит<strong>е</strong>сь к глав<strong>е</strong> 1 , чтобы всп ом ­<br />

нить, каким образом вы эт о сд<strong>е</strong>лали.<br />

Solution Explorer<br />

J з BeeControl o m rfo n<br />

л Щг Properties<br />

'ї ї Assemblylnfo.cs<br />

1> ІІІ^ ReSOU№№jräil<br />

:> Settings.settirrgs<br />

feÜ References<br />

l3I Resources<br />

Ш Forml.cs<br />

'5^ Program.cs<br />

■ 'П К<br />

Изображ<strong>е</strong>ния<br />

дудут доступны<br />

ОЛЯ вс<strong>е</strong>го про<strong>е</strong>кт а,<br />

« н<strong>е</strong> только для<br />

■ формы.<br />

Дважды щ <strong>е</strong>лкнит<br />

<strong>е</strong> на ст рочк<strong>е</strong><br />

Resources.resx для<br />

^ п<strong>е</strong>р<strong>е</strong>хода НЛ вКАйдку<br />

Resources.<br />

о И з о б р а ж <strong>е</strong> н и я п ч <strong>е</strong> л ы вы м о ж <strong>е</strong> т <strong>е</strong> с к а ч а т ь п о ад р <strong>е</strong> су h ttp://w w w .headfirstlabs.com /books/<br />

hfcsharp/. З а т <strong>е</strong> м в в <strong>е</strong> р х н <strong>е</strong> й ч а с т и в кл а д к и R esources в ы б <strong>е</strong> р и т <strong>е</strong> в п <strong>е</strong> р в о м р а с к р ы в а ю щ <strong>е</strong> м с я<br />

с п и с к <strong>е</strong> в а р и а н т Im a g e s , а в с п и с к <strong>е</strong> A d d R e s o u rc e в а р и а н т A d d E x is tin g F ile ...<br />

584<br />

Bee animation l.png<br />

г л а в а 13<br />

Bee animation 2.png<br />

Bee animation 3.png<br />

Импортируйт<strong>е</strong> эт и изображ<strong>е</strong>ния<br />

и доШ ьт <strong>е</strong> их к р<strong>е</strong>сурсам<br />

сво<strong>е</strong>го про<strong>е</strong>кта.<br />

В<strong>е</strong><strong>е</strong> animation 4.png


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и г р а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

О Д о с т у п к д о б а в л <strong>е</strong> н н ы м р <strong>е</strong> с у р с а м о с у щ <strong>е</strong> с тв л я <strong>е</strong> т с я п о с р <strong>е</strong> д с тв о м кл а с с а<br />

P r o p e r t i e s .Resources. В в <strong>е</strong> д и т <strong>е</strong> в п р о и з в о л ь н о м м <strong>е</strong> с т <strong>е</strong> к о д а P r o p e r t i e s .<br />

R e s o u r c e y r ~ ^ , H о к н о In te lliS e n s e п о к а ж <strong>е</strong> т р а с к р ы в а ю щ и й с я с п и с о к со в с<strong>е</strong> м и<br />

Добавим эл<strong>е</strong>м<strong>е</strong>нт BeeControl!<br />

class BeeControl : PictureBox {<br />

private Timer an im ation T im er =<br />

им <strong>е</strong>нно она указы ва<strong>е</strong>м И С Р на<br />

н<strong>е</strong>обходимость вызвать окно с<br />

м ы<br />

програм м ы мзо<br />

браж<strong>е</strong>ни<strong>е</strong> хранят ­<br />

ся в памят и как<br />

объ<strong>е</strong>кты Bitmap-<br />

I<br />

pictureBoxl.Image =<br />

Properties.Resources.Bee_animation_l;<br />

Зд<strong>е</strong>сь указыва<strong>е</strong>тся изображ<strong>е</strong>ни<strong>е</strong>,<br />

связанно<strong>е</strong> с эл<strong>е</strong>м<strong>е</strong>нт ом PictureBox<br />

(в данном случа<strong>е</strong> наил<strong>е</strong> начально<strong>е</strong><br />

изображ<strong>е</strong>ни<strong>е</strong>).<br />

Эти изображ<strong>е</strong>ния<br />

хранят ся в вид<strong>е</strong><br />

с Ы с т в а общ<strong>е</strong>го<br />

дост упа класса<br />

P ro p erties. Resources.<br />

new Timer()<br />

public BeeControl() {<br />

уб<strong>е</strong>дит <strong>е</strong>сь, animationTimer.Tick += new EventHandler(animationTimer_Tick)<br />

что в в<strong>е</strong>рхн<strong>е</strong>й animationTimer.Interval = 150;<br />

части класса<br />

находит ­<br />

animationTimer.Start 0;<br />

ся ст рочка BackColor = System.Drawing.Color.Transparent;<br />

«using System. BackgroundlmageLayout = ImageLayout.Stretch;<br />

Windows. J<br />

fo rm s» .<br />

private int cell = 0;<br />

void animationTimer_Tiok(object sender,<br />

cell++;<br />

Каждый от сч<strong>е</strong>т switch (cell) {<br />

т айм<strong>е</strong>ра вы ­<br />

зыва<strong>е</strong>т событи<strong>е</strong>,<br />

оно ув<strong>е</strong>личива<strong>е</strong>т<br />

знач<strong>е</strong>ни<strong>е</strong> п <strong>е</strong> р <strong>е</strong> ­<br />

м<strong>е</strong>нной cell на<br />

1 , и при п о м о­<br />

щи оп<strong>е</strong>рат ора<br />

sw itch назнача<strong>е</strong>т^<br />

карт инку свойст<br />

ву Image. }<br />

Нужно добавить с т т ч -<br />

^ y / j s i n g System. ^<br />

M n dow s-Form s», т ак<br />

как б про<strong>е</strong>кт <strong>е</strong> при -<br />

^ ^ с т в у ю т эл<strong>е</strong>м<strong>е</strong>нты<br />

PictureBox и Tim er.<br />

Зд<strong>е</strong>сь т айм<strong>е</strong>ру<br />

присваивают -<br />

ся начальны<strong>е</strong><br />

знач<strong>е</strong>ния п у ­<br />

т <strong>е</strong>м создания<br />

<strong>е</strong>го экз<strong>е</strong>мпляра,<br />

задания свой -<br />

ства Interval<br />

и добавл<strong>е</strong>ния<br />

обработчика<br />

событий.<br />

Посл<strong>е</strong> возвращ<strong>е</strong>ния<br />

EventArgs <strong>е</strong>) { к кадру # 1, знач<strong>е</strong>ни<strong>е</strong><br />

парам <strong>е</strong>т ра cell с т а -<br />

^ новится равным О.<br />

Backgroundlmage Properties.Resources.Bee_animation_l; break;<br />

Backgroundlmage Properties.Resources.Bee_aniraation_2; break;<br />

Backgroundlmage Properties.Resources.Bee_animation_3; break;<br />

Backgroundlmage Properties.Resources.Bee_animation_4; break;<br />

Backgroundlmage Properties.Resources.Bee_aniraation_3; break;<br />

default: Backgroundlmage = Properties.Resources.Bee_animation_2;<br />

cell = 0; break;<br />

вв<strong>е</strong>дя код эл<strong>е</strong>м<strong>е</strong>нт а управл<strong>е</strong>ния, п<strong>е</strong>р<strong>е</strong>ст ройт <strong>е</strong> програм м у<br />

для отображ<strong>е</strong>ния изм<strong>е</strong>н<strong>е</strong>ний в конст рукт ор<strong>е</strong>.<br />

П остройт<strong>е</strong> программу. Э л <strong>е</strong> м <strong>е</strong> н т у п р а в л <strong>е</strong> н и я B e e C o n t r o l д о л ж <strong>е</strong> н п о я в и т ь с я в о к н <strong>е</strong><br />

to o lb o x . П <strong>е</strong> р <strong>е</strong> т а щ и т <strong>е</strong> <strong>е</strong> го н а ф орм у, и вы п о л у ч и т <strong>е</strong> анимированную п ч <strong>е</strong>лу!


у д а л <strong>е</strong> н и <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т о в у п р а в л <strong>е</strong> н и я<br />

Кнопка добавл<strong>е</strong>ния эл<strong>е</strong>м<strong>е</strong>нта BeeControl<br />

Д о б а в и т ь э л <strong>е</strong> м <strong>е</strong> н т у п р а в л <strong>е</strong> н и я к ф о р м <strong>е</strong> л <strong>е</strong> гк о , д о с т а т о ч н о д о б а в и ть <strong>е</strong> го в ко л л <strong>е</strong> к-<br />

ц и ю C o n t r o l s . Т а к ж <strong>е</strong> л <strong>е</strong> гк о о н удаля<strong>е</strong>тся и з ф о р м ы . Н о эл <strong>е</strong> м <strong>е</strong> н ты у п р а в л <strong>е</strong> н и я - ^ 7 ^ ^<br />

р <strong>е</strong> а л и з у ю т и н т <strong>е</strong> р ф <strong>е</strong> й с I D i s p o s a b l e , п о э т о м у с л <strong>е</strong> д и т<strong>е</strong> за в ы св о б о ж д <strong>е</strong> н и <strong>е</strong> м р<strong>е</strong>сур<br />

сов п о с л <strong>е</strong> удал <strong>е</strong>ния эл <strong>е</strong>м <strong>е</strong> н то в .<br />

О<br />

До^а6л<strong>е</strong>ин&1м<br />

б колл<strong>е</strong>кцию<br />

Controls<br />

эл<strong>е</strong>м<strong>е</strong>нт<br />

н<strong>е</strong>м<strong>е</strong>дл<strong>е</strong>нно<br />

появля<strong>е</strong>тся<br />

на форм<strong>е</strong>.<br />

Удалит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт BeeControl с формы и добавьт<strong>е</strong> кнопку<br />

^<br />

О т к р о й т <strong>е</strong> к о н с т р у к т о р ф о р м и удал и т<strong>е</strong> эл <strong>е</strong>м <strong>е</strong> н т B e e C o n t r o l. Д о б а в ь т <strong>е</strong> к ф о р м <strong>е</strong> к н о п к у<br />

С д <strong>е</strong> л а <strong>е</strong>м т а к , ч т о б ы о н а у п р а в л я л а п о я в л <strong>е</strong> н и <strong>е</strong> м и и с ч <strong>е</strong> з н о в <strong>е</strong> н и <strong>е</strong> м э л <strong>е</strong> м <strong>е</strong> н т а B e e C o n t r o l .<br />

Код управляю щ <strong>е</strong>й кнопки<br />

В о т к а к в ы гл я д и т о б р а б о т ч и к с о б ы т и й д ля к н о п к и ;<br />

BeeControl control = null;<br />

private void buttonl_Click(object sender, EventArgs e) { /<br />

if (control == null) {<br />

^<br />

control = new BeeControl0 { Location = new Point(100, 100)<br />

^ C o n tr o ls . Add ( c o n tr o l) ;<br />

}<br />

} else {<br />

u s in g ( c o n tr o l) {<br />

C o n tr o ls .R e m o v e (c o n tr o l);<br />

}<br />

}<br />

control = null;<br />

^<br />

Вы использу<strong>е</strong>т<strong>е</strong><br />

инициализатор для<br />

задания свойств<br />

BeeControl посл<strong>е</strong> создания<br />

<strong>е</strong>го экз<strong>е</strong>мпляра.<br />

О п<strong>е</strong>рат ор using гарант иру<strong>е</strong>т вы ­<br />

свобожд<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>сурсов посл<strong>е</strong> удал<strong>е</strong>ния<br />

эл<strong>е</strong>м<strong>е</strong>нта из колл<strong>е</strong>кции Controls.<br />

З а п у с т и т <strong>е</strong> п р о гр а м м у . П <strong>е</strong> р в ы й щ <strong>е</strong> л ч о к н а к н о п к <strong>е</strong> д о л ж <strong>е</strong> н д о б а в л я ть э л <strong>е</strong> м <strong>е</strong> н т B e e C o n t r o l .<br />

П р и в т о р о м щ <strong>е</strong> л ч к <strong>е</strong> э л <strong>е</strong> м <strong>е</strong> н т у д а л я <strong>е</strong> тся. С с ы л ка н а н <strong>е</strong> г о х р а н и т с я в з а к р ы т о м п о л <strong>е</strong> c o n t r o l .<br />

П р и и с ч <strong>е</strong> з н о в <strong>е</strong> н и и э л <strong>е</strong> м <strong>е</strong> н т а о н а у ка зы в а <strong>е</strong> т н а з н а ч <strong>е</strong> н и <strong>е</strong> n u ll.<br />

} ;<br />

Toolbox<br />

[ j i BeeControt on 3 form С о тр о п ^<br />

Pointer<br />

BeeControl<br />

_;> All W indows Forms<br />

J» C om m on Controls<br />

Pointer<br />

fab] Button<br />

0 CheckBox<br />

H CheckedListBox<br />

Чтобы добавить эл<strong>е</strong>м<strong>е</strong>нт<br />

в окно toolbox, создайт<strong>е</strong><br />

класс, производный от<br />

класса Control.<br />

с Д <strong>е</strong> н о й<br />

Вс<strong>е</strong> визуальны<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты в окн<strong>е</strong> Toolbox<br />

насл<strong>е</strong>дуют от S y s te m .W in d o w s . Form s .<br />

C o n t r o l. Чл<strong>е</strong>ны этого класса вам уж<strong>е</strong><br />

знакомы; v i s i b l e , w id th , H e ig h t , T e x t,<br />

L o c a t i o n , B a c k C o lo r , B a c k g r o u n d lm a g e ...<br />

ВЫ ИХ видит<strong>е</strong> в окн<strong>е</strong> Properties для вс<strong>е</strong>х эл<strong>е</strong>м<strong>е</strong>нтов<br />

управл<strong>е</strong>ния.<br />

586 глава 13


э л <strong>е</strong> м <strong>е</strong> н т ы у п р а в л <strong>е</strong> н и <strong>е</strong> и г р а ф и ч <strong>е</strong> с к и <strong>е</strong> ф р а г м <strong>е</strong> н т ы<br />

Удал<strong>е</strong>ни<strong>е</strong> доч<strong>е</strong>рних эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

О т р а б о т а в , э л <strong>е</strong> м <strong>е</strong> н ты у п р а в л <strong>е</strong> н и я д о л ж н ы в ы с в о б о ж д а ть р <strong>е</strong>сурсы .<br />

Н о э л <strong>е</strong> м <strong>е</strong> н т B e e C o n tr o l с о зд а <strong>е</strong> т э к з <strong>е</strong> м п л я р э л <strong>е</strong> м <strong>е</strong> н т а T im e r ... к о ­<br />

т о р ы й о с т а <strong>е</strong> т с я н <strong>е</strong> уд а л <strong>е</strong>н н ы м ! К с ч а с ть ю , э ту п р о б л <strong>е</strong> м у л <strong>е</strong> г к о р <strong>е</strong> ­<br />

ш и т ь — д о с т а т о ч н о п <strong>е</strong> р <strong>е</strong> к р ы т ь м <strong>е</strong> то д D is p o s e {).<br />

О<br />

К л а с с эл<strong>е</strong>м<strong>е</strong>нтов у п р а в ­<br />

л<strong>е</strong>ния р<strong>е</strong>ализу<strong>е</strong>т инт <strong>е</strong>рф<strong>е</strong>йс<br />

IDisposable, поэт о­<br />

м у нужно просл<strong>е</strong>дить,<br />

чтобы вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

удалялись, когда в них<br />

пропада<strong>е</strong>т надобность.<br />

П <strong>е</strong>р<strong>е</strong>кройт<strong>е</strong> м<strong>е</strong>тод bisposeO и удалит<strong>е</strong> тайм<strong>е</strong>р<br />

Н а ш кл а сс B e e C o n tr o l д о л ж <strong>е</strong> н о б л ад а ть у н а с л <strong>е</strong> д о в а н н ы м м <strong>е</strong> т о д о м D is p o s e ( ) . Д о с т а т о ч н о<br />

п <strong>е</strong> р <strong>е</strong> к р ы т ь и р а с ш и р и т ь э т о т м <strong>е</strong> то д . В в <strong>е</strong> д и т <strong>е</strong> в к о д кл а с с а к л ю ч <strong>е</strong> в о <strong>е</strong> слово o v e r r i d e :<br />

class BeeControl : PictureBox {<br />

o v e r r id e<br />

D1sfKee(booS disposing)<br />

r Dock {ge^ set;}<br />

DoybleBuffered {get; set;}<br />

i # Equals(object obj)<br />

^ Focused {get; }<br />

Font {get; set;}<br />

^ ForeCotor {ge^ set;}<br />

1% GetAccessibilityObjectByldOnt objectid)<br />

Посл<strong>е</strong> вв<strong>е</strong>д<strong>е</strong>ния ключ<strong>е</strong>вого<br />

слова override появит ся<br />

от о IntelliSense с «а<strong>е</strong>р<strong>е</strong>чк<br />

ю ы т и я м <strong>е</strong> т о д о в , в ы д <strong>е</strong> р и<br />

т <strong>е</strong> м <strong>е</strong>т од PisposeQ.<br />

И С Р в в <strong>е</strong> д <strong>е</strong> т с т р о ч к у b a s e . D is p o s e ( ) , к о т о р о й б уд<strong>е</strong>т вы зы в ать ся д а н н ы й м <strong>е</strong>то д :<br />

protected override void Dispose(bool disposing) {<br />

base.Dispose(disposing);<br />

}<br />

Код удал<strong>е</strong>ния тайм<strong>е</strong>ра<br />

Д о б а в ь т <strong>е</strong> в к о н <strong>е</strong> ц н о в о го м <strong>е</strong> т о д а D is p o s e () ко д , в ы зы в а ю щ и й м <strong>е</strong>­<br />

т о д a n im a tio n T im e r .D is p o s e О , к о гд а а р гу м <strong>е</strong> н т d i s p o s i n g и м <strong>е</strong> ­<br />

<strong>е</strong> т з н а ч <strong>е</strong> н и <strong>е</strong> tru e .<br />

protected override void Dispose(bool disposing) {<br />

base .Dispose (disposing) ; .<br />

^ Мы п<strong>е</strong>р<strong>е</strong>крыва<strong>е</strong>м n o-<br />

}<br />

i f (d is p o s in g ) {<br />

a n im a tio n T im e r .D isp o se О ;<br />

Т <strong>е</strong> п <strong>е</strong> р ь э л <strong>е</strong> м <strong>е</strong> н т B e e C o n tr o l у б и р а <strong>е</strong> т за с о б о й !<br />

м<strong>е</strong>ч<strong>е</strong>нный ключ<strong>е</strong>вым<br />

словом, protected м<strong>е</strong>тод<br />

DisposeQ, вызыва<strong>е</strong>мый<br />

р<strong>е</strong>ализаии<strong>е</strong>й м<strong>е</strong>тода<br />

IDisposable.DisposeQ эл<strong>е</strong>м<strong>е</strong>нта<br />

управл<strong>е</strong>ния.<br />

П р о в <strong>е</strong> р ь т <strong>е</strong> сам и . Добавьт<strong>е</strong> точку останова в в с т а в л <strong>е</strong> н н у ю с т р о ч к у<br />

и з а п у с т и т <strong>е</strong> п р о гр а м м у . П р и к а ж д о м у д а л <strong>е</strong> н и и э л <strong>е</strong> м <strong>е</strong> н т а B e e C o n tr o l<br />

и з к о л л <strong>е</strong> к ц и и C o n t r o l s буд<strong>е</strong>т вы зы в ать ся м <strong>е</strong> т о д D is p o s e ().<br />

Любой созданный<br />

вами<br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

долж<strong>е</strong>н<br />

удалять вс<strong>е</strong><br />

порожд<strong>е</strong>нны<strong>е</strong><br />

им эл<strong>е</strong>м<strong>е</strong>нты<br />

и други<strong>е</strong> допускаюпщ<strong>е</strong><br />

удал<strong>е</strong>ни<strong>е</strong><br />

объ<strong>е</strong>кты.<br />

Если вы собира<strong>е</strong>т<strong>е</strong>сь создавать свои эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния, вам буд<strong>е</strong>т пол<strong>е</strong>зно<br />

прочитать мат<strong>е</strong>риалы с сайта ЬЦр://т5с1п.т1сг080Д.С0т/ги-ги/11Ьгагу/8У81<strong>е</strong>т.1а1вР05аЫ<strong>е</strong>.а15Р0$<strong>е</strong>.а50х<br />

д а л ь ш <strong>е</strong> > 587


создани<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

Класс UserControl<br />

Есть и бол<strong>е</strong><strong>е</strong> простой способ создания эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния для окна<br />

toolbox. Вм<strong>е</strong>сто того чтобы пользоваться классом, насл<strong>е</strong>дующим от сущ<strong>е</strong>ствующ<strong>е</strong>го<br />

эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния, вам нужно добавить в свой про<strong>е</strong>кт ^<br />

класс U s e rC o n tro l. Вы работа<strong>е</strong>т<strong>е</strong> с ним, как с формой, п<strong>е</strong>р<strong>е</strong>таскивая на<br />

'чк'тт тт<br />

н<strong>е</strong>го эл<strong>е</strong>м<strong>е</strong>нты из окна toolbox. И точно так ж<strong>е</strong>, как в случа<strong>е</strong> с формой вы ] 0 U 0 ,<br />

пользу<strong>е</strong>т<strong>е</strong>сь событиями. Поэтому заново создадим эл<strong>е</strong>м<strong>е</strong>нт B e e C o n t r o l , V/ m<br />

но уж<strong>е</strong> с помощью класса U s e r C o n t r o l .<br />

^<br />

О О ткройт<strong>е</strong> новый про<strong>е</strong>кт Windows Forms Application и добавьт<strong>е</strong> к <strong>е</strong>го р<strong>е</strong>сурсам ч<strong>е</strong>ты р<strong>е</strong> изображ<strong>е</strong>ния.<br />

П<strong>е</strong>р<strong>е</strong>тащ ит<strong>е</strong> на форму кнопку и вв<strong>е</strong>дит<strong>е</strong> изв<strong>е</strong>стный вам код, добавляющий и удаляющий<br />

эл<strong>е</strong>м<strong>е</strong>нт B e e C o n t r o l .<br />

© Щ <strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на им<strong>е</strong>ни про<strong>е</strong>кта в окн<strong>е</strong> Solution Explorer и выб<strong>е</strong>рит<strong>е</strong><br />

команду Add » User Control... Д обавьт<strong>е</strong> эл<strong>е</strong>м <strong>е</strong>нт B e e C o n tro l. Он буд<strong>е</strong>т откры т в конструктор<strong>е</strong><br />

форм.<br />

Используйт<strong>е</strong> м<strong>е</strong>тод animationTimerJTickQ и пол<strong>е</strong> cel! field<br />

^— из старой в<strong>е</strong>рсии эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния.<br />

А ^<br />

^ П<strong>е</strong>р<strong>е</strong>тащ ит<strong>е</strong> на ваш эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния эл<strong>е</strong>м<strong>е</strong>нт Timer. Назовит<strong>е</strong> <strong>е</strong>го a n im a tio n T im e r,<br />

свойству I n t e r v a l п рисвой т<strong>е</strong> зн ач<strong>е</strong>н и<strong>е</strong> 150, свойству E n a b le d - зн ач<strong>е</strong>н и<strong>е</strong> tru e. Дважды<br />

щ<strong>е</strong>лкнит<strong>е</strong> на тайм<strong>е</strong>р<strong>е</strong>, чтобы добавить обработчик события Tick. Используйт<strong>е</strong> для н<strong>е</strong>го<br />

тот ж<strong>е</strong> код, что и раньш<strong>е</strong>.<br />

О Обновит<strong>е</strong> конструктор эл<strong>е</strong>м<strong>е</strong>нта B e e C o n t r o l :<br />

М ;<br />

Эти изм<strong>е</strong>н<strong>е</strong>ния можно вн<strong>е</strong>сти<br />

^ и поср<strong>е</strong>дством окна Properties.<br />

I n i t i a l i z e C o m p o n e n t O ;<br />

}<br />

BackColor = System.Drawing.Color.Transparent;<br />

BackgroundlmageLayout = ImageLayout.Stretch;<br />

О Запустит<strong>е</strong> программу, кнопка должна работать так ж<strong>е</strong>, как и раньш<strong>е</strong>, просто т<strong>е</strong>п<strong>е</strong>рь <strong>е</strong>ю<br />

управля<strong>е</strong>т класс U s e r C o n t r o l . Им<strong>е</strong>нно он отв<strong>е</strong>ча<strong>е</strong>т за появл<strong>е</strong>ни<strong>е</strong> и удал<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нта<br />

B e e C o n t r o l .<br />

Класс UserControl позволя<strong>е</strong>т л<strong>е</strong>гко добавить эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

в окно Toolbox. Как и при работ<strong>е</strong> с формой, вы мож<strong>е</strong>т<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>таскивать на н<strong>е</strong>го други<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния и пользоваться<br />

событиями.<br />

588 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

О<br />

Z '<br />

-------^<br />

I С колько я ни пользовалась<br />

эл<strong>е</strong>м<strong>е</strong>нтам <strong>е</strong>нтам и управл<strong>е</strong>ния, м н<strong>е</strong><br />

ни разу н<strong>е</strong> п р и хо д и л о сь и х удалять!<br />

Зач<strong>е</strong>м это вообщ <strong>е</strong> д<strong>е</strong>лать?<br />

-- —<br />

Ч<br />

Вам н<strong>е</strong> тр<strong>е</strong>бовалось удалять эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния, так как<br />

эту работу вы полняла ф орма.<br />

Впроч<strong>е</strong>м, н<strong>е</strong> в<strong>е</strong>рьт<strong>е</strong> нам на слово. Воспользуйт<strong>е</strong>сь функци<strong>е</strong>й поиска<br />

и найдит<strong>е</strong> в код<strong>е</strong> слово Dispose, вы обнаружит<strong>е</strong>, что ИСР<br />

добавила м<strong>е</strong>тод в файл F o r m l .D e s i g n e r .cs для п<strong>е</strong>р<strong>е</strong>крытия<br />

м<strong>е</strong>тода D i s p o s e {) и вызова сво<strong>е</strong>го собств<strong>е</strong>нного м<strong>е</strong>тода b a s e .<br />

D i s p o s e О . П ри удал<strong>е</strong>нии формы автом ати ч <strong>е</strong>ск и удаля<strong>е</strong>тся<br />

в ся св я за н н а я с н <strong>е</strong> й к ол л <strong>е</strong>к ц и я C o n t r o l s . Н о <strong>е</strong>сли вы вручную<br />

удаля<strong>е</strong>т<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния с формы или созда<strong>е</strong>т<strong>е</strong> новы<strong>е</strong> экз<strong>е</strong>мпляры,<br />

н<strong>е</strong> принадл<strong>е</strong>жащи<strong>е</strong> колл<strong>е</strong>кции C ontrols, высвобождать<br />

р<strong>е</strong>сурсы пр<strong>е</strong>дстоит уж<strong>е</strong> вам.<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Часто<br />

Б о Т Ір о С ь і<br />

Поч<strong>е</strong>му код формы эл<strong>е</strong>м<strong>е</strong>нтов<br />

BeeControl, один из которых получ<strong>е</strong>н<br />

из эл<strong>е</strong>м<strong>е</strong>нта PictureBox, а другой на<br />

баз<strong>е</strong> класса UserControl, работа<strong>е</strong>т<br />

сов<strong>е</strong>рш<strong>е</strong>нно одинаково?<br />

Г ; Коду б<strong>е</strong>зразлично, каким им<strong>е</strong>нно образом<br />

р<strong>е</strong>ализу<strong>е</strong>тся объ<strong>е</strong>кт B e e C o n t r o l.<br />

Ему важна лишь возможность добавить<br />

объ<strong>е</strong>кт м<strong>е</strong>тоду C o n t r o l s .<br />

Посл<strong>е</strong> двойного щ<strong>е</strong>лчка на строчк<strong>е</strong><br />

OldBeeControl в окн<strong>е</strong> Solution<br />

Explorer появилось сообщ<strong>е</strong>ни<strong>е</strong> о добавл<strong>е</strong>нии<br />

в мой класс компон<strong>е</strong>нтов.<br />

Что это значит?<br />

Q ; Когда вы созда<strong>е</strong>т<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния,<br />

добавляя к про<strong>е</strong>кту класс, насл<strong>е</strong>дующий<br />

от эл<strong>е</strong>м<strong>е</strong>нта P i c t u r e B o x , ИСР<br />

позволя<strong>е</strong>т вам работать с компон<strong>е</strong>нтами.<br />

К ним относятся н<strong>е</strong>визуальны<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния, наприм<strong>е</strong>р, T im e r<br />

и O p e n F il e D ia lo g . Их значки появляются<br />

под формой.<br />

Пров<strong>е</strong>рьт<strong>е</strong> сами. Создайт<strong>е</strong> пустой класс,<br />

насл<strong>е</strong>дующий от класса P i c t u r e B o x .<br />

П<strong>е</strong>р<strong>е</strong>стройт<strong>е</strong> про<strong>е</strong>кт и дважды щ<strong>е</strong>лкнит<strong>е</strong><br />

на <strong>е</strong>го названии в окн<strong>е</strong> Solution Explorer<br />

Появится сообщ<strong>е</strong>ни<strong>е</strong>:<br />

«Чтобы добавить компон<strong>е</strong>нты в<br />

класс, п<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> их из окна Toolbox<br />

и воспользуйт<strong>е</strong>сь окном Properties для<br />

задания их свойств».<br />

П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong> из окна toolbox эл<strong>е</strong>м<strong>е</strong>нт<br />

O p e n F il e D ia lo g . Он появится в<br />

вид<strong>е</strong> значка. Вы мож<strong>е</strong>т<strong>е</strong> выд<strong>е</strong>лит<strong>е</strong> <strong>е</strong>го<br />

и изм<strong>е</strong>нить <strong>е</strong>го свойства. Прод<strong>е</strong>лайт<strong>е</strong><br />

эту оп<strong>е</strong>рацию, а зат<strong>е</strong>м в<strong>е</strong>рнит<strong>е</strong>сь к коду<br />

класса. Посмотрит<strong>е</strong> на конструктор, там<br />

вы найд<strong>е</strong>т<strong>е</strong> код создания экз<strong>е</strong>мпляра<br />

O p e n F i l e D i a l o g И задания <strong>е</strong>го<br />

свойств.<br />

Р<strong>е</strong>дактируя свойства эл<strong>е</strong>м<strong>е</strong>нта<br />

OpenFileDialog, Я зам<strong>е</strong>тил сообщ<strong>е</strong>ни<strong>е</strong><br />

об ошибк<strong>е</strong>: «Вы должны п<strong>е</strong>р<strong>е</strong>строить<br />

про<strong>е</strong>кт, чтобы изм<strong>е</strong>н<strong>е</strong>ния отобразились<br />

в любом открытом конструктор<strong>е</strong>».<br />

Поч<strong>е</strong>му оно появилось?<br />

г ; Эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния отображаются<br />

конструктором, и для отображ<strong>е</strong>ния посл<strong>е</strong>дн<strong>е</strong>й<br />

в<strong>е</strong>рсии эл<strong>е</strong>м<strong>е</strong>нта программу тр<strong>е</strong>бу<strong>е</strong>тся<br />

п<strong>е</strong>р<strong>е</strong>строить.<br />

Помнит<strong>е</strong>, как двигались крылья пч<strong>е</strong>лы на<br />

эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong> B e e C o n t r o l, даж<strong>е</strong> в проц<strong>е</strong>сс<strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>таскивания <strong>е</strong>го из окна Toolbox?<br />

Программа <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> была запущ<strong>е</strong>на, но написанный<br />

вами код уж<strong>е</strong> выполнялся. Тайм<strong>е</strong>р<br />

запускал событи<strong>е</strong> T ic k , а <strong>е</strong>го обработчик<br />

м<strong>е</strong>нял картинку. Подобно<strong>е</strong> пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

возможно только посл<strong>е</strong> компиляции кода,<br />

когда программа работа<strong>е</strong>т в памяти. Им<strong>е</strong>нно<br />

поэтому вам напомнили о н<strong>е</strong>обходимости<br />

р<strong>е</strong>гулярно обновлять код, чтобы эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния отображались корр<strong>е</strong>ктно.<br />

дальш<strong>е</strong> > 589


вот что вы буд<strong>е</strong>т<strong>е</strong> д<strong>е</strong>лать<br />

Пом<strong>е</strong>стим на форму анимиробанных пч<strong>е</strong>л<br />

Вс<strong>е</strong> готово для анимации симулятора. У вас <strong>е</strong>сть класс B e e C o n t r o l и дв<strong>е</strong> формы<br />

и нужно расположить пч<strong>е</strong>л в пространств<strong>е</strong> и п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щать их с одного объ<strong>е</strong>кта<br />

на другой, подд<strong>е</strong>рживая это движ<strong>е</strong>ни<strong>е</strong>. Тр<strong>е</strong>бу<strong>е</strong>тся такж<strong>е</strong> расположить цв<strong>е</strong>ты в<br />

форм<strong>е</strong> F i e l d F o r m . Впроч<strong>е</strong>м, это простая задача, так как цв<strong>е</strong>ты статичны. Этот<br />

новый код мы пом<strong>е</strong>стим в класс Renderer. Вот что он буд<strong>е</strong>т д<strong>е</strong>лать:<br />

П<strong>е</strong>р<strong>е</strong>д т<strong>е</strong>м<br />

как приступить<br />

к постро<strong>е</strong>нию<br />

визуализатора.<br />

подума<strong>е</strong>м,<br />

как им<strong>е</strong>нно<br />

долж<strong>е</strong>н работат<br />

ь класс<br />

Renderer...<br />

О<br />

$орм а со статистикой стан<strong>е</strong>т базовой<br />

Добавим к наш<strong>е</strong>му про<strong>е</strong>кту дв<strong>е</strong> н<strong>е</strong>достающи<strong>е</strong> формы. Форма<br />

H i v e F o r m буд<strong>е</strong>т отображать события в уль<strong>е</strong>, а форма F i e l d F o r m —<br />

происходящ<strong>е</strong><strong>е</strong> на пол<strong>е</strong>. П ом<strong>е</strong>стит<strong>е</strong> в конструктор основной формы<br />

строчки отображ<strong>е</strong>ния двух доч<strong>е</strong>рних форм. П<strong>е</strong>р<strong>е</strong>дайт<strong>е</strong> ссылку в основную<br />

форму, указывая, что им<strong>е</strong>нно она явля<strong>е</strong>тся их влад<strong>е</strong>льц<strong>е</strong>м:<br />

p u b l i c F o r m l О {<br />

/ / о с т а л ь н о й к о д к о н с т р у к т о р а Form l<br />

h i v e F o r m . Show ( t h i s )<br />

f i e l d F o r m . S h o w ( t h i s )<br />

Класс R enderer ссыла<strong>е</strong>тся на объ<strong>е</strong>кт world и на об<strong>е</strong> срормы<br />

Класс R e n d e r e r долж<strong>е</strong>н знать полож<strong>е</strong>ни<strong>е</strong> каждой пч<strong>е</strong>лы и каждого<br />

цв<strong>е</strong>тка, поэтому <strong>е</strong>му нужна ссылка на объ<strong>е</strong>кт World. А при добавл<strong>е</strong>нии,<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>нии и удал<strong>е</strong>нии эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния с форм н<strong>е</strong><br />

обойтись б<strong>е</strong>з ссылок на эти формы:<br />

Нужно связать<br />

формы, отображающи<strong>е</strong><br />

ул<strong>е</strong>й и пол<strong>е</strong>, с<br />

формой ст ат ист и­<br />

ки. в р<strong>е</strong>зультат<strong>е</strong><br />

св<strong>е</strong>ртка посл<strong>е</strong>дн<strong>е</strong>й<br />

формы буд<strong>е</strong>т приводить<br />

к св<strong>е</strong>ртк<strong>е</strong> п<strong>е</strong>рвых<br />

двух. Д ля этого<br />

форму со ст ат и­<br />

стикой нужно объявить<br />

влад<strong>е</strong>льц<strong>е</strong>м.<br />

Каждая форма облада<strong>е</strong>т<br />

м<strong>е</strong>тодом ShowQ. Если<br />

вы хотит<strong>е</strong> сд<strong>е</strong>лать одни<br />

форму влад<strong>е</strong>льц<strong>е</strong>м другой,<br />

п<strong>е</strong>р<strong>е</strong>дайт<strong>е</strong> ссылку на н<strong>е</strong><strong>е</strong><br />

о м<strong>е</strong>тод ShowQ.<br />

О<br />

c l a s s R e n d e r e r {<br />

p r i v a t e W o r l d w o r l d ;<br />

p r i v a t e H iv e F o r m h iv e F o r m ;<br />

p r i v a t e F i e l d F o r m f i e l d F o r m ;<br />

Начнит<strong>е</strong> класс<br />

Renderer с этих<br />

строк.<br />

Состояни<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов отсл<strong>е</strong>живаю т словари<br />

Класс W o r 1 d сл<strong>е</strong>дит за пч<strong>е</strong>лами и цв<strong>е</strong>тами при помощи списков L i s t < B e e > n L i s t < F l o w e г >.<br />

Визуализатору нуж<strong>е</strong>н доступ к объ<strong>е</strong>ктам В <strong>е</strong> <strong>е</strong> и Flower, чтобы понять, каки<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

B e e C o n t r o l и P i c t u r e B o x им соотв<strong>е</strong>тствуют. Если он н<strong>е</strong> находит эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния,<br />

то долж<strong>е</strong>н создать <strong>е</strong>го. В этом вам помогут словари. В класс R e n d e r e r нужно добавить два<br />

закрытых поля:<br />

. . Эти словари позвоp<br />

r i v a t e D i c t i o n a r y < F l o w e r , P i c t u r e B o x > f l o w e r L o o k u p = д я ю т виЗуализатору<br />

n e w D i c t i o n a r y < F l o w e r , P i c t u r e B o x > () ; хранит ь эл<strong>е</strong>м<strong>е</strong>нты<br />

С p r i v a t e D i c t i o n a r y < B e e , B e e C o n t r o l> b e e L o o k u p = ^ управл<strong>е</strong>ния длЯ каЖ -<br />

X ; --------— дой пч<strong>е</strong>лы и каждого<br />

n e w D i c t i o n a r y < B e e , B e e C o n t r o l > ( ) из НйШ&ВО<br />

мира^<br />

590 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

возд<strong>е</strong>йству<strong>е</strong>т как на<br />

об<strong>е</strong> формы, так и на вс<strong>е</strong> объ<strong>е</strong>кты<br />

постро<strong>е</strong>нны<strong>е</strong> вами в пр<strong>е</strong>дыдущ<strong>е</strong>й '<br />

глаб<strong>е</strong> для симулятора.<br />

О б ъ <strong>е</strong> к т ^<br />

П ч <strong>е</strong>л ы и цв<strong>е</strong>ты знаю т сво<strong>е</strong> м<strong>е</strong>сто<br />

Класс P o i n t хранит информацию о полож<strong>е</strong>нии цв<strong>е</strong>тов и пч<strong>е</strong>л. Для любого объ<strong>е</strong>кта В <strong>е</strong> <strong>е</strong><br />

можно л<strong>е</strong>гко посмотр<strong>е</strong>ть B e e C o n t r o l и задать полож<strong>е</strong>ни<strong>е</strong>.<br />

b e e C o n t r o l = b e e L o o k u p [ b e e ] ;<br />

b e e C o n t r o l . L o c a t i o n = b e e . L o c a t i o n ;<br />

Мы мож<strong>е</strong>м увид<strong>е</strong>ть эл<strong>е</strong>м<strong>е</strong>нт цправл<strong>е</strong>ния<br />

для любой пч<strong>е</strong>лы и любого<br />

цб<strong>е</strong>тка. Посл<strong>е</strong> ч<strong>е</strong>го полож<strong>е</strong>ни<strong>е</strong> эл<strong>е</strong>-<br />

Визуализатор добавля<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния новым пч<strong>е</strong>лам<br />

Если м<strong>е</strong>тод словаря C o n t a i n s K e y О для выд<strong>е</strong>л<strong>е</strong>нного объ<strong>е</strong>кта В <strong>е</strong> <strong>е</strong> возвраща<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong><br />

false, значит, для данной пч<strong>е</strong>лы отсутству<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния. Класс R e n d e r e r долж<strong>е</strong>н<br />

создать B e e C o n t r o l и добавить <strong>е</strong>го в словарь, зат<strong>е</strong>м на форму (Н<strong>е</strong> забудьт<strong>е</strong> вызвать<br />

м<strong>е</strong>тод B r i n g T o F r o n t () (Пом<strong>е</strong>стить вп<strong>е</strong>р<strong>е</strong>д) эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния, чтобы пч<strong>е</strong>ла н<strong>е</strong> оказалась<br />

закрыта цв<strong>е</strong>тами.)<br />

i f { ib e e L o o k u p . C o n t a i n s K e y ( b e e ) ) {<br />

b e e C o n t r o l = n e w B e e C o n t r o l 0 { W i d t h = 4 0 , H e i g h t = 4 0 } ;<br />

b e e L o o k u p . A d d ( b e e , b e e C o n t r o l ) ;<br />

h i v e F o r m . C o n t r o l s . A d d ( b e e C o n t r o l ) ;<br />

} e l s e<br />

b e e C o n t r o l . B r i n g T o F r o n t ( ) ;<br />

b e e C o n t r o l = b e e L o o k u p [ b e e ] ;<br />

М<strong>е</strong>тод СопЬа1п5К<strong>е</strong>у() показыва<strong>е</strong>т<br />

наличи<strong>е</strong> пч<strong>е</strong>лы в словар<strong>е</strong>. Если<br />

она там отсутству<strong>е</strong>т, значит,<br />

<strong>е</strong><strong>е</strong> нужно добавить вм<strong>е</strong>ст<strong>е</strong> с <strong>е</strong><strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нтом управл<strong>е</strong>ния.<br />

Помнит<strong>е</strong>, что в кач<strong>е</strong>ств<strong>е</strong> ключа словари могут использовать<br />

что угодно? В данном случа<strong>е</strong> ключом выступа<strong>е</strong>т<br />

объ<strong>е</strong>кт В<strong>е</strong><strong>е</strong>. Визуализатору нужно знать, какой эл<strong>е</strong>м<strong>е</strong>нт<br />

BeeControl на форм<strong>е</strong> соотв<strong>е</strong>тству<strong>е</strong>т той или иной пч<strong>е</strong>л<strong>е</strong>.<br />

Поэтому он находит пч<strong>е</strong>лу в словар<strong>е</strong>, опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т <strong>е</strong><strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния и таким образом получа<strong>е</strong>т возможность<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щать <strong>е</strong><strong>е</strong> по форм<strong>е</strong>.<br />

М <strong>е</strong>тод BringToFrontO гаран т и ру<strong>е</strong>т .<br />

J.H , ^гррда бидцт появляться<br />

. «А»<br />

ф <strong>е</strong> р т Him э т о т “ 7<br />

ба<strong>е</strong>т появл<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>л пов<strong>е</strong>рх фона.<br />

дальш<strong>е</strong> > 591


начн<strong>е</strong>м!<br />

Это эл<strong>е</strong>м <strong>е</strong>нт улравл<strong>е</strong><br />

ния PictureBox. свойст<br />

во Backgroundlm age<br />

ф орм ы Hive u Field<br />

кот орого связано с<br />

вн<strong>е</strong>шним изображ<strong>е</strong>ни<strong>е</strong>м<br />

ул ья Свойству<br />

Добавим н<strong>е</strong>достающи<strong>е</strong> формы. В озь м и т <strong>е</strong> сущ <strong>е</strong>ствую щ и й п р о<strong>е</strong>к т симулятор<br />

а и при помощи команды Add » Existing Item... добавьт<strong>е</strong> п ользоват<strong>е</strong>л ьск и й<br />

B a c k g r o u n d lm a g e L a y o u t<br />

присво<strong>е</strong>но знач<strong>е</strong>ни<strong>е</strong><br />

эл <strong>е</strong>м <strong>е</strong>н т управл<strong>е</strong>ния B e e C o n tr o l. В класс<strong>е</strong> U s e r C o n t r o l три файла - .cs<br />

Stretch. При загруз<br />

• d e s i g n e r. cs и . r e s x - добавьт<strong>е</strong> их вс<strong>е</strong>. В файлах . cs и . d e s i g n e r . cs изм<strong>е</strong>нит<strong>е</strong><br />

пространство им<strong>е</strong>н в соотв<strong>е</strong>тствии с вашим про<strong>е</strong>ктом. П<strong>е</strong>р<strong>е</strong>стройт<strong>е</strong> про<strong>е</strong>кт- в конструктор р<strong>е</strong>­<br />

к<strong>е</strong> изображ<strong>е</strong>ний улья<br />

эл<strong>е</strong>м<strong>е</strong>нт B e e C o n t r o l долж<strong>е</strong>н появиться в окн<strong>е</strong> Toolbox. Добавьт<strong>е</strong> графич<strong>е</strong>ски<strong>е</strong> сурсов они начинают<br />

отображаться<br />

р <strong>е</strong> ^ с ы . Зат<strong>е</strong>м щ <strong>е</strong>л к н и т<strong>е</strong> п равой к н оп к ой м ьппи на и м <strong>е</strong>н и п р о<strong>е</strong>к та в окн<strong>е</strong><br />

в списк<strong>е</strong>, вызыва<strong>е</strong>мом<br />

Solution Explorer и выб<strong>е</strong>рит<strong>е</strong> команду Windows Form... в м<strong>е</strong>ню Add. Назовит<strong>е</strong> файлы<br />

H i v e F o r m .cs и F i e l d F o r m .cs, и ИСР автоматич<strong>е</strong>ски присвоит их свойствам рядом со свойством<br />

щ<strong>е</strong>лчком на кнопк<strong>е</strong> ...<br />

N a m e знач<strong>е</strong>ния H i v e F o r m и F ieldForm. Вы только что созда^1и два новых класса Backgroundlmage в окн<strong>е</strong><br />

Properties.<br />

Пом<strong>е</strong>няйт<strong>е</strong><br />

разм<strong>е</strong>ры<br />

форм, как<br />

показано<br />

на скриншотах.<br />

Свойству формы Backgroundlmage<br />

присвоит<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong> улья,<br />

а BackgroundlmageLayout —■Stretch.<br />

Опр<strong>е</strong>д<strong>е</strong>лим м<strong>е</strong>ст0П0А0)к<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>ктов<br />

присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

Р^'ЖНО понять, гд<strong>е</strong> на форм<strong>е</strong> F ie ld F o rm находится ул<strong>е</strong>й. В окн<strong>е</strong> Properties создайт<strong>е</strong><br />

обработчик для с о б ы т и я M o u s e C lic k ф о р м ы H iv e и добавьт<strong>е</strong> код;<br />

p r i v a t e v o i d H i v e F o r m _ M o u s e C l ic k ( o b je c t s e n d e r , M o u s e E v e n tA r g s e ) f<br />

M e s s a g e B o x . S h o w ( e . L o c a t i o n . T o S t r i n g ( ) ) ;<br />

Мы скоро запустим форму. В этот мом<strong>е</strong>нт вам нужно буд<strong>е</strong>т щ<strong>е</strong>лкнугь на изображ<strong>е</strong>нии<br />

выхода, и обработчик событий покаж<strong>е</strong>т точную координату этого м<strong>е</strong>ста.<br />

Добавьт<strong>е</strong> аналогичный обработчик к форм<strong>е</strong> Field. Щ <strong>е</strong>лчком получит<strong>е</strong> координаты<br />

вьгхода, питомника и фабрики. Эти координаты позволят обновлять м<strong>е</strong>тод<br />

I n i t i a l i z e L o c a t i o n s {), написанный в пр<strong>е</strong>дьщущ<strong>е</strong>й глав<strong>е</strong> для класса Hive:<br />

Запуст ив<br />

Симу л я - F p r i v a t e v o i d I n i t i a l i z e L o c a t i o n s О<br />

т ор, вы ^<br />

смож<strong>е</strong>т<strong>е</strong> l o c a t i , o n s = n e w D i c t i o n a r y ^ < w s I-#i t r i-Lxx^ n g , f It^XX P o i n L> t > ( ) ;<br />

--и ____________<br />

locations.Add("Entrance'', new Point (626, j a o ) ) •<br />

заполнит ь<br />

locations. Add ("Nursery", n e w P o i n t d T T T l e z E ^ '-g<br />

колл<strong>е</strong>кцию<br />

locations.Add("HoneyFactory", new PointTl57, 78))•<br />

координат locations. Add ("Exit", n e w P o i n t U V S , 180));}<br />

внут ри<br />

улья.<br />

Эт о наш вариант координат , для ваших<br />

ф орм координаты м о гут отличаться.<br />

І у н ч и в , уб<strong>е</strong>рит<strong>е</strong> обработчик<br />

щ<strong>е</strong>лчка мьтки<br />

.он m o Z o -<br />

нат коорди -<br />

ваших объ<strong>е</strong>ктов.


Постро<strong>е</strong>ни<strong>е</strong> бизуализатора<br />

Вот код класса Renderer. Основная форма вызыва<strong>е</strong>т<br />

м<strong>е</strong>тод R e n d e r О этого класса посл<strong>е</strong> м<strong>е</strong>тода<br />

W o r l d .G o (), чтобы отобразить на формах<br />

пч<strong>е</strong>л и цв<strong>е</strong>ты. Уб<strong>е</strong>дит<strong>е</strong>сь, что изображ<strong>е</strong>ни<strong>е</strong> цв<strong>е</strong>тка<br />

(Flower.png) такж<strong>е</strong> загруж<strong>е</strong>но в ваш про<strong>е</strong>кт.<br />

c l a s s R e n d e r e r {<br />

p r i v a t e W o r l d world;<br />

p r i v a t e H iv e F o r m hiveForm;<br />

p r i v a t e F i e l d F o r m fieldForm;<br />

H « “<br />

пч<strong>е</strong>лэл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Вс<strong>е</strong> поля визуализатора<br />

закрыты, так как други<strong>е</strong><br />

классы н<strong>е</strong> должны им<strong>е</strong>ть<br />

доступа к <strong>е</strong>го свойствам.<br />

Класс world просто вызыва<strong>е</strong>т<br />

м<strong>е</strong>тоды RenderQ<br />

и ResetQ. П<strong>е</strong>рвый рису<strong>е</strong>т<br />

графику на формах, а<br />

второй при п<strong>е</strong>р<strong>е</strong>загрузк<strong>е</strong><br />

форм удаля<strong>е</strong>т с нмх эл<strong>е</strong>м<strong>е</strong>нты<br />

управл<strong>е</strong>ния.<br />

О тсл<strong>е</strong>живани<strong>е</strong> состояния пч<strong>е</strong>л<br />

и цв<strong>е</strong>тов осущ<strong>е</strong>ствля<strong>е</strong>тся ч<strong>е</strong>р<strong>е</strong>з<br />

объ<strong>е</strong>кты В<strong>е</strong><strong>е</strong> и Flower. А ля<br />

отображ<strong>е</strong>ния цо<strong>е</strong>тод цв<strong>е</strong>тов использи использу-p<br />

r i v a t e D i c t i o n a r y < F l o w e r , P i c t u r e B o x > flowerLookup = \ Р'^^мг<strong>е</strong>Бох, й Зля<br />

n e w D i c t i o n a r y < F l o w e r , P i c t u r e B o x > () ; / ^ ^ ^ С ^ Г п р Т Т о м о ш Т Т ^<br />

p r i v a t e L i s t < F l o w e r > deadFlowers = n e w L i s t < F l o w e r > {) ; > вар<strong>е</strong>й визуализатор связыва<strong>е</strong>т<br />

^аждую ^ пч<strong>е</strong>лу ^ и г^1Л.УГк(/01Ц каждый Ц0С1/ цв<strong>е</strong>ток<br />

p r i v a t e D i c t i o n a r y < B e e , B e e C o n t r o l> beeLookup =<br />

С- с ПК UK ЭАаАЛР.ииллплл!. эл<strong>е</strong>м<strong>е</strong>нтами BeeControl , .<br />

n e w D i c t i o n a r y < B e e , B e e C o n t r o l > ( ) ;<br />

и rictureßoK.<br />

p r i v a t e L i s t < B e e > retiredBees = n e w L i s t < B e e > ( ) ;<br />

p u b l i c Renderer( W o r ld w o r l d ,<br />

}<br />

t h i s . w o r l d = w o r l d ;<br />

t h i s . h i v e F o r m = h iv e F o r m ;<br />

t h i s . f i e l d F o r m = f i e l d F o r m ;<br />

p u b l i c v o i d Render 0<br />

}<br />

D r a w B e e s ( ) ;<br />

D r a w F lo w e r s ( ) ;<br />

R e m o v e R e tir e d B e e s A n d D e a d F lo w e r s ( ) ;<br />

{<br />

J<br />

H iv e F o r m h iv e F o r m , F i e l d F o r m f i e l d F o r m )<br />

Тайм<strong>е</strong>р основной формы вызыва<strong>е</strong>т м <strong>е</strong>-<br />

— ■mod RenderQ, который обновля<strong>е</strong>т пч<strong>е</strong>л<br />

^ и цв<strong>е</strong>ты, а зат<strong>е</strong>м очища<strong>е</strong>т ик словари.<br />

A<br />

{ Когда цв<strong>е</strong>ток<br />

вян<strong>е</strong>т, а пч<strong>е</strong>ла<br />

уходит на за ­<br />

служ<strong>е</strong>нный о т ­<br />

дых, информация<br />

о ник удаля<strong>е</strong>тся<br />

из словар<strong>е</strong>й при<br />

помощи списков<br />

deadFlowers<br />

и retiredBees.<br />

p u b l i c v o i d Reset 0 {<br />

f o r e a c h ( P i c t u r e B o x f l o w e r i n f l o w e r L o o k u p . V a l u e s<br />

f i e l d F o r m . C o n t r o l s . R e m o v e ( f l o w e r ) ;<br />

f l o w e r . D i s p o s e ( ) ;<br />

}<br />

f o r e a c h ( B e e C o n t r o l b e e i n b e e L o o k u p . V a lu e s )<br />

h i v e F o r m . C o n t r o l s . R e m o v e ( b e e ) ;<br />

f i e l d F o r m . C o n t r o l s . R e m o v e ( b e e ) ;<br />

b e e . D i s p o s e 0 ;<br />

}<br />

f l o w e r L o o k u p . C l e a r ( ) ;<br />

b e e L o o k u p . C le a r 0 ;<br />

{<br />

) {<br />

При п<strong>е</strong>р<strong>е</strong>загрузк<strong>е</strong> симулятора для<br />

каждой формы вызыва<strong>е</strong>тся м<strong>е</strong>тод<br />

Controk.RemoveQ, удаляющий вс<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния. Он находит<br />

каждый эл<strong>е</strong>м<strong>е</strong>нт в словар<strong>е</strong> и вызыва<strong>е</strong>т<br />

для н<strong>е</strong>го.м<strong>е</strong>тод PisposeQ. Посл<strong>е</strong><br />

ч<strong>е</strong>го очища<strong>е</strong>т и словари такж<strong>е</strong>.<br />

дальш<strong>е</strong> > 593


цв<strong>е</strong>ты рисуются при помощи двух циклов foreach. П<strong>е</strong>рвый<br />

добавля<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нт PictureBoxes для новых цв<strong>е</strong>тов, а второй<br />

удаля<strong>е</strong>т этот эл<strong>е</strong>м<strong>е</strong>нт для цв<strong>е</strong>тов, которы<strong>е</strong> завяли.<br />

i<br />

p r i v a t e v o i d DrawFlowers() {<br />

f o r e a c h ( F lo w e r f l o w e r i n w o r l d . F l o w e r s )<br />

i f ( ! f l o w e r L o o k u p . C o n t a i n s K e y ( f l o w e r ) ) {<br />

P i c t u r e B o x f l o w e r C o n t r o l = n e w P i c t u r e B o x (<br />

) {<br />

W id t h = 4 5 ,<br />

М<strong>е</strong>тод PrawFlowersQ H e i g h t = 55<br />

зада<strong>е</strong>т полож<strong>е</strong>ни<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нта PictureBox im a g e = P r o p e r t i e s . R e s o u r c e s . F lo w e r ,<br />

на форм<strong>е</strong> при помощи Сл S iz e M o d e = P i c t u r e B o x S iz e M o d e . S t r e t c h l m a g e<br />

свойства Location объ- L o c a t i o n = f l o w e r . L o c a t i o n<br />

<strong>е</strong>кта Flower.<br />

}; --------------<br />

}<br />

f l o w e r L o o k u p . A d d ( f l o w e r , f l o w e r C o n t r o l )<br />

f i e l d F o r m . C o n t r o l s . A d d ( f l o w e r C o n t r o l ) ;<br />

f o r e a c h ( F lo w e r f l o w e r i n f l o w e r L o o k u p . K e y s )<br />

i f (. ! w o r l d . F l o w e r s . C o n t a i n s ( f l o w e r ) ) {<br />

}<br />

P i c t u r e B o x f l o w e r C o n t r o l T o R e m o v e = f l o w e r L o o k u p [ f l o w e r ] ,■<br />

П<strong>е</strong>рвый цикл foreach<br />

использу<strong>е</strong>т словарь<br />

flowerLookup для про-<br />

— в<strong>е</strong>рки наличия эл<strong>е</strong>м<strong>е</strong>нта<br />

управл<strong>е</strong>ния у выд<strong>е</strong>л<strong>е</strong>нного<br />

1 / цв<strong>е</strong>тка. Н<strong>е</strong> обнаружив<br />

такового, он созда<strong>е</strong>т новый<br />

эл<strong>е</strong>м<strong>е</strong>нт PictureBox<br />

с помощью инициализатора<br />

объ<strong>е</strong>ктов, добавля<strong>е</strong>т<br />

<strong>е</strong>го к форм<strong>е</strong>, а зат<strong>е</strong>м<br />

добавля<strong>е</strong>т <strong>е</strong>го в словарь<br />

flowerLookup.<br />

Второй цикл foreach<br />

ищ<strong>е</strong>т в словар<strong>е</strong><br />

flowerLookup эл<strong>е</strong>м<strong>е</strong>нты<br />

PictureBox. которы<strong>е</strong> уж<strong>е</strong><br />

н<strong>е</strong> принадл<strong>е</strong>жат форм<strong>е</strong>,<br />

и удаля<strong>е</strong>т их.<br />

f i e l d F o r m . C o n t r o l s . R e m o v e ( f l o w e r C o n t r o l T o R e m o v e ) ;<br />

f l o w e r C o n t r o l T o R e m o v e . D i s p o s e ( ) ;<br />

d e a d F lo w e r s .A d d ( f l o w e r ) ;<br />

удалив эл<strong>е</strong>м<strong>е</strong>нт PictureBox, OH<br />

p r i v a t e v o i d DrawBees() {<br />

B e e C o n t r o l b e e C o n t r o l ;<br />

f o r e a c h (B e e b e e i n w o r l d . B e e s ) {<br />

к<br />

вызыва<strong>е</strong>т <strong>е</strong>го м<strong>е</strong>тод DisposeQ<br />

\ — • Посл<strong>е</strong> ч<strong>е</strong>го объ<strong>е</strong>кт Flower добавля<strong>е</strong>тся<br />

в список deadFlowers.<br />

М<strong>е</strong>тод DrawBeesQ т акж<strong>е</strong><br />

использу<strong>е</strong>т два цикла<br />

, roreach. Он по сути д<strong>е</strong>ла<strong>е</strong>т<br />

то ж<strong>е</strong> само<strong>е</strong>, что<br />

b e e C o n t r o l = G e t B e e C o n t r o l ( b e e ) ;<br />

i f ( b e e . I n s i d e H i v e ) {<br />

и м<strong>е</strong>тод DrawFlowersQ. Но<br />

в данном случа<strong>е</strong> функция<br />

i f ( f i e l d F o r m . C o n t r o l s . C o n t a i n s ( b e e C o n t r o l ) )<br />

сложн<strong>е</strong><strong>е</strong>, поэтому мы распр<strong>е</strong>д<strong>е</strong>лили<br />

<strong>е</strong>го функции срункции по no<br />

M o v e B e e F r o m F ie ld T o H iv e ( b e e C o n t r o l ) ;<br />

} e l s e i f ( h i v e F o r m . C o n t r o l s . C o n t a i n s ( b e e C o n t r o l ) Л 1<strong>е</strong> то5 дл 1^ 0^ -<br />

M o v e B e e F r o m H i v e T o F i e ld ( b e e C o n t r o l) ;<br />

л<strong>е</strong>гчив понимани<strong>е</strong> кода.<br />

b e e C o n t r o l . L o c a t i o n = b e e . L o c a t i o n ; kj t ^ /n д<br />

М<strong>е</strong>тод DrawBeesQ пров<strong>е</strong>ря-<br />

’ em. н<strong>е</strong> возникла ли ситуация.<br />

когда пч<strong>е</strong>ла находится в уль<strong>е</strong>.<br />

f o r e a c h (В <strong>е</strong> <strong>е</strong> Ь <strong>е</strong> <strong>е</strong> i n b e e L o o k u p .K e y s ) { а <strong>е</strong><strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния —<br />

Посл<strong>е</strong> удал<strong>е</strong>ния эл<strong>е</strong>-^^ *: ' w o r l d . B e e s . C o n t a i n s ( b e e ) ) { форм<strong>е</strong> FieldForm или<br />

b e e C o n t r o l = b e e L o o k u p [ b e e ] ;<br />

наоборот. Д ля п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>ния<br />

^ \ эл<strong>е</strong>м<strong>е</strong>нта BeeControls м<strong>е</strong>жду<br />

i f ( f i e l d F o r m . C o n t r o l s . C o n t a i n s ( b e e C o n t r o l ) ) формами используются два<br />

f i e l d F o r m . C o n t r o l s . R e m o v e ( b e e C o n t r o l ) ; дополнит<strong>е</strong>льных м<strong>е</strong>тода.<br />

м<strong>е</strong>нта BeeControl<br />

нужно вызвать <strong>е</strong>го<br />

м<strong>е</strong>тод DisposeQ.<br />

при этом буд<strong>е</strong>т<br />

удал<strong>е</strong>н и связанный<br />

с ним тайм<strong>е</strong>р<br />

i f ( h i v e F o r m . C o n t r o l s . C o n t a i n s ( b e e C o n t r o l ) ) Второй цикл foreach pah<br />

i v e F o r m . C o n t r o ls . R e m o v e ( b e e C o n t r o l ) ; бота<strong>е</strong>т в основном как в<br />

b e e C o n t r o l . D i s p o s e О ; К ;; м<strong>е</strong>тод<strong>е</strong> DrawFlowersQ. но<br />

, r e t i r e d B e e s .A d d ( Ь <strong>е</strong> <strong>е</strong> ) ; приходится уда-<br />

} 1 лять эл<strong>е</strong>м<strong>е</strong>нты BeeControl<br />

} из правой формы.<br />

594 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

В в <strong>е</strong> р х н <strong>е</strong> й ч а ст и к ласса R e n d e r e r д о л ж н ы<br />

н а х о д и т с я стр о к и u s i n g S y s te m .D r a w in g<br />

и u s i n g S y ste m .W in d o w s.F o r m s.<br />

p r i v a t e B e e C o n t r o l GetBeeControl(B ee b e e )<br />

B e e C o n t r o l b e e C o n t r o l ;<br />

i f ( I b e e L o o k u p . C o n t a i n s K e y ( b e e ) ) {<br />

{<br />

М<strong>е</strong>тод GetBeeControiQ ищ<strong>е</strong>т пч<strong>е</strong>лу<br />

в словар<strong>е</strong> beeLookup. При от сут ­<br />

ствии нужной пч<strong>е</strong>лы он созда<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нт<br />

управл<strong>е</strong>ния BeeControl разм<strong>е</strong>ром<br />

4 0 X 4 0 и добавля<strong>е</strong>т <strong>е</strong>го к форм<strong>е</strong> hive<br />

(в<strong>е</strong>дь им<strong>е</strong>нно зд<strong>е</strong>сь появляются новы<strong>е</strong><br />

пч<strong>е</strong>лы).<br />

/ " ■ '“ d e c o n t r o l = n e w B e e C o n t r o l 0 { W id t h = 4 0 , H e i g h t = 4 0 } ;<br />

He забудьт<strong>е</strong>: b e e L o o k u p . A d d (b e e , b e e C o n t r o l ) ;<br />

! означа<strong>е</strong>т НЕТ!<br />

}<br />

h i v e F o r m . C o n t r o l s . A d d ( b e e C o n t r o l ) ;<br />

b e e C o n t r o l . B r i n g T o F r o n t ( ) ;<br />

}<br />

e l s e<br />

b e e C o n t r o l = b e e L o o k u p [ b e e ] ;<br />

r e t u r n b e e C o n t r o l ;<br />

p r i v a t e v o i d MoveBeeFromHiveToField( B e e C o n t r o l b e e C o n t r o l )<br />

Г<br />

h i v e F o r m . C o n t r o l s . R e m o v e ( b e e C o n t r o l ) ;<br />

b e e C o n t r o l . S iz e = n e w S i z e (2 0 , 20<br />

f i e l d F o r m . C o n t r o l s . A d d ( b e e C o n t r o l ) ;<br />

b e e C o n t r o l . B r i n g T o F r o n t ( ) ;<br />

'<br />

М <strong>е</strong>тод MoveBeeFromHiveToFieldQ<br />

б<strong>е</strong>р<strong>е</strong>т указанный эл<strong>е</strong>м <strong>е</strong>нт BeeControl<br />

из колл<strong>е</strong>кции Controls улья и добавля<strong>е</strong>т<br />

<strong>е</strong>го в колл<strong>е</strong>кцию Controls поля.<br />

Пч<strong>е</strong>лм на пол<strong>е</strong> им<strong>е</strong>ют м<strong>е</strong>ньший разм<strong>е</strong>р,<br />

ч<strong>е</strong>м пч<strong>е</strong>лы в уль<strong>е</strong>, соотв<strong>е</strong>тств<strong>е</strong>нно,<br />

м<strong>е</strong>тод долж<strong>е</strong>н м<strong>е</strong>нять свойство Size<br />

эл<strong>е</strong>м<strong>е</strong>нта BeeControl.<br />

p r i v a t e v o i d MoveBeeFromFieldToHive( B e e C o n t r o l b e e C o n t r o l ) {<br />

}<br />

f i e l d F o r m . C o n t r o l s . R e m o v e ( b e e C o n t r o l ) ;<br />

b e e C o n t r o l . S i z e = n e w S i z e ( 4 0 , 4 0 ) ;<br />

h i v e F o r m . C o n t r o l s . A d d ( b e e C o n t r o l ) ;<br />

b e e C o n t r o l . B r i n g T o F r o n t ( ) ;<br />

p r i v a t e v o i d RemoveRetiredBeesAndDeadFlowers()<br />

]<br />

f o r e a c h (B e e b e e i n r e t i r e d B e e s )<br />

b e e L o o k u p . R e m o v e ( b e e ) ;<br />

r e t i r e d B e e s . C l e a r ( ) ;<br />

f o r e a c h ( F lo w e r f l o w e r i n d e a d F lo w e r s )<br />

f l o w e r L o o k u p . R e m o v e ( f l o w e r ) ;<br />

d e a d F lo w e r s . C l e a r ( ) ;<br />

М<strong>е</strong>тод MoveBeeFromFieldToHiveO<br />

возвраща<strong>е</strong>т эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

BeeControl обратно в ул<strong>е</strong>й. Соотв<strong>е</strong>тств<strong>е</strong>нно,<br />

он долж<strong>е</strong>н ув<strong>е</strong>личить<br />

<strong>е</strong>го разм<strong>е</strong>р.<br />

К ак только м<strong>е</strong>тоды VrawBees()<br />

и PrawFlowersO обнаруживают,<br />

что цв<strong>е</strong>тка или пч<strong>е</strong>лы больш<strong>е</strong><br />

н<strong>е</strong>т, они добавляют эти объ<strong>е</strong>кты<br />

в списки deadFlowers и retiredBees,<br />

чтобы в конц<strong>е</strong> кадра произошло их<br />

удал<strong>е</strong>ни<strong>е</strong>.<br />

Напосл<strong>е</strong>док визуализатор вызыва<strong>е</strong>т м <strong>е</strong>­<br />

тод для удал<strong>е</strong>ния из словар<strong>е</strong>й вс<strong>е</strong>х увядших<br />

цв<strong>е</strong>тов и пр<strong>е</strong>кративших работу пч<strong>е</strong>л.<br />

дальш<strong>е</strong> > 595


со<strong>е</strong>диним вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong><br />

Со<strong>е</strong>диним оснобную форму с формами HiveForm и FieldForm<br />

М ы создали визуализатор, н о у н<strong>е</strong>го н<strong>е</strong>т ф о р м , в к о т о р ы <strong>е</strong> м о ж н о б ы л о б ы в ы в о д и т ь изображ<strong>е</strong>ни<strong>е</strong>. Ч т о ­<br />

б ы исправить ситуацию, в<strong>е</strong>рн<strong>е</strong>мся к классу F o r m о с н о в н о й ф о р м ы (скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го, о н называ<strong>е</strong>тся Forml)<br />

и вн<strong>е</strong>с<strong>е</strong>м и з м <strong>е</strong> н <strong>е</strong> н и я в код:<br />

Код п<strong>е</strong>р<strong>е</strong>загрузки мира пом<strong>е</strong>щ<strong>е</strong>н в м <strong>е</strong> -<br />

1^о д ResetSimulatorQ<br />

p u b l i c p a r t i a l c l a s s F o r m l : F o r m {<br />

S a f o m<br />

p r i v a t e H iv e F o rm h iv e F o r m = n ew H iv e F o rm () ; ? а к т а м и в кцч<strong>е</strong>°<br />

p r i v a t e F ie ld F o r m f i e l d F o r m = n ew F ie ld F o r m O ; ^ noKa^J^ T<br />

p r i v a t e R e n d e r e r r e n d e r e r ; — Pernod Skow(). их<br />

/ / о с т а л ь н ы <strong>е</strong> п о л я Kodj создающий экз<strong>е</strong>мпляр<br />

объ<strong>е</strong>кта World, пом<strong>е</strong>стит<strong>е</strong><br />

p u b l i c F o r m l О { в м<strong>е</strong>тод ResetSlmulatori).<br />

I n i t i a l i z e C o m p o n e n t ()<br />

M o v e C h ild F o r m s( ) ;<br />

h i v e F o r m . S h o w ( t h i s ) ; '<br />

f i e l d F o r m . S h o w ( t h i s ) ;<br />

R e s e t S i m u l a t o r { ) ;<br />

t i m e r l . I n t e r v a l = 5 0 ;<br />

t i m e r l . T i c k += n e w E v e n t H a n d le r ( R u n F r a m e ) ;<br />

t i m e r l . E n a b l e d = f a l s e ;<br />

U p d a t e S t a t s (n e w T im e S p a n ()) ;<br />

. p r i v a t e v o i d M o v e C h ild F o r m s {) Т<br />

форма п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т ссылку на<br />

-с<strong>е</strong>бя м<strong>е</strong>тоду Рогт.31ло\ы{),<br />

' становясь таким способом<br />

родит<strong>е</strong>льской формой.<br />

h iv e F o r m .L o c a t io n = n ew P o i n t ( L o c a t i o n . X + W id th<br />

f i e l d F o r m .L o c a t i o n = n ew P o i n t ( L o c a t i o n . X ,<br />

^ L o c a t i o n .Y + M a th .M a x (H e ig h t, h iv e F o r m .H e ig h t )<br />

p u b l i c v o i d R u n F r a m e ( o b j e c t s e n d e r ,<br />

f r a m e s R u n + + ;<br />

w o r l d .G o (random) ;<br />

r e n d e r e r .R e n d e r О ;<br />

Конструктор основной<br />

формы пом<strong>е</strong>ща<strong>е</strong>т<br />

на м<strong>е</strong>сто дв<strong>е</strong> доч<strong>е</strong>рни<strong>е</strong><br />

формы, а потом<br />

отобража<strong>е</strong>т их. Зат<strong>е</strong>м<br />

он вызыва<strong>е</strong>т м <strong>е</strong> ­<br />

тод ResetSimulator().<br />

создающий экз<strong>е</strong>мпляр<br />

объ<strong>е</strong>кта Renderer.<br />

Так как свойство StartPosition об<strong>е</strong>их доч<strong>е</strong>рних<br />

форм им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> Manual, основная<br />

форма мож<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щать их при помощи<br />

E v e n t A r g s e) {<br />

Эт а строка в м<strong>е</strong>тод<strong>е</strong> RunFrame<br />

заставля<strong>е</strong>т симулятор обнов-<br />

1 0 , L o c a t i o n . Y ) ;<br />

'<br />

Этот код заставля<strong>е</strong>т<br />

доч<strong>е</strong>рни<strong>е</strong> формы<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щаться. При<br />

этом форма Hive<br />

располож<strong>е</strong>на рядом<br />

с основной формой,<br />

а форма Field —<br />

под ними.<br />

^ П п р <strong>е</strong> д ы д у щ и й к о д ^ Т ь ^ в Т м <strong>е</strong> т ^ Т ^ О ^ '"<br />

Событи<strong>е</strong> Move возника<strong>е</strong>т<br />

при каждом п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щ<strong>е</strong>нии<br />

основной формы.<br />

p r i v a t e v o i d F o r m l_ M o v e ( o b j e c t s e n d e r E v e n tA r g s <strong>е</strong> ) { М<strong>е</strong>тод MoveChildFormsQ<br />

M o v e C h ild F o r m s( ) ;<br />

^ . а гарантиру<strong>е</strong>т, что до- tio-<br />

} ^ ^<br />

EycKvfe в окн<strong>е</strong><br />

ч<strong>е</strong>рны<strong>е</strong> формы будут<br />

Properties позволя<strong>е</strong>т добавить<br />

слЬом.<br />

Свойство Startposition об<strong>е</strong>их доч<strong>е</strong>рних оораоо^чик события Move. •<br />

форм должно им<strong>е</strong>ть знач<strong>е</strong>ни<strong>е</strong> Manual,<br />

инач<strong>е</strong> м<strong>е</strong>тод MoveChildFormsQ работат<br />

ь н<strong>е</strong> буд<strong>е</strong>т.


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Зд<strong>е</strong>сь мы созда<strong>е</strong>м экз<strong>е</strong>мпляры<br />

классов World и Renderer. которы<strong>е</strong><br />

\ у п<strong>е</strong>р<strong>е</strong>загружают симулятор.<br />

p r i v a t e v o i d R e s e t S i m u l a t o r () {<br />

fr a m esR u n = 0 ;<br />

w o r ld = n ew W o r ld (n e w B e e M e s s a g e ( S e n d M e s s a g e ) ) ;<br />

r e n d e r e r = n ew R e n d e r e r ( w o r ld , h iv e F o r m , f ie ld F o r m )<br />

}<br />

p r i v a t e v o i d r e s e t _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e )<br />

r e n d e r e r . R e s e t 0 ;<br />

R e s e t S i m u l a t o r ( ) ;<br />

i f ( ! t i m e r l . E n a b l e d )<br />

t o o l S t r i p l . I t e m s [ 0 ] . T e x t = " S t a r t s i m u l a t i o n " ;<br />

Эля<br />

}<br />

p r i v a t e v o i d o p e n T o o l S t r i p B u t t o n _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

/ / О с т а т о к к о д а д л я к н о п к и о с т а <strong>е</strong> т с я б <strong>е</strong> з и з м <strong>е</strong> н <strong>е</strong> н и й .<br />

r e n d e r e r . R e s e t ( ) ;<br />

r e n d e r e r = n ew R e n d e r e r ( w o r ld , h iv e F o r m , f i e l d F o r m ) ;<br />

Час1Ю°<br />

597


что-то н<strong>е</strong> так<br />

Т<strong>е</strong>стировани<strong>е</strong>... М М . . .<br />

Скомпилируйт<strong>е</strong> код, исправьт<strong>е</strong> любы<strong>е</strong> обнаруж<strong>е</strong>нны<strong>е</strong> ошибки и запустит<strong>е</strong> симулятор.<br />

Т<strong>е</strong>п<strong>е</strong>рь пч<strong>е</strong>лы должны<br />

радостно т т т ь<br />

крыль>яллы- ,<br />

4?<br />

Пом<strong>е</strong>няйт<strong>е</strong> константы<br />

и посм от рит <strong>е</strong>, как<br />

визуализат ор р<strong>е</strong>аги ру<strong>е</strong>т<br />

на изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> колич<strong>е</strong>ства<br />

цв<strong>е</strong>т ов и пч<strong>е</strong>л.<br />

598 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Выглядит красиво, но ч<strong>е</strong>го-то н<strong>е</strong> х в а т а <strong>е</strong> т ...<br />

Присмотр<strong>е</strong>вшись к пч<strong>е</strong>лам, жужжащим вокруг улья и цв<strong>е</strong>тов, вы зам<strong>е</strong>тит<strong>е</strong>, что их визуализация происходит<br />

н<strong>е</strong> б<strong>е</strong>з пробл<strong>е</strong>м. Помнит<strong>е</strong>, что свойству B a c k C o l o r эл<strong>е</strong>м<strong>е</strong>нта B e e C o n t r o l было присво<strong>е</strong>но знач<strong>е</strong>ни<strong>е</strong><br />

C o l o r .T r a n s p a r e n t ? К сожал<strong>е</strong>нию, этого н<strong>е</strong>достаточно, чтобы изб<strong>е</strong>жать пробл<strong>е</strong>м.<br />

Пробл<strong>е</strong>м ы с производит<strong>е</strong>льностью<br />

Вы зам<strong>е</strong>тили, как зам<strong>е</strong>для<strong>е</strong>тся симулятор, когда вс<strong>е</strong> пч<strong>е</strong>лы зал<strong>е</strong>тают в ул<strong>е</strong>й? Особ<strong>е</strong>нно это<br />

зам<strong>е</strong>тно, <strong>е</strong>сли добавить пч<strong>е</strong>л, ув<strong>е</strong>личив константу в класс<strong>е</strong> Hive. О братит<strong>е</strong> внимани<strong>е</strong>, как<br />

при этом м<strong>е</strong>ня<strong>е</strong>тся частота кадров.<br />

О<br />

Н<strong>е</strong>полная прозрачность срона<br />

И другая, совс<strong>е</strong>м отд<strong>е</strong>льная пробл<strong>е</strong>ма. Графич<strong>е</strong>ский файл с цв<strong>е</strong>тком им<strong>е</strong><strong>е</strong>т прозрачный<br />

фон. Это позволя<strong>е</strong>т пом<strong>е</strong>стить цв<strong>е</strong>ты на фон формы, но н<strong>е</strong> оч<strong>е</strong>нь красиво выглядит, когда<br />

цв<strong>е</strong>ты начинают п<strong>е</strong>р<strong>е</strong>крываться.<br />

Прозрачный фоновый цб<strong>е</strong>ид<br />

эл<strong>е</strong>м <strong>е</strong>нт а PictureBox озня<br />

т <strong>е</strong> т , что на<br />

в эт ом м <strong>е</strong>ст <strong>е</strong> будут выво<br />

диться прозрачны<strong>е</strong> пикс<strong>е</strong>лы.<br />

сквозь кот оры<strong>е</strong> буд<strong>е</strong>т про<br />

ст уп ат ь фон ^ В £ ^ - ^ о<br />

эт о н<strong>е</strong> вс<strong>е</strong>гда т о. что нам<br />

нужно.<br />

Л<br />

Когда один эл<strong>е</strong>м <strong>е</strong>нт<br />

PictureBox оказыва<strong>е</strong>тся<br />

пов<strong>е</strong>рх другого. С * рису<strong>е</strong>т<br />

прозрачны<strong>е</strong> пикс<strong>е</strong>лы, удаляя<br />

част ь пикс<strong>е</strong>лов с нижн<strong>е</strong>го<br />

эл<strong>е</strong>м<strong>е</strong>нт а.<br />

5он пч<strong>е</strong>л такж<strong>е</strong> н<strong>е</strong>достаточно прозрач<strong>е</strong>н<br />

Каж<strong>е</strong>тся, парам<strong>е</strong>тр C o l o r .T r a n s p a r e n t им<strong>е</strong><strong>е</strong>т ряд огранич<strong>е</strong>ний. Когда пч<strong>е</strong>лы садится на<br />

цв<strong>е</strong>ток, появля<strong>е</strong>тся выр<strong>е</strong>занный прямоугольный фрагм<strong>е</strong>нт. П розрачность лучш<strong>е</strong> проявля<strong>е</strong>тся<br />

внутри улья, но при п<strong>е</strong>р<strong>е</strong>крытии изображ<strong>е</strong>ний пч<strong>е</strong>л возника<strong>е</strong>т та ж<strong>е</strong> пробл<strong>е</strong>ма. Кром<strong>е</strong><br />

того, <strong>е</strong>сли присмотр<strong>е</strong>ться к пч<strong>е</strong>лам, п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щающимся по улью, можно зам<strong>е</strong>тить, как искажа<strong>е</strong>тся<br />

изображ<strong>е</strong>ни<strong>е</strong>.<br />

дальш<strong>е</strong> > 599


н<strong>е</strong>хватка р<strong>е</strong>сурсов<br />

Пробл<strong>е</strong>мы с производит<strong>е</strong>льностью<br />

Загруж<strong>е</strong>нны<strong>е</strong> изображ<strong>е</strong>ния пч<strong>е</strong>л им<strong>е</strong>ют большой разм<strong>е</strong>р. Д<strong>е</strong>йствит<strong>е</strong>льно большой. О ткройт<strong>е</strong> одно из<br />

них в программ<strong>е</strong> просмотра и уб<strong>е</strong>дит<strong>е</strong>сь. Это означа<strong>е</strong>т, что эл<strong>е</strong>м<strong>е</strong>нт P i c t u r e B o x ужима<strong>е</strong>т изображ<strong>е</strong>ни<strong>е</strong><br />

при каждом изм<strong>е</strong>н<strong>е</strong>нии. А в<strong>е</strong>дь изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> масштаба изображ<strong>е</strong>ния занима<strong>е</strong>т вр<strong>е</strong>мя. Им<strong>е</strong>нно поэтому<br />

движ<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>л зам<strong>е</strong>для<strong>е</strong>тся, когда они зал<strong>е</strong>тают в ул<strong>е</strong>й. П розрачный фон эл<strong>е</strong>м<strong>е</strong>нта B e e C o n t r o l удваива<strong>е</strong>т<br />

работу: сначала тр<strong>е</strong>бу<strong>е</strong>тся ум<strong>е</strong>ньшить изображ<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>лы, а зат<strong>е</strong>м участок фона, на котором будут<br />

выводиться прозрачны<strong>е</strong> пикс<strong>е</strong>лы.<br />

В<strong>е</strong><strong>е</strong> animation l.png<br />

Изображ<strong>е</strong>ни<strong>е</strong> пч<strong>е</strong>лы<br />

в<strong>е</strong>лико, и эл<strong>е</strong>м <strong>е</strong>нт у<br />

PictureBox в каждом<br />

кадр<strong>е</strong> т р<strong>е</strong>бу<strong>е</strong>т ся<br />

вр<strong>е</strong>м я, чтобы <strong>е</strong>го<br />

ум<strong>е</strong>ньш ит ь.<br />

J<br />

Hive (Inside).png<br />

Э л<strong>е</strong>м<strong>е</strong>нт P ic t u r e B o x ум <strong>е</strong>ньш а<strong>е</strong>т<br />

картинку с изображ <strong>е</strong>ни<strong>е</strong>м пч<strong>е</strong>лы .<br />

Это заним а<strong>е</strong>т вр<strong>е</strong>м я...<br />

Карт инка с изображ<strong>е</strong>ни<strong>е</strong>м<br />

внут р<strong>е</strong>нн<strong>е</strong>го уст р о й ­<br />

ст ва улья тож<strong>е</strong> огромна.<br />

Каждый раз, когда п<strong>е</strong>р<strong>е</strong>д<br />

н<strong>е</strong>й оказыва<strong>е</strong>тся пч<strong>е</strong>ла,<br />

эл<strong>е</strong>м <strong>е</strong>нт PictureBox<br />

ум <strong>е</strong>ньш а<strong>е</strong>т <strong>е</strong><strong>е</strong> до нужного<br />

разм <strong>е</strong>ра.<br />

...поэтом у для ув<strong>е</strong>лич<strong>е</strong>ния производит<strong>е</strong>льности сим улятора картинку<br />

нужно ум <strong>е</strong>ньш ить до <strong>е</strong><strong>е</strong> отображ<strong>е</strong>ния.<br />

600 глава 13


д л я у в<strong>е</strong>лич<strong>е</strong>ния и р и и а ь и д и гсльиис 1И Д^иао^гио плпо^си/и'ю«! \<br />

м<strong>е</strong>тод, м<strong>е</strong>няющий разм<strong>е</strong>р изображ<strong>е</strong>ния в мом<strong>е</strong>нт <strong>е</strong>го загрузки, что-<br />

^<br />

б ы для о т о б р а ж <strong>е</strong> н и я пч<strong>е</strong>л и ф о н о в о г о рисунка улья пользоваться у ж <strong>е</strong> ^ у 1Х р а Ж Н 0 Н и 0<br />

п т м а с ш т а б и п о в а н н ы м и в<strong>е</strong>осиями.<br />

^<br />

9 М <strong>е</strong>тод R e s i z e lm a g e для визуализатора<br />

Вс<strong>е</strong> изображ<strong>е</strong>ния про<strong>е</strong>кта хранятся как объ<strong>е</strong>кты Bitmap. Вот статич<strong>е</strong>ский м<strong>е</strong>тод, м<strong>е</strong>няющий их<br />

разм<strong>е</strong>р, который нужно добавить в класс R e nderer:<br />

p u b l i c s t a t i c B it m a p R e s iz e lm a g e ( B it m a p p i c t u r e , i n t w i d t h , i n t h e i g h t ) {<br />

B it m a p r e s i z e d P i c t u r e = n e w B i t m a p ( w i d t h , h e i g h t ) ;<br />

u s i n g (G rap h ics g r a p h ic s = G r a p h i c s . F r o m l m a g e ( r e s i z e d P i c t u r e ) ) {<br />

g r a p h i c s - D r a w l m a g e ( p i c t u r e , 0 , 0 , w i d t h , h e i g h t ) ;<br />

L t u r n r e s i z e d P i c t u r e - \ Ч т о тако<strong>е</strong> о б ш кт g ra p h ics и как работ а<strong>е</strong>т<br />

^ r e t u r n r e s i z e d P i c t u <strong>е</strong> , данный м<strong>е</strong>т од, М И поговорим чут ь поздн<strong>е</strong><strong>е</strong>.<br />

@ М <strong>е</strong>тод R e s i z e C e l l s для эл<strong>е</strong>м<strong>е</strong>нта B e e C o n t r o l<br />

Эл<strong>е</strong>м<strong>е</strong>нт B e e C o n t r o l хранит собств<strong>е</strong>нны<strong>е</strong> объ<strong>е</strong>кты B i t m a p в вид<strong>е</strong> массива. Вот код, заполняющий<br />

этот массив и дающий каждому эл<strong>е</strong>м<strong>е</strong>нту правильный разм<strong>е</strong>р:<br />

О б ъ <strong>е</strong> к т ы B itm a p , хранящи<strong>е</strong> картинки с изображ<strong>е</strong>ни<strong>е</strong>м пч<strong>е</strong>л,<br />

p r i v a t e B it m a p [] c e l l s = ne w B it m a p [ 4 ] ; при помощи м<strong>е</strong>тода ResizelmageQ. X<br />

p r i v a t e v o i d R e s i z e C e l l s () { \<br />

c e l l s [0 ] = R e n d e r e r . R e s i z e I m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ l , W id t h , H e i g h t ) ;<br />

c e l l s [1] = R e n d e r e r . R e s i z e I m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ 2 , W id t h , H e i g h t ) ; \ J<br />

c e l l s [ 2 ] = R e n d e r e r . R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ 3 , W id t h , H e i g h t ) r > ь С<br />

c e l l s [3 ] = R e n d e r e r . R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ 4 , W id t h , H e ig h t )<br />

}<br />

@ П усть оп<strong>е</strong>ратор s w i t c h работа<strong>е</strong>т с массивом cells, а н<strong>е</strong> с р<strong>е</strong>сурсами<br />

О п<strong>е</strong>ратор switch обработчика событий T i c k зада<strong>е</strong>т свойство B a c k g r o u n d l m a g e :<br />

B a c k g r o u n d lm a g e = P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ l ;<br />

Зам<strong>е</strong>нит<strong>е</strong> Properties .Resources .Bee_animation_l на cells [0 ].Изам<strong>е</strong>нит<strong>е</strong> и остальны<strong>е</strong> строки<br />

case, вв<strong>е</strong>дя на вторую позицию c e l l s [1 ], на тр<strong>е</strong>тью —c e l l s [2 ], на ч<strong>е</strong>тв<strong>е</strong>ртую —c e l l s [3 ], на<br />

пятую - c e l l s [2 ], на позицию default - c e l l s [1 ], чтобы отображались только отмасштабированны<strong>е</strong><br />

рисунки.<br />

Добавить вызов м <strong>е</strong>тода R e s i z e C e l l s О ДЛЯ эл<strong>е</strong>м<strong>е</strong>нта B e e C o n t r o l<br />

Новый м<strong>е</strong>тод R e s i z e C e l l s () долж<strong>е</strong>н вызываться в нижн<strong>е</strong>й части конструктора. Зат<strong>е</strong>м дважды<br />

щ<strong>е</strong>лкнит<strong>е</strong> на строчк<strong>е</strong> B e e C o n t r o l в окн<strong>е</strong> Properties. Откройт<strong>е</strong> в этом окн<strong>е</strong> страницу Events (щ<strong>е</strong>лкнув<br />

на значк<strong>е</strong> с изображ<strong>е</strong>ни<strong>е</strong>м молнии) и дважды щ<strong>е</strong>лкнит<strong>е</strong> на строчк<strong>е</strong> Resize, чтобы добавить<br />

обработчик этого события. Новый обработчик такж<strong>е</strong> долж<strong>е</strong>н вызывать м<strong>е</strong>тод R e s i z e C e l l s (),<br />

чтобы масштабировани<strong>е</strong> формы сопровождалось масштабировани<strong>е</strong>м анимированных картинок.<br />

О вручную выб<strong>е</strong>рит<strong>е</strong> дюново<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong> формы<br />

В окн<strong>е</strong> Properties выб<strong>е</strong>рит<strong>е</strong> для фонового изображ<strong>е</strong>ния улья вариант (п о п <strong>е</strong> ). Зат<strong>е</strong>м в конструктор<strong>е</strong><br />

загрузит<strong>е</strong> вм<strong>е</strong>сто н<strong>е</strong>го отмасштабированно<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong>.<br />

p u b l i c p a r t i a l c l a s s H iv e F o r m : F o rm { Свойство ClientRectangle ф ормы включа<strong>е</strong>т<br />

p u b l i c H iv e F o r m О { f^^ctangte, сод<strong>е</strong>ржащ<strong>е</strong><strong>е</strong> инф орм а-<br />

I n i t i a l i z e C o m p o n e n t O ;<br />

00 отображ а<strong>е</strong>мой области<br />

B a c k g r o u n d lm a g e = R e n d e r e r . R e s i z e l m a g e (<br />

P r o p e r t i e s . R e s o u r c e s . H i v e ___i n s i d e _ , \<br />

C l i e n t R e c t a n g l e . W i d t h , C l i e n t R e c t a n g l e . H e i g h t ) ;<br />

j<br />

^<br />

Запустит<strong>е</strong> сим улятор, он работа<strong>е</strong>т нам ного бы стр<strong>е</strong><strong>е</strong>!


подробно о график<strong>е</strong><br />

Объ<strong>е</strong>кт Graphics<br />

Посмотрим на добавл<strong>е</strong>нный к визуализатору м<strong>е</strong>тод R e s i z e l m a g e {). Он<br />

начина<strong>е</strong>т с создания объ<strong>е</strong>кта B i t m a p тр<strong>е</strong>бу<strong>е</strong>мого разм<strong>е</strong>ра. Зат<strong>е</strong>м при<br />

мощи м<strong>е</strong>тода G r a p h i c s . F r o m l m a g e О созда<strong>е</strong>тся о б ъ <strong>е</strong> к т G r a p h i c s и<br />

использу<strong>е</strong>тся м<strong>е</strong>тод D r a w l m a g e () этого объ<strong>е</strong>кта для отображ<strong>е</strong>ния картинки<br />

на объ<strong>е</strong>кт<strong>е</strong> Bitmap. О братит<strong>е</strong> внимани<strong>е</strong>, каким образом м<strong>е</strong>тоду<br />

D r a w l m a g e {) п<strong>е</strong>р<strong>е</strong>даются парам<strong>е</strong>тры w i d t h и height. Им<strong>е</strong>нно в этот мом<strong>е</strong>нт<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся масштабировани<strong>е</strong>. Након<strong>е</strong>ц вам возвраща<strong>е</strong>тся только<br />

что созданный объ<strong>е</strong>кт Bitmap, который можно использовать в кач<strong>е</strong>ств<strong>е</strong><br />

фонового изображ<strong>е</strong>ния улья или анимированного рисунка пч<strong>е</strong>лы.<br />

ф ормы и эл<strong>е</strong>м<strong>е</strong>нт ы<br />

управл<strong>е</strong>ния снабж<strong>е</strong>ны м <strong>е</strong> ­<br />

т одом CreateGraphicsQj<br />

который возвращ а<strong>е</strong>т<br />

^<br />

Впроч<strong>е</strong>м,<br />

пю ои<strong>е</strong>м ^<br />

скоро<br />

с^ро Ы вс<strong>е</strong><br />

увидит <strong>е</strong> собств<strong>е</strong>нными<br />

глазами.<br />

/<br />

Вы п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т<strong>е</strong> м <strong>е</strong>т о­<br />

ду изображ<strong>е</strong>ни<strong>е</strong> с данными<br />

о том. какую<br />

ширину и высоту оно<br />

должно им<strong>е</strong>ть.<br />

public static Bitmap Resizelmage(Bitmap picture, int width, int height) {<br />

}<br />

Bitmap resizedPicture = new Bitmap(width, height);<br />

using (Graphics graphics = Graphics,Fromlmage(resizedPicture)) {<br />

graphics.Drawlmage(picture, 0, 0, width, height);<br />

} ^ ш т о д FromlmageO возвраш,а<strong>е</strong>т новый обш кт drapkics,^<br />

V _ позволяющий вст авлят ь графич<strong>е</strong>ски<strong>е</strong> f<br />

return resizedPicture; браж<strong>е</strong>ни<strong>е</strong>. Воспользуйт<strong>е</strong>сь функци<strong>е</strong>й IntelliSense аля у<br />

ч<strong>е</strong>ния м <strong>е</strong>т одов, принадл<strong>е</strong>жащих классу Graphics. Н априм<br />

<strong>е</strong>р, м <strong>е</strong>т од Praw lm ageQ копиру<strong>е</strong>т<br />

resizedPicture с координатой (О. О) и<br />

f<br />

соот в<strong>е</strong>т ст вии с заданными парам <strong>е</strong>т рам и w id th и height.<br />

Масштабировани<strong>е</strong> изоб|>а)к<strong>е</strong>ния<br />

П<strong>е</strong>р<strong>е</strong>тащ ит<strong>е</strong> кнопку на форму F i e l d и добавьт<strong>е</strong> к н<strong>е</strong>й этот код,<br />

создающий эл<strong>е</strong>м<strong>е</strong>нт P i c t u r e B o x разм<strong>е</strong>ром 100 хЮО пикс<strong>е</strong>лов<br />

с ч<strong>е</strong>рной лини<strong>е</strong>й по краю, что позволя<strong>е</strong>т оц<strong>е</strong>нить <strong>е</strong>го разм<strong>е</strong>р.<br />

Зат<strong>е</strong>м м<strong>е</strong>тод R e s i z e l m a g e {) масштабиру<strong>е</strong>т картинку пч<strong>е</strong>лы до<br />

80 X 40 пикс<strong>е</strong>лов и назнача<strong>е</strong>т свойству Image. Посл<strong>е</strong> добавл<strong>е</strong>ния<br />

к форм<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нта P i c t u r e B o x появля<strong>е</strong>тся пч<strong>е</strong>ла,<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e)<br />

{<br />

}<br />

P i c t u r e B o x b e e P i c t u r e = n e w P i c t u r e B o x 0 ;<br />

b e e P i c t u r e . L o c a t i o n = n e w P o i n t d O , 1 0 ) ;<br />

b e e P i c t u r e . S iz e = n e w S iz e d O O , 1 0 0 ) ;<br />

b e e P i c t u r e . B o r d e r S t y l e = B o r d e r S t y l e . F i x e d S i n g l e ;<br />

b e e P i c t u r e . I m a g e = R e n d e r e r . R e s i z e l m a g e (<br />

P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ l , 8 0 , 4 0 ) ;<br />

C o n t r o l s . A d d ( b e e P i c t u r e ) ;<br />

Вы наблюда<strong>е</strong>т<strong>е</strong> проц<strong>е</strong>сс масштабирования<br />

изображ<strong>е</strong>ния—сжатая карт инка'^<br />

намного м<strong>е</strong>ньш<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нта PictureBox.<br />

И м<strong>е</strong>тод ResizelmageQ ум<strong>е</strong>ньшит р а з­<br />

м<strong>е</strong>р эл<strong>е</strong>м<strong>е</strong>нта.<br />

602 глава 13<br />

^ТЬ<strong>е</strong>й<strong>е</strong>и<br />

^<br />

Это прим<strong>е</strong>р. Закончив <strong>е</strong>го,<br />

удалит<strong>е</strong> кнопку и код.<br />

М<strong>е</strong>тод Resizelmage ( )<br />

созда<strong>е</strong>т объ<strong>е</strong>кт<br />

Graphics, рисующий<br />

на н<strong>е</strong>видимом<br />

объ<strong>е</strong>кт<strong>е</strong> Bitmap. Он<br />

возвраща<strong>е</strong>т о^<strong>е</strong>кт<br />

Bitmap, который<br />

и отобража<strong>е</strong>тся на<br />

форм<strong>е</strong> или эл<strong>е</strong>м<strong>е</strong>нт<strong>е</strong><br />

KctureBox.


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Объ<strong>е</strong>кт Bitmap<br />

Что происходит с графич<strong>е</strong>скими файлами, которы<strong>е</strong><br />

импортируются в р<strong>е</strong>сурсы про<strong>е</strong>кта? Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong><br />

способ доступа к ним — P r o p e r t i e s .Resources.<br />

Н о как им<strong>е</strong>нно поступа<strong>е</strong>т с ними прилож<strong>е</strong>ни<strong>е</strong>?<br />

.NET п р <strong>е</strong> в р а щ а <strong>е</strong> т и з о б р а ж <strong>е</strong> н и я в объ<strong>е</strong>кт Bitmap:<br />

Если пробл<strong>е</strong>м с производит<strong>е</strong>льностью<br />

н<strong>е</strong>т,<br />

добавляйт<strong>е</strong> пч<strong>е</strong>л, пока<br />

программа н<strong>е</strong> зам<strong>е</strong>длит<br />

работу!<br />

Класс Bitmap им<strong>е</strong><strong>е</strong>т н<strong>е</strong>сколько п<strong>е</strong>р<strong>е</strong>грцж<strong>е</strong>нных<br />

конструкторов. Этот загружа<strong>е</strong>т графич<strong>е</strong>ский<br />

файл с диска. Если п<strong>е</strong>р<strong>е</strong>дать <strong>е</strong>мц<br />

ц<strong>е</strong>лы<strong>е</strong> числа, указывающи<strong>е</strong> ж<strong>е</strong>ла<strong>е</strong>мы<strong>е</strong> ширина<br />

и высоту, р<strong>е</strong>зультатом стан<strong>е</strong>т обь<strong>е</strong>кт<br />

Bitmap, которому пока н<strong>е</strong> сопоставл<strong>е</strong>но никакого<br />

рисунка.<br />

j i t m a p bee = new Bitmap("Bee animation 1 . p n g " )<br />

Bee animation 1-png<br />

Отобра)к<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>кта Bitmap<br />

Загруж<strong>е</strong>нны<strong>е</strong> в объ<strong>е</strong>кты B itm ap изображ<strong>е</strong>ния форма показыва<strong>е</strong>т<br />

на экран<strong>е</strong> при помощи сл<strong>е</strong>дующ<strong>е</strong>го кода:<br />

Эта<br />

рант иру<strong>е</strong>т<br />

. П <strong>е</strong> « ”<br />

using (Graphics g CreateGraphicsО ) {<br />

на<br />

га-<br />

g .Drawlmage(myBitmap, 30, 30, 150, 150);<br />

f<br />

М<strong>е</strong>тод DrawlmaaeQ использу<strong>е</strong>т<br />

объ<strong>е</strong>кт Bitmap в кач<strong>е</strong>ств<strong>е</strong> Г<br />

...и разм<strong>е</strong>р. 1 5 0 X ISO пикс<strong>е</strong>лов.<br />

изображ<strong>е</strong>ния, которо<strong>е</strong> нужно ..начальны<strong>е</strong><br />

нарисовать...<br />

координаты X и Y...<br />

Ч<strong>е</strong>м они больш<strong>е</strong>...<br />

Вы обратили внимани<strong>е</strong> на два посл<strong>е</strong>дних парам<strong>е</strong>тра м<strong>е</strong>тода<br />

D r a w l m a g e () ? Что, <strong>е</strong>сли изображ<strong>е</strong>ни<strong>е</strong>, пом<strong>е</strong>ща<strong>е</strong>мо<strong>е</strong><br />

в объ<strong>е</strong>кт Bitmap, им<strong>е</strong><strong>е</strong>т разм<strong>е</strong>р 175 х 175? Его тр<strong>е</strong>бу<strong>е</strong>тся<br />

ум<strong>е</strong>ньшить до разм<strong>е</strong>ра 150 х 150. А как быть, <strong>е</strong>сли объ<strong>е</strong>кт<br />

B i t m a p сод<strong>е</strong>ржит изображ<strong>е</strong>ни<strong>е</strong> разм<strong>е</strong>ром 1500 х 2025?<br />

М асштабировани<strong>е</strong> произойд<strong>е</strong>т намного м<strong>е</strong>дл<strong>е</strong>нн<strong>е</strong><strong>е</strong>....<br />

Это изображ<strong>е</strong>ни<strong>е</strong><br />

им<strong>е</strong><strong>е</strong>т разм<strong>е</strong>р<br />

3 0 0 X 5 0 0<br />

пикс<strong>е</strong>лов...<br />

М асш табировани<strong>е</strong> изображ<strong>е</strong>ний<br />

тр<strong>е</strong>бу<strong>е</strong>т больш ой производит<strong>е</strong>льности!<br />

Нич<strong>е</strong>го страш ного,<br />

<strong>е</strong>сли эта проц<strong>е</strong>дура явля<strong>е</strong>тся<br />

однократной. Но когда <strong>е</strong><strong>е</strong> приходится<br />

вы полнять в КАЖД01У!<br />

КА ДРЕ, работа програм мы зам<strong>е</strong>для<strong>е</strong>тся.<br />

И м <strong>е</strong>нно со слиш ком<br />

больш им разм<strong>е</strong>ром загруж <strong>е</strong>нны<br />

х вами изображ <strong>е</strong>ний связана<br />

слиш ком м<strong>е</strong>дл<strong>е</strong>нная работа<br />

симулятора.<br />

...ум<strong>е</strong>ньша<strong>е</strong>тся до разм<strong>е</strong>ра й.50 х 1 5 0 пикс<strong>е</strong>лов.<br />

И это зам<strong>е</strong>для<strong>е</strong>т работу симулятора!<br />

дальш<strong>е</strong> ► 603


м<strong>е</strong>тоды создания графики<br />

П ространство им<strong>е</strong>н System.Drawing<br />

Объ<strong>е</strong>кт G r a p h i c s принадл<strong>е</strong>жит пространству им<strong>е</strong>н S y s t e m .<br />

D rawing. В . N E T F r a m e w o r k им<strong>е</strong><strong>е</strong>тся набор инструм<strong>е</strong>нтов<br />

для работы с графикой, намного пр<strong>е</strong>восходящий по возможностям<br />

знакомый вам PictureBox. Вы мож<strong>е</strong>т<strong>е</strong> рисовать ф ормы,<br />

работать со шрифтами и сложной графикой... благодаря<br />

объ<strong>е</strong>кту G raphics. Он созда<strong>е</strong>тся каждый раз, когда тр<strong>е</strong>бу<strong>е</strong>тся<br />

добавить или отр<strong>е</strong>дактировать графич<strong>е</strong>ский фрагм<strong>е</strong>нт. Зат<strong>е</strong>м<br />

вам оста<strong>е</strong>тся воспользоваться <strong>е</strong>го м<strong>е</strong>тодами.<br />

называют<br />

иногда<br />


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Знакомство с 6 D I +<br />

Объ<strong>е</strong>кт G r a p h i c s позволя<strong>е</strong>т рисовать любы<strong>е</strong> формы<br />

и изображ<strong>е</strong>ния. Вы вызыва<strong>е</strong>т<strong>е</strong> <strong>е</strong>го м<strong>е</strong>тоды, и на создавш<strong>е</strong>м<br />

<strong>е</strong>го объ<strong>е</strong>кт<strong>е</strong> появля<strong>е</strong>тся нужный рисунок.<br />

лагат ься ст рока Ms/na с ~<br />

В прот ивном случа<strong>е</strong> при<br />

п ро<strong>е</strong>кт у ф орм ы ИГР ^°°^вл<strong>е</strong>нии к<br />

Завит э Ц Т ^ р ^ в доу<br />

т рочку б класс эт ой формы.<br />

О<br />

О<br />

Начн<strong>е</strong>м с создания объ<strong>е</strong>кта G r a p h i с s . Используйт<strong>е</strong><br />

что этот объ<strong>е</strong>кт р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс I D i s p o s a b l e<br />

пользуйт<strong>е</strong>сь оп<strong>е</strong>ратором using:<br />

u s i n g ( G r a p h ic s g = t h i s . C r e a t e G r a p h i c s ()<br />

м<strong>е</strong>тод C r e a t e G r a p h i c s () формы. Помнит<strong>е</strong>,<br />

(), поэтому при создании нового экз<strong>е</strong>мпляра<br />

Помнит<strong>е</strong>, что изображ<strong>е</strong>ни<strong>е</strong> появля<strong>е</strong>тся<br />

I на объ<strong>е</strong>кт <strong>е</strong>, создавил<strong>е</strong>м эт о т экз<strong>е</strong>мпляр.<br />

Чтобы нарисовать линию, вызовит<strong>е</strong> м<strong>е</strong>тод D r a w L i n e {) и укажит<strong>е</strong> координаты X и Y начальной<br />

и кон<strong>е</strong>чной точ<strong>е</strong>к:<br />

К оординат а начальной точки...<br />

g . D r a w L i n e ( P e n s . B l u e , 3 0 , 1 0 , 1 0 0 , 4 5 ) ;<br />

. ...координата кон<strong>е</strong>чной точки.<br />

то ж<strong>е</strong> само<strong>е</strong> можно сд<strong>е</strong>лать при помош;и класса Point:<br />

мож <strong>е</strong>т<strong>е</strong> выбирать<br />

цо<strong>е</strong>т а, дост ат очд<br />

. D r a w L i n e ( P e n s . B lu e , n e w P o i n t ( 3 0 , 4 5 ) , n e w P o i n t ( l O O , 1 0 ) ) ; HO вв<strong>е</strong>ст и «C olor»,<br />

«P en s» или «B rushes»<br />

^<br />

„ пост авит ь т очку, и в<br />

Этот код рису<strong>е</strong>т залитый с<strong>е</strong>рым цв<strong>е</strong>том прямоугольник с голубой рамкой, окн<strong>е</strong> IntelliSense поя-<br />

Его разм<strong>е</strong>р зада<strong>е</strong>т объ<strong>е</strong>кт R e c t a n g l e . В наш<strong>е</strong>м случа<strong>е</strong> в<strong>е</strong>рхний л<strong>е</strong>вый угол вится п<strong>е</strong>р<strong>е</strong>ч<strong>е</strong>нь цв<strong>е</strong>тов.<br />

находится в точк<strong>е</strong> (150, 15), ш ирина 140 пикс<strong>е</strong>лов, а высота 90 пикс<strong>е</strong>лов.<br />

g . F i l l R e c t a n g l e ( B r u s h e s . S l a t e G r a y , n e w R e c t a n g l e ( 1 5 0 , 1 5 , 1 4 0 ,<br />

g . D r a w R e c t a n g l e ( P e n s . S k y B lu e , n e w R e c t a n g l e (1 5 0 , 1 5 , 1 4 0 , 9 0 ) ) ;<br />

Для рисования окружност<strong>е</strong>й и эллипсов пользуйт<strong>е</strong>сь м<strong>е</strong>тодами D r a w C i r c l e () или<br />

F i l l C i r c l e О . Разм<strong>е</strong>р формы зада<strong>е</strong>т объ<strong>е</strong>кт Re c t a n g l e . Сл<strong>е</strong>дующий код рису<strong>е</strong>т<br />

сдвинуты<strong>е</strong> друг относит<strong>е</strong>льно друга для создания эф ф <strong>е</strong>кта т<strong>е</strong>ни эллипсы:<br />

д .F i l l E l l i p s e ( B r u s h e s . D a r k G r a y , n e w R e c t a n g l e ( 4 5 , 6 5 , 2 0 0 , 1 0 0 ) ) ;<br />

g . F i l l E l l i p s e ( B r u s h e s . S i l v e r , n e w R e c t a n g l e ( 4 0 , 6 0 , 2 0 0 , 1 0 0 ) ) ;<br />

М<strong>е</strong>тод D r a w s t r i n g () вводит т<strong>е</strong>кст. Н о сначала вам нужно создать объ<strong>е</strong>кт Font, опр<strong>е</strong>д<strong>е</strong>ляющий<br />

шрифт. Этот объ<strong>е</strong>кт р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс I D i s p o s a b l e :<br />

u s i n g ( F o n t a r i a l 2 4 B o l d = n e w F o n t ( " A r i a l " , 2 4 , F o n t S t y l e . B o l d ) ) {<br />

}<br />

g . D r a w s t r i n g ( " H i t h e r e ! " , a r i a l 2 4 B o l d , B r u s h e s . R e d , 5 0 , 7 5 ) ;<br />

Выполнив оп<strong>е</strong>рат оры по^<br />

порядку, вы полу^^ит<strong>е</strong><br />

т акую ф орму- В<strong>е</strong>рхний<br />

л<strong>е</strong>вый угол им <strong>е</strong><strong>е</strong>т координату<br />

(О, О).<br />

‘^ аг<strong>е</strong> мы<br />

создавали объ<strong>е</strong>кт Graphics<br />

п оэт ом у на ф орм <strong>е</strong> ^ ’<br />

от сут ст ву<strong>е</strong>т цифра 1 .<br />

дальш<strong>е</strong> ► 605


рису<strong>е</strong>м картинку<br />

Рису<strong>е</strong>м на форм<strong>е</strong><br />

Создадим ново<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong> Ш1п(1о\У5, к о т о р о <strong>е</strong> рису<strong>е</strong>т<br />

картинку п о с л <strong>е</strong> щ <strong>е</strong>л ч к а н а ф о р м <strong>е</strong>.<br />

J a p u c y u n i e э щ о<br />

9 Добавим к форм<strong>е</strong> событи<strong>е</strong> C lic k<br />

На вкладк<strong>е</strong> E ven ts ок н а P r o p e r tie s найдит<strong>е</strong> событи<strong>е</strong> Click и дважды щ<strong>е</strong>лкнит<strong>е</strong> на н<strong>е</strong>м.<br />

Так как нам тр<strong>е</strong>бу<strong>е</strong>тся объ<strong>е</strong>кт G r a p h i c s , начнит<strong>е</strong> код обработчика события с оп<strong>е</strong>ратора<br />

using. При работ<strong>е</strong> с GDI+ вы использу<strong>е</strong>т<strong>е</strong> объ<strong>е</strong>кты, р<strong>е</strong>ализующи<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йс I D i s p o s a b l e .<br />

Если н<strong>е</strong> удалить их, они будут потр<strong>е</strong>блять р<strong>е</strong>сурсы до выхода из программы. Поэтому вам<br />

потр<strong>е</strong>бу<strong>е</strong>тся множ<strong>е</strong>ство оп<strong>е</strong>раторов using:<br />

u s i n g ( G r a p h ic s g = C r e a t e G r a p h ic s О ) { Это п<strong>е</strong>рвая ст рочка М<strong>е</strong>тода<br />

обработчика события<br />

Forml_Ciick(). Пост<strong>е</strong>п<strong>е</strong>нно мы<br />

пр<strong>е</strong>доставим вам и остальны<strong>е</strong><br />

О Порядок рисования на форм<strong>е</strong> строчки.<br />

Нам потр<strong>е</strong>бу<strong>е</strong>тся голубой фон, поэтому начн<strong>е</strong>м с голубого прямоугольника, вс<strong>е</strong> остально<strong>е</strong><br />

буд<strong>е</strong>т появляться п о в <strong>е</strong> р х н <strong>е</strong>г о . Вы воспользу<strong>е</strong>т<strong>е</strong>сь свойством формы C l i e n t R e c t a n g l e .<br />

Это объ<strong>е</strong>кт R e c t a n g l e , опр<strong>е</strong>д<strong>е</strong>ляющий границы доступной для рисования области. Для<br />

создания этого объ<strong>е</strong>кта нужно указать координаты в<strong>е</strong>рхн<strong>е</strong>го л<strong>е</strong>вого угла объ<strong>е</strong>кта Point,<br />

а такж<strong>е</strong> ширину и высоту. Посл<strong>е</strong> этого появятся свойства Тор, Left, R i g h t и Bottom. И такой<br />

п о л <strong>е</strong> зн ы й м <strong>е</strong>т о д как C o n ta in s ( ) , в о зв р а щ а ю щ и й зн а ч <strong>е</strong> н и <strong>е</strong> tru e, <strong>е</strong>сл и т о ч к а п оп а­<br />

д а <strong>е</strong>т в н утр ь п р я м оугол ь н и к а. -----------------------------<br />

д . F i l l R e c t a n g l e ( B r u s h e s . S k y B lu e , C l i e n t R e c t a n g l e ) ; Чуть позж<strong>е</strong> этот м<strong>е</strong>тод<br />

вам пригодится! Как<br />

О Нарису<strong>е</strong>м цв<strong>е</strong>ток и пч<strong>е</strong>лу<br />

вы дума<strong>е</strong>т<strong>е</strong>, что вам<br />

пр<strong>е</strong>дстоит д<strong>е</strong>лать с<br />

м<strong>е</strong>тодом СопЬат$0)?<br />

Вы уж<strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, как работа<strong>е</strong>т м<strong>е</strong>тод D r a w l m a g e ().<br />

д . D r a w l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ l , 5 0 , 2 0 , 7 5 , 7 5 ) ;<br />

g . D r a w l m a g e ( P r o p e r t i e s . R e s o u r c e s . F lo w e r , 1 0 , 1 3 0 , 1 0 0 , 1 5 0 ) ;<br />

О Д о «»в и « ручку д л . рисования fl/'<br />

Ручки пр<strong>е</strong>дназнач<strong>е</strong>ны для рисования линий<br />

и им<strong>е</strong>ют толщину. Чтобы нарисовать<br />

заполн<strong>е</strong>нную форму или т<strong>е</strong>кст<br />

<strong>е</strong> *<br />

Рисовани<strong>е</strong> линий осущ<strong>е</strong>ствля<strong>е</strong>тся при помощи объ<strong>е</strong>кта Р<strong>е</strong>п, задающ<strong>е</strong>го цв<strong>е</strong>т и толщину.<br />

Встро<strong>е</strong>нный класс P e n s да<strong>е</strong>т вам множ<strong>е</strong>ство вариантов (наприм<strong>е</strong>р. P e n s .R e d —это тонкая<br />

красная ручка). Конструктор класса Р <strong>е</strong> п позволя<strong>е</strong>т создавать собств<strong>е</strong>нны<strong>е</strong> ручки. Для<br />

рисования залитых форм прим<strong>е</strong>няю тся кисти. Класс B r u s h e s пр<strong>е</strong>доставля<strong>е</strong>т кисти различных<br />

цв<strong>е</strong>тов.<br />

u s i n g (Р <strong>е</strong> п t h i c k B l a c k P e n = n e w P e n ( B r u s h e s . B l a c k , 3 . 0 F ) ) {<br />

606 глава 13


Это мы добавим внутрь<br />

оп<strong>е</strong>ратора using, создающ<strong>е</strong>го<br />

объ<strong>е</strong>кт Р<strong>е</strong>п.<br />

Добавим указы ваю щ ую на цв<strong>е</strong>ток стр<strong>е</strong>лку<br />

Н<strong>е</strong>которы<strong>е</strong> м<strong>е</strong>тоды объ<strong>е</strong>кта G r a p h i c s б<strong>е</strong>рут массив объ<strong>е</strong>ктов P o i n t и со<strong>е</strong>диняют их линиями<br />

или кривыми. М<strong>е</strong>тодом D r a w L i n e s {) нарису<strong>е</strong>м након<strong>е</strong>чник стр<strong>е</strong>лы, а м<strong>е</strong>тодом<br />

D r a w C u r v e О —<strong>е</strong><strong>е</strong> основу. Есть и други<strong>е</strong> м<strong>е</strong>тоды, работающи<strong>е</strong> с массивами точ<strong>е</strong>к (наприм<strong>е</strong>р,<br />

м<strong>е</strong>тод D r a w P o l y g o n () рису<strong>е</strong>т замкнуты<strong>е</strong> формы, а м<strong>е</strong>тод F i l l P o l y g o n O заполня<strong>е</strong>т их).<br />

д . D r a w L i n e s ( t h i c k B l a c k P e n , n e w P o i n t [] {<br />

n e w P o i n t ( 1 3 0 , 1 1 0 ) , n e w P o i n t ( 1 2 0 , 1 6 0 ) , n e w P o i n t (1 5 5 , 1 6 3 ) } ) ;<br />

g . D r a w C u r v e ( t h i c k B l a c k P e n , n e w P o i n t []<br />

n e w P o i n t ( 1 2 0 , 1 6 0 ) , n e w P o i n t ( 1 7 5 ,<br />

{<br />

120)<br />

n e w P o i n t ( 2 1 5 , 7 0 ) } ) ;<br />

}<br />

Зд<strong>е</strong>сь заканчива<strong>е</strong>тся блок<br />

using, объ<strong>е</strong>кт thickBlackPen<br />

удаля<strong>е</strong>тся, так как он нам<br />

дольш<strong>е</strong> н<strong>е</strong> нуж<strong>е</strong>н.<br />

ч<br />

На основ<strong>е</strong> массива точ<strong>е</strong>к м<strong>е</strong>тод<br />

VrawCurveO рису<strong>е</strong>т гладкую,<br />

со<strong>е</strong>диняющую их друг с другом<br />

кривую.<br />

О Добавим шрифт<br />

П<strong>е</strong>рво<strong>е</strong>, что тр<strong>е</strong>бу<strong>е</strong>тся для написания т<strong>е</strong>кста, —создать объ<strong>е</strong>кт Font. Снова напиш<strong>е</strong>м оп<strong>е</strong>ратор<br />

using, так как он р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс I D i s p o s a b l e . Создать ш рифт просто. Сущ<strong>е</strong>ству<strong>е</strong>т<br />

н<strong>е</strong>сколько п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нных конструкторов, самый простой использу<strong>е</strong>т имя шрифта,<br />

<strong>е</strong>го разм<strong>е</strong>р и п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong> FontStyle.<br />

u s i n g ( F o n t f o n t = n e w F o n t ( " A r i a l " , 1 6 , F o n t S t y l e . I t a l i c ) ) {<br />

Добавим т<strong>е</strong>кст « N e c ta r h e re »<br />

Опр<strong>е</strong>д<strong>е</strong>лим м<strong>е</strong>сто для строки, выяснив, какой разм<strong>е</strong>р она буд<strong>е</strong>т им<strong>е</strong>ть на форм<strong>е</strong> при помощи<br />

м<strong>е</strong>тода M e a s u r e S t r i n g (), возвращающ<strong>е</strong>го парам<strong>е</strong>тр SizeF. (SizeF —это в<strong>е</strong>рсия<br />

f l o a t парам<strong>е</strong>тра Size). Так как мы зна<strong>е</strong>м, гд<strong>е</strong> находится кон<strong>е</strong>ц стр<strong>е</strong>лки, пом<strong>е</strong>стим над ним<br />

ц<strong>е</strong>нтральную точку надписи.<br />

S iz e F s i z e = g . M e a s u r e S t r i n g ( " N e c t a r h e r e " , f o n t ) ;<br />

g . D r a w s t r i n g ( " N e c t a r h e r e " , f o n t . B r u s h e s . R e d , n e w P o i n t (<br />

2 1 5 - ( i n t ) s i z e . W i d t h / 2 , 70 - ( i n t ) s i z e . H e i g h t ) ) ;<br />

} _______________<br />

} ^ ^ f 'I® forml ^<br />

Ч f-je забудьт<strong>е</strong> закрыть оба блока using.<br />

Дія создания обь<strong>е</strong>кта Rectangle тр<strong>е</strong>бу<strong>е</strong>тся<br />

точка и парам<strong>е</strong>тр Size ( то <strong>е</strong>сть ширина<br />

и высота). Зат<strong>е</strong>м вы мож<strong>е</strong>т<strong>е</strong> опр<strong>е</strong>д<strong>е</strong>лить<br />

<strong>е</strong>го границы и пров<strong>е</strong>рить м<strong>е</strong>тодом<br />

Contains ( ) , с<strong>е</strong>ть ли внутри обь<strong>е</strong>кт Point.<br />

дальш<strong>е</strong> > 607


как это выглядит?<br />

в руку карандаш<br />

1. Работа с объ<strong>е</strong>ктам и Graphics вклю ча<strong>е</strong>т в с<strong>е</strong>бя<br />

пр<strong>е</strong>дставл <strong>е</strong>ни<strong>е</strong> ваш их объ<strong>е</strong>ктов в координатах X и Y.<br />

Вот код д ля постр о<strong>е</strong>ни я показанной снизу с<strong>е</strong>тки;<br />

вам нуж но за полни ть о тсутствую щ и<strong>е</strong> части.<br />

u s i n g ( G r a p h ic s g = t h i s . C r e a t e G r a p h i c s О )<br />

u s i n g ( F o n t f = n e w F o n t ( " A r i a l " , 6 , F o n t S t y l e . R e g u l a r ) ) {<br />

f o r ( i n t X = 0 ; X < t h i s . W i d t h ; x += 2 0 ) {<br />

} .........................................................................<br />

f o r ( i n t у = 0 ; у < t h i s . H e i g h t ; у += 2 0 ) {<br />

s к too 1ЭЭ t«3 iSQ 29Q Ш m I<br />

2. Что произойд <strong>е</strong>т при запуск<strong>е</strong> прив<strong>е</strong>д<strong>е</strong>нного ниж<strong>е</strong><br />

кода? Н арисуйт<strong>е</strong> р<strong>е</strong>зультат на ф орм <strong>е</strong>, используя<br />

для разм <strong>е</strong>щ <strong>е</strong>ния отд<strong>е</strong>льны х точ<strong>е</strong>к только что<br />

визуализированную с<strong>е</strong>тку.<br />

u s i n g (Р <strong>е</strong> п р <strong>е</strong> п =<br />

n e w Р <strong>е</strong> п ( B r u s h e s . B l a c k , 3 . 0 F ) ) {<br />

g . D r a w C u r v e ( p e n , ne w P o i n t [] {<br />

n e w P o i n t (8 0 , 6 0 ) ,<br />

n e w P o i n t ( 2 0 0 , 4 0 ) ,<br />

n e w P o i n t ( 1 8 0 , 6 0 ) ,<br />

n e w P o i n t ( 3 0 0 , 4 0 ) ,<br />

})<br />

g . D r a w C u r v e ( p e n , n e w P o i n t [] {<br />

n e w P o i n t ( 3 0 0 , 1 8 0 ) , n e w P o i n t ( 1 8 0 , 2 0 0 )<br />

ne w P o i n t ( 2 0 0 , 1 8 0 ) , n e w P o i n t (8 0 , 2 0 0 ) ,<br />

} ) ;<br />

g . D r a w L in e ( p e n , 3 0 0 , 4 0 , 3 0 0 , 1 8 0 ) ;<br />

g . D r a w L in e ( p e n , 8 0 , 6 0 , 8 0 , 2 0 0 ) ;<br />

g . D r a w E l l i p s e ( p e n , 4 0 , 4 0 , 2 0 , 2 0 ) ;<br />

g . D r a w R e c t a n g le ( p e n , 4 0 , 6 0 , 2 0 , 3 0 0 ) ;<br />

g . D r a w L in e ( p e n , 6 0 , 6 0 , 8 0 , 6 0 ) ;<br />

g . D r a w L i n e ( p e n , 6 0 , 2 0 0 , 8 0 , 2 0 0 ) ;<br />

2Q<br />

ed<br />

ЇІ<br />

■ tie<br />

: lab<br />

МЙ<br />

Ж Г<br />

(ёб<br />

»3<br />

' Ш<br />

@<br />

Wl<br />

№<br />

608 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

3. Э тот код работа<strong>е</strong>т с н<strong>е</strong> прави льны м и ф орм ам и.<br />

О пр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong>, какой рисун ок созд а<strong>е</strong>т этот код,<br />

и воспроизв<strong>е</strong>дит<strong>е</strong> <strong>е</strong>го на с<strong>е</strong>тк<strong>е</strong>.<br />

P o l t ы<br />

о й <strong>е</strong> к т о б<br />

Ko/nt и рису<strong>е</strong>т в<strong>е</strong>ршины, которы<strong>е</strong><br />

зат<strong>е</strong>м со<strong>е</strong>диняются линиями.<br />

g . F i l l P o l y g o n ( B r u s h e s . B l a c k , n e w P o i n t [] {<br />

n e w P o i n t ( 6 0 , 4 0 ) , n e w P o i n t ( 1 4 0 , 8 0 ) , n e w P o i n t ( 2 0 0 , 4 0 ) ,<br />

n e w P o i n t ( 3 0 0 , 8 0 ) , n e w P o i n t ( 3 8 0 , 6 0 ) , n e w P o i n t ( 3 4 0 , 1 4 0 ) ,<br />

n e w P o i n t ( 3 2 0 , 1 8 0 ) n e w P o i n t ( 3 8 0 , 2 4 0 ) , n e w P o i n t ( 3 2 0 ,3 0 0 )<br />

n e w P o i n t ( 3 4 0 , 3 4 0 ) n e w P o i n t ( 2 4 0 , 3 2 0 ) , n e w P o i n t ( 1 8 0 ,3 4 0 )<br />

n e w P o i n t ( 2 0 , 3 2 0 ) , n e w P o i n t (6 0 , 2 8 0 ) , n e w P o i n t (1 0 0 , 2 4 0 )<br />

n e w P o i n t (4 0 , 2 2 0 ) , n e w P o i n t ( 8 0 , 1 6 0 ) ,<br />

} ) ;<br />

u s i n g ( F o n t b i g = n e w F o n t ( " T i m e s New R om an"<br />

g . D r a w S t r i n g ( " P o w ! " , b i g , B r u s h e s . W h i t e ,<br />

g . D r a w s t r i n g ( " P o w ! " , b i g , B r u s h e s . W h i t e ,<br />

g . D r a w S t r i n g ( " P o w ! " , b i g , B r u s h e s . W h i t e ,<br />

g . D r a w S t r i n g ( " P o w ! " , b i g , B r u s h e s . W h i t e ,<br />

g . D r a w S t r i n g ( " P o w ! " , b i g . B r u s h e s . W h i t e ,<br />

, 2 4 , F o n t S t y l e . I t a l i c<br />

n e w P o i n t (8 0 , 80 ));<br />

n e w P o i n t (1 2 0 , 120))<br />

n e w P o i n t (1 6 0 , 160))<br />

n e w P o i n t (2 0 0 , 200))<br />

n e w P o i n t (2 4 0 , 240))<br />

)) {<br />

Щ Forml<br />

s r Г “ и Г w r r ISP ST ST w s - !&" p r ssr w<br />

90<br />

16<br />

й<br />

IS<br />

fSB<br />

m-<br />

Ш<br />

ssr<br />

a<br />

Ub<br />

ЯЗ<br />

8^<br />

!5S<br />

BB<br />

Я<br />

Ш<br />

дальш<strong>е</strong> ► 609


выглядит пр<strong>е</strong>красно, но...<br />

в о зь м и в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вам нуж но бы ло вписать н<strong>е</strong>достаю щ ий код и нарисовать<br />

ф игуры , создава<strong>е</strong>м ы <strong>е</strong> двум я д р уги м и ф р агм <strong>е</strong>нтам и кода.<br />

Сначала мы<br />

1


Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> пробл<strong>е</strong>мы с прозрачностью<br />

Давайт<strong>е</strong> устраним арт<strong>е</strong>факты изображ<strong>е</strong>ния в м<strong>е</strong>стах, гд<strong>е</strong> мал<strong>е</strong>ньки<strong>е</strong><br />

картинки п<strong>е</strong>р<strong>е</strong>крываются! Р<strong>е</strong>шить пробл<strong>е</strong>му помож<strong>е</strong>т<br />

м<strong>е</strong>тод D raw lm age (). Мы в<strong>е</strong>рн<strong>е</strong>мся к наш<strong>е</strong>му прилож<strong>е</strong>нию<br />

Windows и отр<strong>е</strong>дактиру<strong>е</strong>м <strong>е</strong>го таким образом, чтобы п<strong>е</strong>р<strong>е</strong>крывающи<strong>е</strong>ся<br />

изображ<strong>е</strong>ния н<strong>е</strong> удаляли фрагм<strong>е</strong>нты друг друга.<br />

Нарисованны<strong>е</strong> нашим визуализатором<br />

п<strong>е</strong>р<strong>е</strong>крывающи<strong>е</strong>ся<br />

пч<strong>е</strong>лы им<strong>е</strong>ли странный<br />

вид.<br />

»ажн<strong>е</strong>ни<strong>е</strong>!<br />

©<br />

Добавьт<strong>е</strong> м<strong>е</strong>тод D r a w B e e {), рисующий пч<strong>е</strong>л на объ<strong>е</strong>ктах Graphics. Он<br />

использу<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>груж<strong>е</strong>нный конструктор D r a w l m a g e (), который опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т<br />

м<strong>е</strong>сто и разм<strong>е</strong>р рисунка при помощи структуры R e c t a n g l e .<br />

p u b l i c v o i d DrawBee( G r a p h ic s g . R e c t a n g le r e c t ) {<br />

}<br />

g . D r a w l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n _ l , r e c t ) ;<br />

Это новый о б р а б о т ч и к со б ы т и я C l ic k . Он располага<strong>е</strong>т в<strong>е</strong>рхний<br />

л<strong>е</strong>вый угол улья вн<strong>е</strong> формы, в точк<strong>е</strong> ( -width, - H e i g h t ) ,<br />

распространяя <strong>е</strong>го на двойную ширину и высоту формы, и да<strong>е</strong>т<br />

возможность м<strong>е</strong>нять <strong>е</strong><strong>е</strong> разм<strong>е</strong>р. Зат<strong>е</strong>м м<strong>е</strong>тодом D r a w B e e () добавляются<br />

ч<strong>е</strong>ты р<strong>е</strong> пч<strong>е</strong>лы.<br />

П<strong>е</strong>р<strong>е</strong>крывающи<strong>е</strong>ся изображ<strong>е</strong>ния<br />

пч<strong>е</strong>л вы глядят<br />

намного лучил<strong>е</strong>.<br />

Ь -<br />

Ш Ш<br />

p r i v a t e v o i d F o r m l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

Сначала рису<strong>е</strong>тся^<br />

фон улья, который<br />

выходит за границы<br />

формы. Зат<strong>е</strong>м мы<br />

рису<strong>е</strong>м ч<strong>е</strong>тыр<strong>е</strong>х п<strong>е</strong>р<strong>е</strong>крывающихся<br />

пч<strong>е</strong>л,<br />

<strong>е</strong>сли они н<strong>е</strong> п<strong>е</strong>р<strong>е</strong>крываются,<br />

ув<strong>е</strong>личьт<strong>е</strong><br />

форму и снова щ <strong>е</strong>лкнит<strong>е</strong><br />

на н<strong>е</strong>й.<br />

О<br />

}<br />

u s i n g ( G r a p h ic s g = C r e a t e G r a p h i c s 0 ) {<br />

}<br />

g . D r a w l m a g e ( P r o p e r t i e s . R e s o u r c e s . H i v e ___i n s i d e _ ,<br />

}<br />

...НО оста<strong>е</strong>тся пробл<strong>е</strong>ма<br />

- W i d t h , - H e i g h t , W id t h * 2 , H e i g h t * 2 ) ;<br />

S iz e s i z e = n e w S i z e ( W i d t h / 5 , H e i g h t / 5)<br />

D r a w B e e ( g , n e w R e c t a n g l e (<br />

n e w P o i n t ( W i d t h / 2 - 5 0 , H e i g h t / 2 - 40), s i z e ) ) ;<br />

D r a w B e e ( g , n e w R e c t a n g l e (<br />

n e w P o i n t ( W i d t h / 2 - 2 0 , H e i g h t / 2 - 60), s i z e ) ) ;<br />

D r a w B e e ( g , n e w R e c t a n g l e (<br />

n e w P o i n t ( W i d t h / 2 - 8 0 , H e i g h t / 2 - 30), s i z e ) ) ;<br />

D r a w B e e ( g , n e w R e c t a n g l e (<br />

n e w P o i n t ( W i d t h / 2 - 9 0 , H e i g h t / 2 - 80), s iz e ) ) ;<br />

Но посмотрит<strong>е</strong>, что произойд<strong>е</strong>т,<br />

<strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>тащить пч<strong>е</strong>л за<br />

границу формы и обратно!<br />

Запустит<strong>е</strong> программу и щ<strong>е</strong>лкнит<strong>е</strong> на форм<strong>е</strong>, чтобы нарисовать<br />

пч<strong>е</strong>л. Но <strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>тащ ить форму за границу экрана, а потом в<strong>е</strong>рнуть,<br />

и зо б р а ж <strong>е</strong> н и <strong>е</strong> и сч <strong>е</strong> зн <strong>е</strong>т ! Сд<strong>е</strong>лайт<strong>е</strong> то ж<strong>е</strong> само<strong>е</strong> с картинкой<br />

«Nectar here», программу для которой вы написали н<strong>е</strong>сколько страниц<br />

назад, —та ж <strong>е</strong> п р обл <strong>е</strong>м а!<br />

Как ВЫ дум а<strong>е</strong>т<strong>е</strong>, что происходит?<br />

дальш<strong>е</strong> ► 611


в<strong>е</strong>рн<strong>е</strong>мся к событиям<br />

Событи<strong>е</strong> Paint<br />

Наша графика исч<strong>е</strong>за<strong>е</strong>т, стоит закрыть <strong>е</strong><strong>е</strong>, наприм<strong>е</strong>р, другим<br />

окном. К счастью, этот н<strong>е</strong>доч<strong>е</strong>т можно исправить<br />

при помош;и о б р а б о т ч и к а с о б ы т и я P a in t . Это событи<strong>е</strong><br />

вызыва<strong>е</strong>тся при п<strong>е</strong>р<strong>е</strong>рисовк<strong>е</strong> формы. Одним из свойств<br />

парам<strong>е</strong>тра P a in tE v e n tA rg s явля<strong>е</strong>тся объ<strong>е</strong>кт G ra p h ic s ,<br />

который собств<strong>е</strong>нно и рису<strong>е</strong>т на эл<strong>е</strong>м<strong>е</strong>нтах управл<strong>е</strong>ния.<br />

О Добавим обработчик события Paint<br />

Дважды щ<strong>е</strong>лкнит<strong>е</strong> на строк<strong>е</strong> Paint на вкладк<strong>е</strong> Events<br />

окна Properties. Событи<strong>е</strong> P a in t возника<strong>е</strong>т всякий<br />

раз, когда появля<strong>е</strong>тся н<strong>е</strong>обходимость п<strong>е</strong>р<strong>е</strong>рисовать<br />

изображ<strong>е</strong>ни<strong>е</strong>.<br />

О<br />

Дважды щ<strong>е</strong>лкнит<strong>е</strong> на строк<strong>е</strong> Ра'тЬ, чтобы<br />

добавить к этому событию обработчик.<br />

Его парам<strong>е</strong>тр PaintEventArgs облада<strong>е</strong>т __<br />

свойством С1трк!С5. поэтому вс<strong>е</strong> вами<br />

нарисованно<strong>е</strong> буд<strong>е</strong>т «прикл<strong>е</strong><strong>е</strong>но» к форм<strong>е</strong>.<br />

С формами и эл<strong>е</strong>м<strong>е</strong>нтами<br />

управл<strong>е</strong>ния связано событи<strong>е</strong><br />

Paint, дающ<strong>е</strong><strong>е</strong> доступ<br />

к объ<strong>е</strong>кту Graphics,<br />

который автоматич<strong>е</strong>ски<br />

п<strong>е</strong>р<strong>е</strong>рисовыва<strong>е</strong>т вс<strong>е</strong> изображ<strong>е</strong>ния.<br />

Properties<br />

Foniil System.Windows.Forms.Form<br />

• ■>“ • ■ .<br />

► Paint Formi_Patnt<br />

Paint<br />

Occur when a controf needs repaînttog.<br />

Воспользуйт<strong>е</strong>сь объ<strong>е</strong>ктом Graphics<br />

В данном случа<strong>е</strong> обработчик событий долж<strong>е</strong>н начинаться н<strong>е</strong> с оп<strong>е</strong>ратора u s in g , а вот так:<br />

p r i v a t e v o i d F o r m l _ P a i n t ( o b j e c t s e n d e r , P a i n t E v e n t A r g s e ) {<br />

G r a p h ic s g = e . G r a p h i c s ;<br />

- a X<br />

' \*f *<br />

О<br />

Объ<strong>е</strong>кт был создан н<strong>е</strong> вами, поэтому в ы н <strong>е</strong> д о л ж н ы <strong>е</strong>г о ун и ч тож ать .<br />

Скопируйт<strong>е</strong> код, рисую щ ий п<strong>е</strong>р<strong>е</strong>крывающихся пч<strong>е</strong>л и цв<strong>е</strong>ты<br />

Добавьт<strong>е</strong> м<strong>е</strong>тод D r a w B e e ( ) с пр<strong>е</strong>дыдущ<strong>е</strong>й страницы к новому пользоват<strong>е</strong>льскому эл<strong>е</strong>м<strong>е</strong>нту управл<strong>е</strong>ния.<br />

Зат<strong>е</strong>м скопируйт<strong>е</strong> код события C l i c k в событи<strong>е</strong> P a i n t к р ом <strong>е</strong> п <strong>е</strong>р в о й стр очки с о п <strong>е</strong>р атор<br />

ом u s in g , в<strong>е</strong>дь у вас уж<strong>е</strong> <strong>е</strong>сть объ<strong>е</strong>кт G r a p h i с s , который называ<strong>е</strong>тся д. Т<strong>е</strong>п<strong>е</strong>рь запустит<strong>е</strong> программу<br />

Графика о ст а <strong>е</strong>т ся н а м <strong>е</strong>ст<strong>е</strong>! ^<br />

Прод<strong>е</strong>лайт<strong>е</strong> аналогичную оп<strong>е</strong>рацию<br />

для рисунка «Nectar here».<br />

Эитсй с<strong>е</strong>бя т р <strong>е</strong> р 7 с о в ы в ^ Т в с <strong>е</strong> 7 прихографикоа<br />

— м<strong>е</strong>тки, т<strong>е</strong>кст, кнопки<br />

формах являются<br />

с Х. Каждый раз, когда форма оказыва<strong>е</strong>тся за<br />

мал<strong>е</strong>нький квадратик<br />

формой, часть, которая была скш т а стан1й экрана или под другой<br />

т о п<strong>е</strong>р<strong>е</strong>ста<strong>е</strong>т ^^АЕИСТВИТВЛЬНОЙ,<br />

<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>рисовку


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

;н <strong>е</strong> н и <strong>е</strong><br />

Используйт<strong>е</strong> получ<strong>е</strong>нны<strong>е</strong> знания о формах и эл<strong>е</strong>м<strong>е</strong>нтах управл<strong>е</strong>ния, чтобы попрактиковаться<br />

в использовании объ<strong>е</strong>ктов B i t m a p и м<strong>е</strong>тода D r a w l m a g e {). Создайт<strong>е</strong> пользоват<strong>е</strong>льский<br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния, который с помощью эл<strong>е</strong>м<strong>е</strong>нта т г а с к в а г з м<strong>е</strong>ня<strong>е</strong>т масштаб изображ<strong>е</strong>ния.<br />

Добавим два эл<strong>е</strong>м<strong>е</strong>нта Т г а с к В а г<br />

О ткройт<strong>е</strong> новый про<strong>е</strong>кт Windows Application. Д о б а в ь т <strong>е</strong> эл <strong>е</strong>м <strong>е</strong> н т U s e r C o n t r o l—присвойт<strong>е</strong><br />

<strong>е</strong>му имя Zoomer, а свойству S i z e - знач<strong>е</strong>ни<strong>е</strong> (300, 300). Создайт<strong>е</strong> два эл<strong>е</strong>м<strong>е</strong>нта<br />

Т г а с к В а г —п<strong>е</strong>рвый внизу, а второй справа. Свойству O r i e n t a t i o n второго эл<strong>е</strong>м<strong>е</strong>нта<br />

присвойт<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> Ve r t i c a l . Свойство M i n i m u m обоих эл<strong>е</strong>м<strong>е</strong>нтов должно равняться<br />

1, M a x i m u m - 1 7 5 , V a l u e - 175, а T i c k S t y l e - None. Для фона выб<strong>е</strong>рит<strong>е</strong> б<strong>е</strong>лый<br />

цв<strong>е</strong>т. Добавьт<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтам обработчик события S c r o l l и заставьт<strong>е</strong> оба обработчика<br />

вызывать м<strong>е</strong>тод I n v a l i d a t e ().<br />

Ваш пользоват<strong>е</strong>льский эл<strong>е</strong>м<strong>е</strong>нт<br />

управл<strong>е</strong>ния связан с событи<strong>е</strong>м Paint<br />

и работа<strong>е</strong>т сов<strong>е</strong>рш<strong>е</strong>нно аналогично<br />

эл<strong>е</strong>м<strong>е</strong>нту, который вы только что<br />

прим<strong>е</strong>няли в форм<strong>е</strong>. Воспользуйт<strong>е</strong>сь<br />

парам<strong>е</strong>тром <strong>е</strong> свойства Paint­<br />

EventArgs. С ним связано свойство<br />

Graphics, и вс<strong>е</strong> нарисованно<strong>е</strong> при<br />

помощи объ<strong>е</strong>кта Graphics окаж<strong>е</strong>тся<br />

на экз<strong>е</strong>мпляр<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния,<br />

который вы п<strong>е</strong>р<strong>е</strong>тащили<br />

из окна Toolbox.<br />

Лом<strong>е</strong>ститг ползунки<br />

на б<strong>е</strong>лый (рон.<br />

13 эплом случа<strong>е</strong> они<br />

сольются с б<strong>е</strong>лым<br />

прямоугольником,<br />

который вы нарису<strong>е</strong>т<strong>е</strong><br />

о кач<strong>е</strong>ств<strong>е</strong> ф о­<br />

нового изображ<strong>е</strong>ния.<br />

О Загрузит<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong> для эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния в объ<strong>е</strong>кт B itm a p<br />

Добавьт<strong>е</strong> пол<strong>е</strong> p h o t o объ<strong>е</strong>кта B i t m a p к эл<strong>е</strong>м<strong>е</strong>нту Zoomer. Используйт<strong>е</strong> конструктор<br />

экз<strong>е</strong>мпляра B i t m a p для загрузки любимого изображ<strong>е</strong>ния. Добавьт<strong>е</strong> к эл<strong>е</strong>м<strong>е</strong>нту событи<strong>е</strong><br />

Paint. О бработчик сформиру<strong>е</strong>т графич<strong>е</strong>ский объ<strong>е</strong>кт, заполнит фон б<strong>е</strong>лым цв<strong>е</strong>том<br />

и зат<strong>е</strong>м с помощью м<strong>е</strong>тода D r a w l m a g e ( ) нарису<strong>е</strong>т сод<strong>е</strong>ржимо<strong>е</strong> поля photo, пом<strong>е</strong>стив<br />

<strong>е</strong>го в<strong>е</strong>рхний л<strong>е</strong>вый угол в точку (10, 10). Его ш ирина опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>тся парам<strong>е</strong>тром<br />

t r a c k B a r l .Value, а высота —t r a c k B a r 2 .Value. П<strong>е</strong>р<strong>е</strong>тащ ит<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нт на форму.<br />

Дбигдя<br />

Ты м<strong>е</strong>ня<strong>е</strong>т<strong>е</strong> разм<strong>е</strong>р<br />

изображ<strong>е</strong>ния:<br />

Когда вы п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щайт<strong>е</strong> ползунки,<br />

эл<strong>е</strong>м<strong>е</strong>нты ТгаскВаг вызывают<br />

м<strong>е</strong>тод Invalidate О . Ваш эл<strong>е</strong>м<strong>е</strong>нт<br />

управл<strong>е</strong>ния вызыва<strong>е</strong>т событи<strong>е</strong><br />

Paint и м<strong>е</strong>ня<strong>е</strong>т разм<strong>е</strong>р фотографии.<br />

дальш<strong>е</strong> > 613


как работа<strong>е</strong>т событи<strong>е</strong> paint<br />

ажн<strong>е</strong>ни<strong>е</strong><br />

Ещ<strong>е</strong> н<strong>е</strong>много попрактику<strong>е</strong>мся в использовании<br />

объ<strong>е</strong>ктов B i t m a p и м<strong>е</strong>тода D r a w l m a g e ().<br />

Построим форму, которая загружа<strong>е</strong>т<br />

І-^ <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong> из файла, а потом м<strong>е</strong>ня<strong>е</strong>т <strong>е</strong>го<br />

масштаб.<br />

public partial class Zoomer : UserControl {<br />

о л ? ““<br />

ширину « » « « « 6<br />

Bitmap photo = new Bitmap(@"c;\Graphics\fluffy_dog.jpg");<br />

public Zoomer0 {<br />

}<br />

InitializeComponent 0 ;<br />

Выб<strong>е</strong>рит<strong>е</strong> собств<strong>е</strong>нный файл — конструктор<br />

Bitmap работа<strong>е</strong>т с множ<strong>е</strong>ством форматов. Попробуйт<strong>е</strong><br />

воспользоваться м<strong>е</strong>тодом OpenFileDialog<br />

для выбора подходящ<strong>е</strong>го изображ<strong>е</strong>ния.<br />

private void ZoomerPaint(object sender, PaintEventArgs e) {<br />

Graphics g = e.Graphics;<br />

g.FillRectangle(Brushes.White, 0, 0, Width, Height);<br />

g.Drawlmage(photo, 10, 10, trackBarl.Value, trackBar2.Value);<br />

^<br />

Мы нарисовали больилой б<strong>е</strong>лый прямоугольник, заполнивший в<strong>е</strong>сь<br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния, пов<strong>е</strong>рх н<strong>е</strong>го было добавл<strong>е</strong>но фото. Посл<strong>е</strong>дни<strong>е</strong><br />

два парам<strong>е</strong>тра опр<strong>е</strong>д<strong>е</strong>ляют разм<strong>е</strong>р изображ<strong>е</strong>ния: trackB arl зада<strong>е</strong>т<br />

ширину, а trackBarZ — высоту.<br />

private void trackBarl_Scroll(object sender, EventArgs e) {<br />

Invalidate();<br />

}<br />

private void trackBar2_Scroll(object sender, EventArgs e) {<br />

Invalidate 0 ;<br />

Каждый раз, когда пользоват<strong>е</strong>ль начина<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>щать<br />

■> К ползунок, вызыва<strong>е</strong>тся событи<strong>е</strong> Scroll. Обработчики этого<br />

■* события вызывают м<strong>е</strong>тод InvalidateÇ) эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния,<br />

что приводит к п<strong>е</strong>р<strong>е</strong>рисовк<strong>е</strong> сод<strong>е</strong>ржимого формы... при этом<br />

новая копия изображ<strong>е</strong>ния им<strong>е</strong><strong>е</strong>т другой разм<strong>е</strong>р.<br />

П<strong>е</strong>р<strong>е</strong>таскивани<strong>е</strong> ползунка вызыва<strong>е</strong>т изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> разизображ<strong>е</strong>ния<br />

при помощи м<strong>е</strong>тода DrawlmageQ.<br />

д.Drawlmage(myBitmap, 30, 30, 150, 150);<br />

614 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

П<strong>е</strong>р<strong>е</strong>рисобка форм и эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

Ча сД<strong>е</strong>ной<br />

Как уж<strong>е</strong> было сказано, начав работать с объ<strong>е</strong>ктами G r a p h i c s , вы получили<br />

контроль над графикой. Вы как бы говорит<strong>е</strong> .NET «Эй, я отв<strong>е</strong>чаю за свои д<strong>е</strong>йствия».<br />

А что д<strong>е</strong>лать, <strong>е</strong>сли вы н<strong>е</strong> хотит<strong>е</strong> п<strong>е</strong>р<strong>е</strong>рисовки формы при <strong>е</strong><strong>е</strong> св<strong>е</strong>ртывании и разв<strong>е</strong>ртывании...<br />

или наоборот, хотит<strong>е</strong>, чтобы форма обновлялась чащ<strong>е</strong>? Разобравшись, что происходит при п<strong>е</strong>р<strong>е</strong>рисовк<strong>е</strong>,<br />

вы смож<strong>е</strong>т<strong>е</strong> управлять проц<strong>е</strong>ссом.<br />

^ Каждая цю рма связана с событи<strong>е</strong>м Paint<br />

О ткройт<strong>е</strong> список событий для любой формы, и вы обнаружит<strong>е</strong><br />

в н<strong>е</strong>м событи<strong>е</strong> P a in t . Оно вызыва<strong>е</strong>тся, <strong>е</strong>сли нужно п<strong>е</strong>р<strong>е</strong>рисовать<br />

форму. Но каким образом? П ри помош;и м<strong>е</strong>тода O n P a in t, унасл<strong>е</strong>дованного<br />

от класса Control. (On в начал<strong>е</strong> им<strong>е</strong>ни м<strong>е</strong>тода означа<strong>е</strong>т, что<br />

м<strong>е</strong>тод вызыва<strong>е</strong>т событи<strong>е</strong>.) П<strong>е</strong>р<strong>е</strong>кройт<strong>е</strong> м<strong>е</strong>тод OnPaint:<br />

прод<strong>е</strong>лывали<br />

такую оп<strong>е</strong>рацию для<br />

м<strong>е</strong>тода DisposeQ.<br />

М <strong>е</strong>т о^^‘^'^^ p r o t e c t e d o v e r r i d e v o i d O n P a in t ( P a i n t E v e n t A r g s e ) {<br />

OnPaint для -— — ^Console. WriteLine ("OnPaint {O} {l}", DateTime .Now, e.ClipRectangle) ;<br />

ЛН?(5ой формы b a s e . O n P a in t (e ) ;<br />

и добавьт<strong>е</strong> }<br />

эту строку.<br />

Подвигайт<strong>е</strong> форму за границы экрана, св<strong>е</strong>рнит<strong>е</strong> <strong>е</strong><strong>е</strong>, спрячьт<strong>е</strong> под другим окном и посмотрит<strong>е</strong> на<br />

окно вывода. Вы увидит<strong>е</strong>, что м<strong>е</strong>тод O n P a i n t вызыва<strong>е</strong>т событи<strong>е</strong> P a i n t каждый раз, когда форма<br />

становится н<strong>е</strong>д<strong>е</strong>йствит<strong>е</strong>льной и нужда<strong>е</strong>тся в п<strong>е</strong>р<strong>е</strong>рисовк<strong>е</strong>. Парам<strong>е</strong>тр C l i p R e c t a n g l e - это<br />

прямоугольник, описывающий ставшую н<strong>е</strong>д<strong>е</strong>йствит<strong>е</strong>льной часть формы. Он п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся свойству<br />

P a i n t E v e n t A r g s события P a i n t и ув<strong>е</strong>личива<strong>е</strong>т производит<strong>е</strong>льность, так как п<strong>е</strong>р<strong>е</strong>рисовк<strong>е</strong><br />

подв<strong>е</strong>рга<strong>е</strong>тся только та часть формы, которой это д<strong>е</strong>йствит<strong>е</strong>льно нужно.<br />

О Используйт<strong>е</strong> м<strong>е</strong>тод I n v a l i d a t e о<br />

Если скрыть, а потом снова сд<strong>е</strong>лать видимой часть формы, .NET вызыва<strong>е</strong>т<br />

событи<strong>е</strong> Paint, которо<strong>е</strong> вызыва<strong>е</strong>т м<strong>е</strong>тод I n v a l i d a t e (), и М<strong>е</strong>тод InvalidateQ<br />

п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т <strong>е</strong>му парам<strong>е</strong>тр R e c t a n g l e , указываюш;ий, какая часть фор- по формы<br />

мы должна быть п<strong>е</strong>р<strong>е</strong>рисована. Посл<strong>е</strong> ч<strong>е</strong>го .NET вызыва<strong>е</strong>т м<strong>е</strong>тод ^^д<strong>е</strong>йствит<strong>е</strong>ль-<br />

OnPaint, инициируюш,ий событи<strong>е</strong> P a i n t формы, и н<strong>е</strong>д<strong>е</strong>йствит<strong>е</strong>льпая<br />

область п<strong>е</strong>р<strong>е</strong>рисовыва<strong>е</strong>тся. J V.<br />

© М <strong>е</strong>тод U p d a te ( ) пом <strong>е</strong>щ а<strong>е</strong>т запрос I n v a l i d a t e нав<strong>е</strong>рх<br />

Форма вс<strong>е</strong> вр<strong>е</strong>мя получа<strong>е</strong>т сообщ<strong>е</strong>ния. В сист<strong>е</strong>м<strong>е</strong>, вызывающ<strong>е</strong>й м<strong>е</strong>тод<br />

Вызвав<br />

OnPaint, когда пов<strong>е</strong>рх формы оказыва<strong>е</strong>тся другой объ<strong>е</strong>кт, сущ<strong>е</strong>ствуют<br />

ваша<br />

и други<strong>е</strong> сообщ<strong>е</strong>ния. Нап<strong>е</strong>чатайт<strong>е</strong> o v e r r i d e и посмотрит<strong>е</strong> список м<strong>е</strong>то- ^ли эл<strong>е</strong>м<strong>е</strong>нт<br />

дов, начинающихся с Оп, каждый из них сообща<strong>е</strong>т что-то форм<strong>е</strong>. М<strong>е</strong>тод уу^равл<strong>е</strong>ния н<strong>е</strong>д<strong>е</strong>й -<br />

U p d a t e () пом<strong>е</strong>ща<strong>е</strong>т сообщ<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода Invalidate в самый в<strong>е</strong>рх списка, ^твит<strong>е</strong>льны и должны<br />

быть п<strong>е</strong>р<strong>е</strong>рисованы.<br />

_<br />

d М <strong>е</strong>тод R e f r e s h О как сум м а м<strong>е</strong>тодов i n v a l i d a t e () и U p d a te О<br />

М<strong>е</strong>тоЭм можно п<strong>е</strong>р<strong>е</strong>-<br />

прямоугольную<br />

Формы и эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния обладают м<strong>е</strong>тодом R e f r e s h (), который Q^/^acmb — она буд<strong>е</strong>т<br />

сначала вызыва<strong>е</strong>т м<strong>е</strong>тод I n v a l i d a t e (), объявляющий н<strong>е</strong>д<strong>е</strong>йствит<strong>е</strong>ль- п<strong>е</strong>р<strong>е</strong>дана и п ар д м <strong>е</strong>^ру<br />

ной всю занятую графикой область, а зат<strong>е</strong>м U p d a t e ( ), гарантирующий PaintEventArgs со<br />

сообщ<strong>е</strong>нию м<strong>е</strong>тода Invalidate самый высокий приорит<strong>е</strong>т.<br />

'<br />

дальш<strong>е</strong> ► 615


что это за м<strong>е</strong>рцани<strong>е</strong>?<br />

Мн<strong>е</strong> каж<strong>е</strong>тся, что м<strong>е</strong>нять разм<strong>е</strong>р<br />

изображ<strong>е</strong>ния пунш<strong>е</strong> в Paint или<br />

Photoshop. Я н<strong>е</strong>прав?<br />

Ql Вы мож<strong>е</strong>т<strong>е</strong> так поступить, при<br />

условии, что им<strong>е</strong>нно вы контролиру<strong>е</strong>т<strong>е</strong><br />

изображ<strong>е</strong>ни<strong>е</strong> и что оно больш<strong>е</strong> н<strong>е</strong> буд<strong>е</strong>т<br />

м<strong>е</strong>нять разм<strong>е</strong>р. Но в большинств<strong>е</strong> случа<strong>е</strong>в<br />

вы получа<strong>е</strong>т<strong>е</strong> графич<strong>е</strong>ский фрагм<strong>е</strong>нт<br />

из сторонн<strong>е</strong>го источника, наприм<strong>е</strong>р, от<br />

колл<strong>е</strong>ги-дизайн<strong>е</strong>ра. В этом случа<strong>е</strong> <strong>е</strong>го разм<strong>е</strong>р<br />

приходится м<strong>е</strong>нять внутри кода.<br />

Но н<strong>е</strong> лучш<strong>е</strong> ли м<strong>е</strong>нять разм<strong>е</strong>р изо-<br />

I раж<strong>е</strong>ния вн<strong>е</strong> .NET?<br />

Q lfla, <strong>е</strong>спи вы ув<strong>е</strong>р<strong>е</strong>ны, что вам никогда<br />

н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся рисунок больш<strong>е</strong>го разм<strong>е</strong>ра.<br />

Ум<strong>е</strong>ньшать изображ<strong>е</strong>ни<strong>е</strong> намного<br />

прощ<strong>е</strong>, ч<strong>е</strong>м ув<strong>е</strong>личивать <strong>е</strong>го.<br />

В большинств<strong>е</strong> случа<strong>е</strong> лучш<strong>е</strong> м<strong>е</strong>нять разм<strong>е</strong>р<br />

графич<strong>е</strong>ского фрагм<strong>е</strong>нта программными<br />

ср<strong>е</strong>дствами. В этом случа<strong>е</strong> вам н<strong>е</strong><br />

прид<strong>е</strong>тся сталкиваться с огранич<strong>е</strong>ниями,<br />

накладыва<strong>е</strong>мыми вн<strong>е</strong>шними программами,<br />

наприм<strong>е</strong>р, получая файлы, пр<strong>е</strong>дназнач<strong>е</strong>нны<strong>е</strong><br />

только для чт<strong>е</strong>ния.<br />

М<strong>е</strong>тод CreateGraphics О<br />

использу<strong>е</strong>т объ<strong>е</strong>кт Graphics для<br />

рисования на форм<strong>е</strong>, а зач<strong>е</strong>м м<strong>е</strong>тод<br />

Fromlmage () вызыва<strong>е</strong>т м<strong>е</strong>тод<br />

Resizelmage О ?<br />

I F ro m lm a g e () восстанавлива<strong>е</strong>т<br />

ъ<strong>е</strong>кт G r a p h ic s для объ<strong>е</strong>кта B itm a p .<br />

И так ж<strong>е</strong> как вызванный для формы м<strong>е</strong>тод<br />

C r e a t e G r a p h ic s ( ) , возвраща<strong>е</strong>т рисующий<br />

на этой форм<strong>е</strong> объ<strong>е</strong>кг G r a p h ic s ,<br />

м<strong>е</strong>тод F ro m lm a g e ( ) восстанавлива<strong>е</strong>т<br />

объ<strong>е</strong>кт G r a p h ic s для рисования на объ<strong>е</strong>кт<strong>е</strong><br />

B itm a p .<br />

Часто»<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

БоЦ|=>ос;ь1<br />

То <strong>е</strong>сть объ<strong>е</strong>кт Graphics ум<strong>е</strong><strong>е</strong>т<br />

н<strong>е</strong> только рисовать на форм<strong>е</strong>?<br />

Q ; Этот объ<strong>е</strong>кт рису<strong>е</strong>т на любой<br />

структур<strong>е</strong>, которая в состоянии <strong>е</strong>го породить.<br />

Объ<strong>е</strong>кт B it m a p да<strong>е</strong>т вам объ<strong>е</strong>кг<br />

G r a p h ic s , при помощи которого вы рису<strong>е</strong>т<strong>е</strong><br />

на н<strong>е</strong>видимом фон<strong>е</strong>. Этот фон мож<strong>е</strong>т<br />

располагаться н<strong>е</strong> только на формах. П<strong>е</strong>р<strong>е</strong>тащит<strong>е</strong><br />

на форму кнопку, п<strong>е</strong>р<strong>е</strong>йдит<strong>е</strong> к коду<br />

и вв<strong>е</strong>дит<strong>е</strong> имя и точку. В окн<strong>е</strong> IntelliSense<br />

вы увидит<strong>е</strong> м<strong>е</strong>тод C r e a t e G r a p h ic s ( ),<br />

возвращающий объ<strong>е</strong>кг G r a p h ic s . Вс<strong>е</strong>, что<br />

вы нарису<strong>е</strong>т<strong>е</strong> на этом объ<strong>е</strong>кт<strong>е</strong>, окаж<strong>е</strong>тся на<br />

кнопк<strong>е</strong>! Аналошчно для эл<strong>е</strong>м<strong>е</strong>нтов L a b e l,<br />

P ic t u r e B o x , S t a t u s S t r i p . . . практич<strong>е</strong>ски<br />

вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты в окн<strong>е</strong> Toolbox обладают<br />

объ<strong>е</strong>ктом G r a p h ic s .<br />

3 * Я думал, что оп<strong>е</strong>ратор using использу<strong>е</strong>тся<br />

при работ<strong>е</strong> с потоками. Зач<strong>е</strong>м<br />

он нуж<strong>е</strong>н при работ<strong>е</strong> с графикой?<br />

Q j Ключ<strong>е</strong>во<strong>е</strong> слово u s i n g прим<strong>е</strong>ня<strong>е</strong>тся<br />

н<strong>е</strong> только для потоков, но и для<br />

любого класса, р<strong>е</strong>ализующ<strong>е</strong>го инт<strong>е</strong>рф<strong>е</strong>йс<br />

I D i s p o s a b l e . Создав экз<strong>е</strong>мпляр<br />

такого класса, вы должны вызвать м<strong>е</strong>тод<br />

D is p o s e ( ) , как только работа с объ<strong>е</strong>ктом<br />

зав<strong>е</strong>ршится. В случа<strong>е</strong> потоков м<strong>е</strong>тод<br />

D is p o s e ( ) гарантиру<strong>е</strong>т закрыти<strong>е</strong> вс<strong>е</strong>х<br />

открытых файлов.<br />

Объ<strong>е</strong>кты G r a p h ic s , Р <strong>е</strong> п И B r u s h<br />

таюк<strong>е</strong> подл<strong>е</strong>жат удал<strong>е</strong>нию. Они тр<strong>е</strong>буют<br />

м<strong>е</strong>ста в памяти и других р<strong>е</strong>сурсов и н<strong>е</strong><br />

вс<strong>е</strong>гда освобождают их. Когда вы рису<strong>е</strong>т<strong>е</strong><br />

что-то один раз, это н<strong>е</strong> им<strong>е</strong><strong>е</strong>т особого знач<strong>е</strong>ния.<br />

Но в большинств<strong>е</strong> случа<strong>е</strong>в код, работающий<br />

с графикой, вызыва<strong>е</strong>тся снова<br />

и снова, наприм<strong>е</strong>р обработчиком события<br />

P a i n t он мож<strong>е</strong>т вызываться много раз<br />

в с<strong>е</strong>кунду. В таких случаях н<strong>е</strong> обойтись<br />

б<strong>е</strong>з м<strong>е</strong>тода D is p o s e { ) . Его использовани<strong>е</strong><br />

гарантиру<strong>е</strong>т оп<strong>е</strong>ратор u s in g . В итог<strong>е</strong><br />

высвобожд<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>сурсов осущ<strong>е</strong>ствится<br />

ср<strong>е</strong>дствами .NET Для вс<strong>е</strong>х объ<strong>е</strong>кгов,<br />

созданных при помощи оп<strong>е</strong>ратора u s in g ,<br />

м<strong>е</strong>тод D is p o s e () автоматич<strong>е</strong>ски<br />

вызыва<strong>е</strong>тся в конц<strong>е</strong> блока. Им<strong>е</strong>нно это<br />

гарантиру<strong>е</strong>т, что ваша программа по м<strong>е</strong>р<strong>е</strong><br />

работы н<strong>е</strong> начн<strong>е</strong>т занимать в памяти вс<strong>е</strong><br />

больш<strong>е</strong> и больш<strong>е</strong> м<strong>е</strong>ста.<br />

Для создания эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния<br />

лучш<strong>е</strong> пользоваться классом<br />

UserControl или насл<strong>е</strong>довани<strong>е</strong>м<br />

от одного из встро<strong>е</strong>нных эл<strong>е</strong>м<strong>е</strong>нтов<br />

Toolbox?<br />

^ I Это зависит от назнач<strong>е</strong>ния ваш<strong>е</strong>го<br />

эл<strong>е</strong>м<strong>е</strong>нта управл<strong>е</strong>ния. Если <strong>е</strong>го функции<br />

сходны с функци<strong>е</strong>й уж<strong>е</strong> сущ<strong>е</strong>ствующ<strong>е</strong>го<br />

в Toolbox эл<strong>е</strong>м<strong>е</strong>нта, используйт<strong>е</strong> насл<strong>е</strong>довани<strong>е</strong>.<br />

Но в большинств<strong>е</strong> случа<strong>е</strong>в<br />

приходится им<strong>е</strong>ть д<strong>е</strong>ло с полностью<br />

пользоват<strong>е</strong>льскими эл<strong>е</strong>м<strong>е</strong>нтами управл<strong>е</strong>ния.<br />

Зато вы мож<strong>е</strong>т<strong>е</strong> п<strong>е</strong>р<strong>е</strong>таскивать на<br />

них эл<strong>е</strong>м<strong>е</strong>нты Toolbox, созданный вами<br />

эл<strong>е</strong>м<strong>е</strong>нт пр<strong>е</strong>красно справля<strong>е</strong>тся с ролью<br />

конт<strong>е</strong>йн<strong>е</strong>ра.<br />

Пользоват<strong>е</strong>льский<br />

эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния<br />

мож<strong>е</strong>т служить<br />

конт<strong>е</strong>йн<strong>е</strong>ром для<br />

других эл<strong>е</strong>м<strong>е</strong>нтов.<br />

616 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Я зам <strong>е</strong>тил како<strong>е</strong>-то м <strong>е</strong>рцани<strong>е</strong> вокруг м о <strong>е</strong> го<br />

эл<strong>е</strong>м <strong>е</strong>нта управл<strong>е</strong>ния Zoom er. Вы столько<br />

го в о р и л и о контрол<strong>е</strong> над гр а ф икой, что я ув<strong>е</strong>р<strong>е</strong>н,<br />

вы зна<strong>е</strong>т<strong>е</strong>, как р<strong>е</strong>ш ить эту м а л <strong>е</strong> н ькую<br />

пробл<strong>е</strong>м у.<br />

Рисовани<strong>е</strong> изображ<strong>е</strong>ния на форм<strong>е</strong><br />

занима<strong>е</strong>т вр<strong>е</strong>мя, даж<strong>е</strong> <strong>е</strong>сли разм<strong>е</strong>р<br />

изображ<strong>е</strong>ния н<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся.<br />

А пр<strong>е</strong>дставьт<strong>е</strong>, что в симулятор<strong>е</strong> м<strong>е</strong>ня<strong>е</strong>тся<br />

разм<strong>е</strong>р каждого изображ<strong>е</strong>ния.<br />

Рисовани<strong>е</strong> вс<strong>е</strong>х этих пч<strong>е</strong>л, цв<strong>е</strong>тов и самого<br />

улья тр<strong>е</strong>бу<strong>е</strong>т вр<strong>е</strong>м<strong>е</strong>ни, и когда вы<br />

видит<strong>е</strong> кон<strong>е</strong>ц проц<strong>е</strong>сса визуализации,<br />

вы воспринима<strong>е</strong>т<strong>е</strong> <strong>е</strong>го как м<strong>е</strong>рцани<strong>е</strong>.<br />

Пробл<strong>е</strong>ма состоит в слишком большом<br />

объ<strong>е</strong>м<strong>е</strong> рису<strong>е</strong>мой графики. Такая ж<strong>е</strong><br />

пробл<strong>е</strong>ма встр<strong>е</strong>ча<strong>е</strong>тся и в н<strong>е</strong>которых<br />

любит<strong>е</strong>льских компьют<strong>е</strong>рных играх.<br />

1<br />

UTVPM<br />

Как избавиться от этого м <strong>е</strong>рцания? Что д<strong>е</strong>лать, <strong>е</strong>сли<br />

вы должны нарисовать на ф орм <strong>е</strong> м нож <strong>е</strong>ство граф и­<br />

ч<strong>е</strong>ских ф рагм <strong>е</strong>нтов? В<strong>е</strong>дь им <strong>е</strong>нно это явля<strong>е</strong>тся причиной.<br />

Отмасштабированная графика буд<strong>е</strong>т выгляд<strong>е</strong>ть лучш<strong>е</strong>, <strong>е</strong>сли п<strong>е</strong>р<strong>е</strong>д вызовом м<strong>е</strong>тода<br />

D r a w l m a g e () объ<strong>е</strong>кта Graphics свойству InterpolationlWlode этого объ<strong>е</strong>кта присвоить<br />

знач<strong>е</strong>ни<strong>е</strong> i n t e r p o l a t i o n M o d e . H i g h Q u a l i t y B i c u b i c . (В в<strong>е</strong>рхнюю часть кода при этом<br />

нужно добавить строку u s i n g S y s t e m .D r a w i n g .2 D ;)<br />

дальш<strong>е</strong> > 617


сглаживани<strong>е</strong> анимации<br />

двойная буф<strong>е</strong>ризация<br />

В<strong>е</strong>рнит<strong>е</strong>сь к масштабиру<strong>е</strong>мому изображ<strong>е</strong>нию и подвигайт<strong>е</strong> ползунки. Обратили внимани<strong>е</strong> на ноявляюш,<strong>е</strong><strong>е</strong>ся<br />

м<strong>е</strong>рцани<strong>е</strong>? Д<strong>е</strong>ло в том, что при каждом п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>ш;<strong>е</strong>нии ползунка обработчик события P a i n t рису<strong>е</strong>т<br />

б<strong>е</strong>лый прямоугольник, а уж<strong>е</strong> на н<strong>е</strong>м - изображ<strong>е</strong>ни<strong>е</strong>. Эта проц<strong>е</strong>дура происходит н<strong>е</strong>сколько раз в<br />

с<strong>е</strong>кунду и им<strong>е</strong>нно она инт<strong>е</strong>рпр<strong>е</strong>тиру<strong>е</strong>тся ч<strong>е</strong>лов<strong>е</strong>ч<strong>е</strong>ским глазом как м<strong>е</strong>рцани<strong>е</strong>. Изб<strong>е</strong>жать м<strong>е</strong>рцания можно<br />

с помощью двойной буф <strong>е</strong>ризации (double buffering). Каждый кадр или яч<strong>е</strong>йка анимации сначала<br />

рисуются в буф<strong>е</strong>р, и новый кадр отобража<strong>е</strong>тся только посл<strong>е</strong> <strong>е</strong>го полной прорисовки. Рассмотрим принцип<br />

работы этой т<strong>е</strong>хники на прим<strong>е</strong>р<strong>е</strong> объ<strong>е</strong>кта Bitmap.<br />

О Вот типичная программа, рисующая на форм<strong>е</strong> при помощи объ<strong>е</strong>кта G r a p h i с s .<br />

©<br />

Добавим в программу объ<strong>е</strong>кт Bitmap, который сыгра<strong>е</strong>т роль буф<strong>е</strong>ра. Т<strong>е</strong>п<strong>е</strong>рь им<strong>е</strong>нно на<br />

н<strong>е</strong>м, а н<strong>е</strong> н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно на форм<strong>е</strong> будут рисоваться графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты.<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда изображ<strong>е</strong>ни<strong>е</strong><br />

рису<strong>е</strong>тся на н<strong>е</strong>видимом D-, .........UUO объ-<br />

<strong>е</strong>кт.<strong>е</strong> Bitmap, пользоват<strong>е</strong>ли<br />

п<strong>е</strong>р<strong>е</strong>станут наблюдать<br />

м<strong>е</strong>рцани<strong>е</strong>. Им сразу пр<strong>е</strong>дставится<br />

окончат<strong>е</strong>льный<br />

^^


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

двойная буф<strong>е</strong>ризация Встро<strong>е</strong>на В формы<br />

U эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния<br />

Включить двойную буф<strong>е</strong>ризацию можно вручную с помощью объ<strong>е</strong>кта<br />

Bitmap, но в <strong>C#</strong> и .NET сущ<strong>е</strong>ству<strong>е</strong>т встро<strong>е</strong>нная подд<strong>е</strong>ржка этой функции.<br />

Д о ст а точ н о п р и св ои ть св ой ств у D o iib le B u f f e r e d зн а ч <strong>е</strong>н и <strong>е</strong><br />

tru e. Выд<strong>е</strong>лит<strong>е</strong> ваш эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния Zoomer, в окн<strong>е</strong> Properties присвойт<strong>е</strong><br />

свойству D o u b l e B u f f e r e d знач<strong>е</strong>ни<strong>е</strong> true, и м<strong>е</strong>рцани<strong>е</strong> пр<strong>е</strong>кратится!<br />

П р о д <strong>е</strong>л а й т<strong>е</strong> эт о и дл я эл <strong>е</strong>м <strong>е</strong>н т а B e e C o n t r o l. Вс<strong>е</strong>х пробл<strong>е</strong>м это<br />

н<strong>е</strong> р<strong>е</strong>шит, но разницу вы увидит<strong>е</strong> сразу.<br />

Для р<strong>е</strong>ш<strong>е</strong>ния пробл<strong>е</strong>м с графикой в наш<strong>е</strong>м симулятор<strong>е</strong> вс<strong>е</strong> готово!<br />

Капитальный р<strong>е</strong>монт симулятора<br />

в сл<strong>е</strong>дующ<strong>е</strong>м упражн<strong>е</strong>нии вы полностью п<strong>е</strong>р<strong>е</strong>строит<strong>е</strong> симулятор. Н а­<br />

в<strong>е</strong>рно<strong>е</strong>, им<strong>е</strong><strong>е</strong>т смысл создать новый про<strong>е</strong>кт и воспользоваться командой<br />

Add » Existing Item... для добавл<strong>е</strong>ния вс<strong>е</strong>х н<strong>е</strong>обходимых файлов.<br />

(Н<strong>е</strong> забудьт<strong>е</strong> отр<strong>е</strong>дактировать пространство им<strong>е</strong>н!)<br />

Вот что мы буд<strong>е</strong>м д<strong>е</strong>лать:<br />

Используя событи<strong>е</strong><br />

Paint при<br />

работ<strong>е</strong> с графикой,<br />

вы мож<strong>е</strong>т<strong>е</strong><br />

включить двойную<br />

буф<strong>е</strong>ризацию,<br />

изм<strong>е</strong>нив<br />

вс<strong>е</strong>го одно свойство.<br />

Q У д ал им пользоват<strong>е</strong>льский эл<strong>е</strong>м<strong>е</strong>нт управл<strong>е</strong>ния B e e C o n t r o l<br />

На пол<strong>е</strong> и в уль<strong>е</strong> н<strong>е</strong> должно остаться эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния. Пч<strong>е</strong>л, цв<strong>е</strong>ты и ул<strong>е</strong>й мы нарису<strong>е</strong>м<br />

ср<strong>е</strong>дствами GDI-t-. Поэтому щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на строчк<strong>е</strong> B e e C o n t r o l .es<br />

в окн<strong>е</strong> Solution Explorer и выб<strong>е</strong>рит<strong>е</strong> команду Delete.<br />

О Д ля управл<strong>е</strong>ния пч<strong>е</strong>лины ми крыльями вам потр<strong>е</strong>бу<strong>е</strong>тся тайм<strong>е</strong>р<br />

Пч<strong>е</strong>лы двигают крыльями намного м<strong>е</strong>дл<strong>е</strong>нн<strong>е</strong><strong>е</strong>, ч<strong>е</strong>м обновляются кадры симулятора, поэтому<br />

вам потр<strong>е</strong>бу<strong>е</strong>тся бол<strong>е</strong><strong>е</strong> м<strong>е</strong>дл<strong>е</strong>нный сч<strong>е</strong>тчик. Это н<strong>е</strong>удивит<strong>е</strong>льно, в<strong>е</strong>дь эл<strong>е</strong>м<strong>е</strong>нт<br />

B e e C o n t r o l был снабж<strong>е</strong>н для этой ц<strong>е</strong>ли встро<strong>е</strong>нным тайм<strong>е</strong>ром.<br />

О Р<strong>е</strong>конструкция визуализатора<br />

Вам больш<strong>е</strong> н<strong>е</strong> понадобятся словари, так как эл<strong>е</strong>м<strong>е</strong>нтов P i c t u r e B o x и B e e C o n t r o l уж<strong>е</strong> н<strong>е</strong>т.<br />

Вм<strong>е</strong>сто них фигуриру<strong>е</strong>т м<strong>е</strong>тод D r a w H i v e ( g ) , рисующий форму H i v e на объ<strong>е</strong>кт<strong>е</strong> Graphics,<br />

и м<strong>е</strong>тод D r a w F i e l d ( g ) , рисующий форму Field.<br />

И напосл<strong>е</strong>док, подклю чим новый визуализатор<br />

Формам H i v e и F i e l d нужны обработчки события Paint. Каждый из них вызыва<strong>е</strong>т м<strong>е</strong>тод<br />

D r a w F i e l d (g) или D r a w H i v e (g) объ<strong>е</strong>кта R enderer. Тайм<strong>е</strong>ры ж<strong>е</strong> вызывают м<strong>е</strong>тод<br />

I n v a l i d a t e (), обновляющий сод<strong>е</strong>ржимо<strong>е</strong> форм. П ри этом связанны<strong>е</strong> с ними обработчики<br />

события P a i n t будут визуализировать кадр.<br />

I<br />

у а Ч н <strong>е</strong> м !<br />

------------------------------- ►<br />

дальш<strong>е</strong> ► 619


п<strong>е</strong>р<strong>е</strong>страива<strong>е</strong>м визуализатор<br />

;н<strong>е</strong>ни<strong>е</strong><br />

Устраним пробл<strong>е</strong>мы с графикой. Воспользу<strong>е</strong>мся объ<strong>е</strong>ктами СгарИ1с8 и двойной<br />

буф<strong>е</strong>ризаци<strong>е</strong>й.<br />

О тр<strong>е</strong>дактиру<strong>е</strong>м м<strong>е</strong>тод RunFram e О основной


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

О fOpMOM Hive и Field тр<strong>е</strong>бу<strong>е</strong>тся открыто<strong>е</strong> свойство R e n d e r e r<br />

Добавьт<strong>е</strong> свойство общ<strong>е</strong>го доступа R e n d e r e r к об<strong>е</strong>им формам:<br />

, , ______ А оёавьт <strong>е</strong> эт о свойство к об<strong>е</strong>ым<br />

public Renderer Renderer { get; set; } 'форМаМ-<br />

He за- f О т*, ^ р <strong>е</strong> д а к тX и р у<br />

ЖЛ.<br />

й тж ^<br />

<strong>е</strong> о б ъ я в - л <strong>е</strong>—----- н и <strong>е</strong> ------- класса R e n d e r e r сл<strong>е</strong>дующим V образом;<br />

м.<br />

p u b l i c c l a s<br />

5ydt>me бадЬт <strong>е</strong>\ ^ _ _______________________ Г.Т_______<br />

R e n d e r e r . То ж <strong>е</strong> са м о <strong>е</strong> нужно сд<strong>е</strong>лать для классов W o r l d , Hive, B e e и F l o w e r и для п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ния<br />

B e e s t a t e .<br />

добавить<br />

эти<br />

моди­<br />

Экз<strong>е</strong>мпляр R e n d e r e r {) созда<strong>е</strong>тся в код<strong>е</strong> кнопки O pen и в м<strong>е</strong>тод<strong>е</strong> R e s e t S i m u l a t o r ( ) .<br />

фика­<br />

торы У далит<strong>е</strong> в с <strong>е</strong> в ы зо в ы м <strong>е</strong>т о д а renderer- R e s e t О . Зат<strong>е</strong>м обновит<strong>е</strong> конструктор объ<strong>е</strong>кта<br />

доступа!<br />

h i v e F o r m . R e n d e r e r = t h i s ;<br />

М<strong>е</strong>тод ResetQ удалял с формы эл<strong>е</strong>м<strong>е</strong>нты<br />

R e n d e r e r , чтобы задать свойство R e n d e r e r для об<strong>е</strong>их форм:<br />

f i e l d F o r m . R e n d e r e r = t h i s ;<br />

управл<strong>е</strong>ний. HO т<strong>е</strong>п<strong>е</strong>рь <strong>е</strong>му н<strong>е</strong>ч<strong>е</strong>го удалять.<br />

О<br />

Настройт<strong>е</strong> двойную буцї<strong>е</strong>ризацию цюрм Hive и Field<br />

Удалит<strong>е</strong> из конструктора формы Hive код задания фонового изображ<strong>е</strong>ния. Зат<strong>е</strong>м удалит<strong>е</strong> вс<strong>е</strong><br />

эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ния из об<strong>е</strong>их форм и п р и св о й т <strong>е</strong> св ой ств у D o u b le B u f f e r e d зн а ч <strong>е</strong>н и <strong>е</strong> t r u e .<br />

Добавьт<strong>е</strong> к формам обработчик события Paint. Он записан для формы Hive, для формы Field<br />

он отлича<strong>е</strong>тся вызовом R e n d e r e r .P a i n t F i e l d {) вм<strong>е</strong>сто R e n d e r e r .P a i n t H i v e ():<br />

p r i v a t e v o i d H i v e F o r m _ P a i n t ( o b j e c t s e n d e r , P a i n t E v e n t A r g s e ) { J<br />

R e n d e r e r . P a i n t H i v e ( e . G r a p h ic s ) ;<br />

g g s двойной буф<strong>е</strong>ризации ваши<br />

} формы будут м<strong>е</strong>рцать!<br />

Удал им из визуализатора код на основ<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтов управл<strong>е</strong>ния и добавим граф ику<br />

Вот что вам нужно сд<strong>е</strong>лать:<br />

★ Удалит<strong>е</strong> словари. Такж<strong>е</strong> вам больш<strong>е</strong> н<strong>е</strong> понадобятся эл<strong>е</strong>м<strong>е</strong>нт B e e C o n t r o l и м<strong>е</strong>тоды<br />

R e n d e r (),D r a w B e e s () и D r a w F l o w e r s ().<br />

★ Для хран<strong>е</strong>ния изображ<strong>е</strong>ний добавьт<strong>е</strong> поля В і t m a p с им<strong>е</strong>нами H i v e Ins ide. H i v e O u t s ide<br />

и Flower. Создайт<strong>е</strong> два массива B i t m a p [] B e e A n i m a t i o n L a r g e и B e e A n i m a t i o n S m a l l .<br />

В каждом из них будут хранится по ч<strong>е</strong>ты р<strong>е</strong> изображ<strong>е</strong>ния пч<strong>е</strong>лы: больши<strong>е</strong> 40x40 и мал<strong>е</strong>ньки<strong>е</strong><br />

20x20. Создайт<strong>е</strong> м<strong>е</strong>тод I n i t i a l i z e l m a g e s О , масштабирующий р<strong>е</strong>сурсы, пом<strong>е</strong>щающий<br />

их в эти ПОЛЯ и вызывающий их из конструктора класса Renderer.<br />

★ Добавьт<strong>е</strong> м<strong>е</strong>тод P a i n t H i v e О , который б<strong>е</strong>р<strong>е</strong>т в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра объ<strong>е</strong>кт G r a p h i c s<br />

и рису<strong>е</strong>т на н<strong>е</strong>м ул<strong>е</strong>й. Н ачнит<strong>е</strong> с голубого прямоугольника, зат<strong>е</strong>м м<strong>е</strong>тодом D r a w -<br />

I m a g e U n s c a l e d () нарисуйт<strong>е</strong> ул<strong>е</strong>й изнутри, а м<strong>е</strong>тодом D r a w I m a g e U n s c a l e d () - находящихся<br />

внутри улья пч<strong>е</strong>л.<br />

★ Добавьт<strong>е</strong> м<strong>е</strong>тод P a i n t F i e l d (), рисующий голубой прямогоульник в в<strong>е</strong>рхн<strong>е</strong>й части<br />

формы и з<strong>е</strong>л<strong>е</strong>ный —в нижн<strong>е</strong>й. Свойства C l i e n t S i z e и C l i e n t R e c t a n g l e укажут разм<strong>е</strong>р<br />

каждой области. М<strong>е</strong>тодом F i l l E l l i p s e {) нарисуйт<strong>е</strong> ж<strong>е</strong>лто<strong>е</strong> солнц<strong>е</strong>, м<strong>е</strong>тодом<br />

D r a w L i n e () - в<strong>е</strong>тку, с которой свиса<strong>е</strong>т ул<strong>е</strong>й, а м<strong>е</strong>тодом D r a w I m a g e U n s c a l e d {) - вид<br />

улья снаружи. Нарисуйт<strong>е</strong> цв<strong>е</strong>ты, а п<strong>е</strong>р<strong>е</strong>д ними - пч<strong>е</strong>л (используйт<strong>е</strong> для этого мал<strong>е</strong>ньки<strong>е</strong><br />

картинки).<br />

★ П о м н и т <strong>е</strong> , что м<strong>е</strong>тод A n i m a t e B e e s {) зада<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> поля cell.<br />

дальш<strong>е</strong> ► 621


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

,'ажн<strong>е</strong>ни<strong>е</strong><br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

u s i n g S y s t e m . D r a w in g ;<br />

p u b l i c c l a s s R en derer {<br />

Избавимся от арт<strong>е</strong>фактов графики в наш<strong>е</strong>м симулятор<strong>е</strong> улья. Используйт<strong>е</strong> двойную<br />

буф<strong>е</strong>ризацию, чтобы сд<strong>е</strong>лать изображ<strong>е</strong>ни<strong>е</strong> ч<strong>е</strong>тким.<br />

Это готовый класс Renderer, включающий<br />

p r i v a t e W o r ld w o r l d ;<br />

p r i v a t e H iv e F o r m h i v e F o r m ;<br />

p r i v a t e F ie ld F o r m f i e l d F o r m ;<br />

--------- м<strong>е</strong>тод AnimateBeesQ. Уб<strong>е</strong>дит<strong>е</strong>сь, что<br />

вы отр<strong>е</strong>дактировали вс<strong>е</strong> три формы,<br />

особ<strong>е</strong>нно<strong>е</strong> внимани<strong>е</strong> уд<strong>е</strong>лит<strong>е</strong> обработчикам<br />

события Paint для форм Hive и Field. Эти<br />

обработчики вызывают м<strong>е</strong>тоды PaintHiveQ<br />

и PaintFieldQ визуализатора, которы<strong>е</strong><br />

и выполняют всю анимацию.<br />

p u b l i c R e n d e r e r ( W o r ld T h e W o r ld ,<br />

t h i s . w o r l d = T h e W o r ld ;<br />

t h i s . h i v e F o r m = h iv e F o r m ;<br />

t h i s . f i e l d F o r m = f i e l d F o r m ;<br />

f i e l d F o r m . R e n d e r e r = t h i s ;<br />

h i v e F o r m . R e n d e r e r = t h i s ;<br />

I n i t i a l i z e l m a g e s { ) ;<br />

H iv e F o r m h iv e F o r m , F i e l d F o r m f i e l d F o r m ) {<br />

* He забудьт<strong>е</strong> вн<strong>е</strong>сти изм<strong>е</strong>н<strong>е</strong>ния в файл<br />

Renderer.cs, объявив класс Renderer, как<br />

public. Прод<strong>е</strong>лайт<strong>е</strong> аналогичную оп<strong>е</strong>рацию<br />

для классов World, Hive, Flower<br />

и Bee, в противном случа<strong>е</strong> вы получит<strong>е</strong><br />

ошибку постро<strong>е</strong>ния.<br />

у'^игл<strong>е</strong><br />

p u b l i c s t a t i c B it m a p R e s iz e lm a g e (Im a g e Im a g e T o R e s iz e ,<br />

B it m a p b i t m a p = n e w B i t m a p ( W i d t h , H e i g h t ) ;<br />

u s i n g ( G r a p h ic s g r a p h i c s = G r a p h i c s . F r o m lm a g e ( b i t m a p ) ) {<br />

^ g r a p h ic s . D r a w lm a g e ( I m a g e T o R e s iz e , 0 , 0 , W id t h , H e i g h t )<br />

r e t u r n b i t m a p ;<br />

i n t W id t h , i n t H e i g h t ) {<br />

} “ сохийня<strong>е</strong>т их в полях<br />

Bitmap обь<strong>е</strong>кта Renderer. В р<strong>е</strong>зультат<strong>е</strong><br />

B it m a p H i v e l n s i d e ;<br />

м<strong>е</strong>тоЬы PaintHiveQ и PaintFormQ<br />

B it m a p H i v e O u t s i d e ;<br />

1 ^^^°^^о с т ь рисовать<br />

B it m a p F lo w e r ;<br />

н<strong>е</strong>масштабированны<strong>е</strong> изображ<strong>е</strong>ния при<br />

B i t m a p [] B e e A n i m a t io n S m a ll;<br />

омощи м<strong>е</strong>тодов PrawlmaaeUnscaledf)<br />

обь<strong>е</strong>кта Graphics формы.<br />

B i t m a p [] B e e A n i m a t io n L a r g e ;<br />

p r i v a t e v o i d I n i t i a l i z e l m a g e s 0 {<br />

H i v e O u t s i d e = R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . H i v e ___o u t s i d e _ , 8 5 , 1 0 0 ) ;<br />

Flower = Resizelmage(Properties.R e s o u r c e s .Flower, 75, 75); ~<br />

H i v e l n s i d e = R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . H i v e i n s i d e<br />

h i v e F o r m . C l i e n t R e c t a n g l e . W id t h , h i v e F o r m . C l i e n t R e c t a n g l e . H e i g h t ) ;<br />

B e e A n i m a t io n L a r g e = n e w B i t m a p [ 4 ] ;<br />

B e e A n i m a t i o n L a r g e [ 0] = R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n 1 ,<br />

B e e A n i m a t i o n L a r g e [ 1] = R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n ~ 2 !<br />

B e e A n i m a t i o n L a r g e [2 ] = R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n i m a t i o n ~ 3 ’<br />

B e e A n i m a t io n L a r g e [3 ] = R e s iz e lm a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n im a t i o n ~ 4 ,'<br />

B e e A n i m a t io n S m a ll = n e w B i t m a p [ 4 ] ; “<br />

B e e A n i m a t i o n S m a l l [0 ] = R e s i z e l m a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n im a t io n _ _ l,<br />

B e e A n i m a t i o n S m a l l [ 1]<br />

= R e s iz e lm a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n im a t i o n _ 2 ,'<br />

B e e A n i m a t i o n S m a l l [2 ] = R e s iz e lm a g e ( P r o p e r t i e s . R e s o u r c e s . B e e _ a n im a t i o n _ 3 ,<br />

B e e A n i m a t i o n S m a l l [3 ]<br />

= Resizelmage(Properties.Resources.Bee_animation 4 '<br />

4 0 ,<br />

4 0 ,<br />

4 0 ,<br />

4 0 ,<br />

20 ,<br />

2 0 ,<br />

2 0 ,<br />

20,<br />

4 0 )<br />

4 0 )<br />

4 0 )<br />

4 0 )<br />

20)<br />

2 0 )<br />

20)<br />

20)<br />

622 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

p u b l i c v o i d PaintHive( G r a p h ic s g ) {<br />

g . F i l l R e c t a n g l e ( B r u s h e s . S k y B l u e , h i v e F o r m . C l i e n t R e c t a n g l e ) ;<br />

g . D r a w I m a g e U n s c a l e d ( H i v e l n s i d e , 0 , 0 ) ;<br />

f o r e a c h (B e e b e e i n w o r l d . B e e s ) {<br />

i f ( b e e . I n s i d e H i v e )<br />

g . D r a w I m a g e U n s c a l e d ( B e e A n i m a t i o n L a r g e [ c e l l ] ,<br />

b e e . L o c a t i o n . X , b e e . L o c a t i o n . Y ) ;<br />

^<br />

Свойсмво формы ClientSize — ЭМ0 объ<strong>е</strong>кт<br />

J<br />

Rectangle, опр<strong>е</strong>д<strong>е</strong>ляющий разм<strong>е</strong>р пр<strong>е</strong>дназна-<br />

. , т, • I<br />

p u b l i c v o i d PaintField( G r a p h ic s g) 1 ч<strong>е</strong>нной для рисования ^ области. j<br />

/<br />

u s i n g (P V---- e n ---------- b ro w n P e n = n e w P e n ( C o l o r . B r o w n , 6 . OF)) { ^<br />

g . F i l l R e c t a n g l e ( B r u s h e s . S k y B l u e , 0 , 0,<br />

f i e l d F o r m . C l i e n t S i z e . W i d t h , f i e l d F o r m . C l i e n t S i z e . H e i g h t /<br />

g . F i l l E l l i p s e ( B r u s h e s . Y e l l o w , n e w R e c t a n g le F ( 5 0 , 1 5 , 7 0 , 70 ));<br />

g . F i l l R e c t a n g l e ( B r u s h e s . G r e e n , 0 , f i e l d F o r m . C l i e n t S i z e . H e i g h t / 2 ,<br />

f i e l d F o r m . C l i e n t S i z e . W i d t h , f i e l d F o r m . C l i e n t S i z e . H e i g h t /<br />

g . D r a w L in e ( b r o w n P e n , n e w P o i n t ( 5 9 3 , 0 ) , n e w P o i n t ( 5 9 3 , 3 0 ));<br />

g . D r a w I m a g e U n s c a le d ( H iv e O u t s id e , 5 5 0 , 20);<br />

f o r e a c h ( F lo w e r f l o w e r i n w o r l d . F l o w e r s ) {<br />

g . D r a w I m a g e U n s c a le d ( F l o w e r , f l o w e r . L o c a t i o n . X , f l o w e r . L o c a t i o n . Y)<br />

f o r e a c h (B e e b e e i n w o r l d . B e e s ) {<br />

i f ( ! b e e . I n s i d e H i v e )<br />

g . D r a w I m a g e U n s c a l e d ( B e e A n i m a t i o n S m a l l [ c e l l ] ,<br />

T ^ VI "V<br />

b e e . L o c a t i o n . X ,<br />

i—^ Л T Л ^<br />

b e e . L o c a t i o n . Y )<br />

}<br />

p r i v a t e i n t c e l l = 0 ;<br />

p r i v a t e i n t fr a m e = 0 ;<br />

p u b l i c v o i d A n im a te B e e s<br />

f r a m e + + ;<br />

i f ( f r a m e >= 6)<br />

f r a m e = 0 ;<br />

s w i t c h ( fr a m e ) {<br />

c a s e<br />

c a s e<br />

c a s e<br />

c a s e<br />

c a s e<br />

c a s e<br />

0 :<br />

1:<br />

2 :<br />

3 :<br />

4 :<br />

5 :<br />

d e f a u l t<br />

c e l l<br />

c e l l<br />

c e l l<br />

c e l l<br />

c e l l<br />

c e l l<br />

: c e l l =<br />

0 {<br />

0;<br />

1;<br />

2;<br />

3;<br />

2;<br />

1;<br />

0;<br />

h i v e F o r m . I n v a l i d a t e О ;<br />

f i e l d F o r m . I n v a l i d a t e ()<br />

b r e a k ;<br />

b r e a k ;<br />

b r e a k ;<br />

b r e a k ;<br />

b r e a k ;<br />

b r e a k ;<br />

b r e a k ;<br />

У К М<strong>е</strong>тод ^ координатам р и с у -<br />

в класс<strong>е</strong> WoИd ^<br />

н<strong>е</strong>5о и з<strong>е</strong>мная<br />

[<br />

<strong>е</strong> т пол<strong>е</strong>. Сначала Р“ ^<br />

пов<strong>е</strong>ркност ь, зат <strong>е</strong>м<br />

д м <strong>е</strong>л<strong>е</strong> этого<br />

^ ул<strong>е</strong>й. ^...„вания оёь<strong>е</strong>ктов им<strong>е</strong><strong>е</strong>т<br />

1^<strong>е</strong>лы.<br />

нарисовать пч<strong>е</strong>л<br />

г ; « “ » . " <br />

3. и заил<strong>е</strong>м<br />

^»ова Z<br />

заил<strong>е</strong>м z . затолл<br />

2 )<br />

2 )<br />

дальш<strong>е</strong> > 623


вывод графич<strong>е</strong>ских фрагм<strong>е</strong>нтов<br />

Выбод на п<strong>е</strong>чать<br />

М <strong>е</strong>тоды объ<strong>е</strong>кта G r a p h i c s , которыми вы пользовались для рисования<br />

на форм<strong>е</strong>, подходят и для вы вода на п<strong>е</strong>чать. Инструм<strong>е</strong>нты .NET для<br />

этой проц<strong>е</strong>дуры находятся в пространств<strong>е</strong> им<strong>е</strong>н S y s t e m . D r a w i n g .<br />

P r i nting. Вам нужно только создать объ<strong>е</strong>кт P rin tD o c u m e n t. С ним<br />

связано событи<strong>е</strong> P r i n t P a g e , которо<strong>е</strong> прим<strong>е</strong>ня<strong>е</strong>тся так ж<strong>е</strong>, как и событи<strong>е</strong><br />

T i c k тайм<strong>е</strong>ра. Зат<strong>е</strong>м тр<strong>е</strong>бу<strong>е</strong>тся вызвать м<strong>е</strong>тод P r i n t () этого<br />

объ<strong>е</strong>кта и расп<strong>е</strong>чатать докум<strong>е</strong>нт. Вот как это выглядит.<br />

э т о<br />

% %<br />

а п <strong>е</strong> Ч а щ а й т <strong>е</strong><br />

Г '<br />

С оздайт<strong>е</strong> п рилож <strong>е</strong>ни<strong>е</strong> W indows и добавьт<strong>е</strong> к форм<strong>е</strong> кнопку В в<strong>е</strong>рхнюю часть кода<br />

формы добавьт<strong>е</strong> строку u sin g S y stem .D raw in g .P rin tin g , Дважды щ<strong>е</strong>лкнит<strong>е</strong> на<br />

кнопк<strong>е</strong> и вв<strong>е</strong>дит<strong>е</strong> код. Вот что появится, когда вы вв<strong>е</strong>д<strong>е</strong>т<strong>е</strong> +=:<br />

о<br />

private void buttonl_Click(object sender, EventArgs<br />

PrintDocument document = new PrintDocument{);<br />

document.PrintPage +=<br />

e) {<br />

j~7i^ P r ln tP a g e E v e r r tH a n d le r ( d o c u m e n t.P r ln tP B g e )r ^ Т р г ё з Г т А В t o in s e T t)<br />

Нажмит<strong>е</strong> Tab, и нужный код появится автоматич<strong>е</strong>ски. Им<strong>е</strong>нно так вы добавляли<br />

обработчики событий в глав<strong>е</strong> 11:<br />

private void buttonl_Click(object sender, EventArgs e) {<br />

PrintDocument document = new P r i n t D o c u m e n t ();<br />

document.PrintPage += new PrintPageEventHandler(document_I»rlntPage);<br />

P f e s s TAB t o g e n e r a te h a n d le r 'd o cu m en tjF rin tp iaB e* i n t h l s ~ e i a ^<br />

Вм<strong>е</strong>сто исключ<strong>е</strong>ния<br />

О ИСР сг<strong>е</strong>н<strong>е</strong>риру<strong>е</strong>т м<strong>е</strong>тод обработки событий и добавит <strong>е</strong>го к форм<strong>е</strong>. 8ы мож<strong>е</strong>т<strong>е</strong> вв<strong>е</strong>сти<br />

void document_PrintPage (object sender, PrintPageEventArqs e) f код обработки<br />

throw new NotlmplementedException О ;<br />

графики... что им<strong>е</strong>нно<br />

, нап<strong>е</strong>чатать в данном<br />

^<br />

/V .______________ случа<strong>е</strong>, вы увидит<strong>е</strong><br />

Парам<strong>е</strong>тр <strong>е</strong> свойства P r i n t P a g e E v e n t A r g s облада<strong>е</strong>т свойством Graphics^. Зам<strong>е</strong>нит<strong>е</strong><br />

посл<strong>е</strong>днюю строку кодом, вызывающим м<strong>е</strong>тоды объ<strong>е</strong>кта <strong>е</strong> .Graphics.<br />

Зав<strong>е</strong>рш ит<strong>е</strong> обработчик события b u t t o n l _ C l i c k , вызвав м<strong>е</strong>тод d o cu m en t.<br />

P r i n t О . П ри этом объ<strong>е</strong>кт P r i n t D o c u m e n t созда<strong>е</strong>т объ<strong>е</strong>кт G r a p h i c s и, взяв <strong>е</strong>го<br />

в кач<strong>е</strong>ств<strong>е</strong> парам<strong>е</strong>тра, вызыва<strong>е</strong>т событи<strong>е</strong> P r i n t P a g e . Вс<strong>е</strong>, что обработчик события<br />

рису<strong>е</strong>т на объ<strong>е</strong>кт<strong>е</strong> G r a p h i c s , п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>тся на принт<strong>е</strong>р.<br />

private void buttonl_Click(object sender, EventArgs e) {<br />

}<br />

PrintDocument document = new P r i n t D o c u m e n t ();<br />

d o c u m e n t .PrintPage += new PrintPageEventHandler(document_PrintPage);<br />

d o c u m e n t .P r i n t ();<br />

624 глава 13


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

Окно пр<strong>е</strong>дварит<strong>е</strong>льного просмотра и окно диалога Print<br />

Добавл<strong>е</strong>ни<strong>е</strong> окна пр<strong>е</strong>дварит<strong>е</strong>льного просмотра или окна диалога Print напомина<strong>е</strong>т<br />

проц<strong>е</strong>дуру добавл<strong>е</strong>ния окон диалога O pen и Save. Вам нужно создать<br />

объ<strong>е</strong>кт P r i n t D i a l o g или P r i n t P r e v i e w D i a l o g , присвоить <strong>е</strong>го свойству<br />

D o c u m e n t ваш объ<strong>е</strong>кт D o c u m e n t и вызвать м<strong>е</strong>тод S h o w (). Докум<strong>е</strong>нт на п<strong>е</strong>чать<br />

отправит окно диалога, вам н<strong>е</strong> потр<strong>е</strong>бу<strong>е</strong>тся вызывать м<strong>е</strong>тод P r i n t ().<br />

Добавим <strong>е</strong>го к кнопк<strong>е</strong>, созданной вами на шаг<strong>е</strong> 1;<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

^ P r in t D o c u m e n t d o c u m e n t = n e w P r i n t D o c u m e n t ( ) ;<br />

^ d o c u m e n t . P r i n t P a g e += n e w P r i n t P a g e E v e n t H a n d l e r ( d o c u m e n t _ P r i n t P a g e ) ;<br />

P r i n t P r e v i e w D i a l o g p r e v i e w = n e w P r i n t P r e v i e w D i a l o g ( ) ;<br />

p r e v i e w . D o c u m e n t = d o c u m e n t;<br />

p r e v i e w . S h o w D i a l o g ( t h i s ) ;<br />

При наличии объ<strong>е</strong>кта<br />

P rintD ocum ent и соотв<strong>е</strong>.тст6уюш,<strong>е</strong>го<br />

обработчика событии<br />

для вызова окна пр<strong>е</strong>дварит<strong>е</strong>льного<br />

просмотра<br />

достаточно<br />

создать объ<strong>е</strong>кт<br />

PrintPreviewDialog.<br />

v o i d d o c u m e n t P r i n t P a g e ( o b j e c t s e n d e r ,<br />

~ P r in t P a g e E v e n t A r g s e ) {<br />

D r a w B e e ( <strong>е</strong> . G r a p h i c s , n e w R e c t a n g l e (О, О, 300, 300)<br />

^ Мы воспользу<strong>е</strong>мся уж<strong>е</strong> написанным<br />

м<strong>е</strong>тодом DrawBeeQ.<br />

П<strong>е</strong>чать многостраничного докум<strong>е</strong>нта<br />

Чтобы расп<strong>е</strong>чатать н<strong>е</strong>сколько страниц, нужно присвоить<br />

свойству e . H a s M o r e P a g e s обработчика событий<br />

P r i n t P a g e знач<strong>е</strong>ни<strong>е</strong> true. В р<strong>е</strong>зультат<strong>е</strong> объ<strong>е</strong>кт D o c u m e n t<br />

узна<strong>е</strong>т о дополнит<strong>е</strong>льных страницах. Обработчик событий<br />

буд<strong>е</strong>т вызываться снова и снова, до т<strong>е</strong>х пор пока он присваива<strong>е</strong>т<br />

свойству <strong>е</strong> .H a s M o r e P a g e s знач<strong>е</strong>ни<strong>е</strong> true. Отр<strong>е</strong>дактиру<strong>е</strong>м<br />

<strong>е</strong>го таким образом, чтобы расп<strong>е</strong>чатать дв<strong>е</strong> страницы:<br />

b o o l f i r s t P a g e = t r u e ;<br />

v o i d d o c u m e n t _ P r i n t P a g e ( o b j e c t s e n d e r , P r in t P a g e E v e n t A r g s e ) {<br />

©<br />

D r a w B e e ( e . G r a p h i c s , n e w R e c t a n g l e ( 0 , 0 , 300, 30 0));<br />

u s i n g ( F o n t f o n t = n e w F o n t ( " A r i a l " , 3 6 , F o n t S t y l e . B o l d ) ) {<br />

i f ( f i r s t P a g e ) {<br />

e . G r a p h i c s . D r a w s t r i n g ( " П <strong>е</strong> р в а я с т р а н и ц а " . F o n t , B r u s h e s . B l a c k , 0 , 0 ) ;<br />

e .H a sM o r e P a g e s = t r u e ; присвоить свойству e.HasMorePages знач<strong>е</strong>ни<strong>е</strong> true.<br />

f i r s t P a g e = f a l s e ;<br />

D ocum ent снова вызов<strong>е</strong>т обработчик событий<br />

} e l s e { и отправит на п<strong>е</strong>чать сл<strong>е</strong>дующую страницу.<br />

<strong>е</strong> . G r a p h i c s . D r a w s t r i n g ( " В т о р а я с т р а н и ц а " . F o n t , B r u s h e s . B l a c k , О, 0 ) ;<br />

f i r s t P a g e = t r u e ;<br />

Запчстит<strong>е</strong> программу и уб<strong>е</strong>дит<strong>е</strong>сь.<br />

, ^ чило в окн<strong>е</strong> пр<strong>е</strong>дварит<strong>е</strong>льного<br />

J ^ ■ просмотра появляются дв<strong>е</strong> страницы.<br />

дальш<strong>е</strong> > 625


вывод мира<br />

^ажн<strong>е</strong>ни<strong>е</strong><br />

Напишит<strong>е</strong> код для кнопки Print, которая вызыва<strong>е</strong>т окно пр<strong>е</strong>дварит<strong>е</strong>льного просмотра со<br />

статистикой пч<strong>е</strong>л и изображ<strong>е</strong>ниями улья и поля.<br />

Пусть кнопка вызыва<strong>е</strong>т окно пр<strong>е</strong>дварит<strong>е</strong>льного просмотра<br />

Добавьт<strong>е</strong> к событию Click кнопки обработчик, пр<strong>е</strong>рывающий работу симулятора, он<br />

буд<strong>е</strong>т вызывать окно пр<strong>е</strong>дварит<strong>е</strong>льного просмотра и посл<strong>е</strong> <strong>е</strong>го закрытия снова запускать<br />

симулятор.<br />

<strong>е</strong> Создайт<strong>е</strong> оброботчик события P r i n t P a g e<br />

Он долж<strong>е</strong>н создавать показанно<strong>е</strong> на сл<strong>е</strong>дующ<strong>е</strong>й страниц<strong>е</strong> окно:<br />

p r i v a t e v o i d d o c u m e n t _ P r i n t P a g e ( o b j e c t s e n d e r , P r in t P a g e E v e n t A r g s e ) f<br />

G r a p h ic s g = e . G r a p h i c s ;<br />

S iz e s t r i n g S i z e ;<br />

u s i n g ( F o n t a r i a l 2 4 b o l d = n e w F o n t ( " A r i a l "<br />

Овал С т<strong>е</strong>кстом s t r i n g S i z e = S i z e . C e i l i n g (<br />

5ыл создан при g . M e a s u r e S t r i n g ( " В <strong>е</strong> <strong>е</strong> s i m u l a t o r " ,<br />

noMOUiU м<strong>е</strong>тода / g - F i l l E l l i p s e ( B r u s h e s . G r a y ,<br />

, 24, FontStyle.Bold))<br />

arial24bold));<br />

{<br />

M e a s u re S trin g Q j/ n e w R e c t a n g le ( e . M a r g in B o u n d s . X + 2 , e.MarginBounds.Y + 2,<br />

возвращающ<strong>е</strong>го s t r i n g S i z e . w i d t h + 3 0 , s t r i n g S i z e . H e i g h t + 30 ));<br />

знач<strong>е</strong>ни<strong>е</strong> Size, mo g . F i l l E l l i p s e ( B r u s h e s . B l a c k ,<br />

<strong>е</strong>сть разм<strong>е</strong>р cm po- n e w R e c t a n g l e ( e . M a r g i n B o u n d s . X , e . M a r g in B o u n d s . Y ,<br />

Ku, о в а л и т <strong>е</strong>кст s t r i n g S i z e . w i d t h + 3 0 , s t r i n g S i z e . H e i g h t + 3 0 ) ) ;'<br />

были наридованы g . D r a w s t r i n g (" В <strong>е</strong> <strong>е</strong> S i m u l a t o r " , a r i a l 2 4 b o l d ,<br />

два раза для созда- B r u s h e s . G r a y , e . M a r g in B o u n d s . X + 1 7 , e . M a r g in B o u n d s Y + 1 7 ) •<br />

НКЯ э ф ф <strong>е</strong> к т а т <strong>е</strong> н и . g . D r a w S t r i n g (" B e e S i m u l a t o r " , a r i a l 2 4 b o l d ,<br />

^ B r u s h e s . W h i t e , e . M a r g in B o u n d s . X + 1 5 , e . M a r g in B o u n d s . Y + 1 5 ) ;<br />

f i n t t a b l e X = e . M a r g in B o u n d s . X + ( i n t ) s t r i n g S i z e . W i d t h + 5 0 ;<br />

Проц<strong>е</strong>дура ) t a b l e W i d t h = e . M a r g in B o u n d s . X + e .M a r g in B o u n d s . W i d t h - t a b l e X - 2 0 -<br />

постро<strong>е</strong>ния Л f i r s t c o l u m n x = t a b l e X + 2 ;<br />

таблицы.<br />

i n t s e c o n d C o lu m n X = t a b l e X + ( t a b l e W i d t h / 2)<br />

_ i n t t a b l e Y = e . M a r g in B o u n d s . Y ;<br />

+ 5 ;<br />

/ / В ам н у ж н о н а п и с а т ь о с т а л ь н у ю ч а с т ь м <strong>е</strong> т о д а , р а с п <strong>е</strong> ч а т ы в а ю щ <strong>е</strong> г о о к н о<br />

О Используйт<strong>е</strong> м<strong>е</strong>тод P rin tT a Ы e R o w ()<br />

Этот м<strong>е</strong>тод пригодится для создания таблицы со статистикой в в<strong>е</strong>рхн<strong>е</strong>й части окна.<br />

626<br />

p r i v a t e i n t P r i n t T a b l e R o w ( G r a p h i c s p r i n t G r a p h i c s , i n t t a b l e X ,<br />

i n t t a b l e W i d t h , i n t f i r s t C o l u m n X , i n t s e c o n d C o lu m n X ,<br />

i n t t a b l e Y , s t r i n g f i r s t C o l u m n , s t r i n g s e c o n d C o lu m n )<br />

F o n t a r i a l l 2 = n e w F o n t ( " A r i a l " , 12);<br />

S iz e s t r i n g S i z e = S i z e . C e i l i n g ( p r i n t G r a p h i c s . M e a s u r e S t r i n g ( f i r s t C o l u m n , a r i a l l 2 ) )<br />

tH D lc Y += 2;<br />

p r i n t G r a p h i c s . D r a w S t r i n g ( f i r s t C o l u m n , a r i a l l 2 , B r u s h e s . B l a c k ,<br />

f i r s t c o l u m n x , t a b l e Y ) ;<br />

p r i n t G r a p h i c s . D r a w S t r i n g ( s e c o n d C o l u m n , a r i a l l 2 , B r u s h e s . B l a c k ,<br />

s e c o n d C o lu m n X , t a b l e Y ) ;<br />

t a b l e Y += ( i n t ) s t r i n g S i z e . H e i g h t + 2 ;<br />

p r i n t G r a p h i c s . D r a w L i n e ( P e n s . B l a c k , t a b l e X , t a b l e Y , t a b l e X + t a b l e W i d t h , t a b l e Y ) -<br />

a r i a l l 2 . D is p o s e 0 ; ^ / / /<br />

r e t u r n t a b l e Y ; V При каждом вызов<strong>е</strong> м<strong>е</strong>тод PrintTableRowQ добавля<strong>е</strong>т<br />

}<br />

высоту расп<strong>е</strong>чапланной строки в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную tableY<br />

и возвраща<strong>е</strong>т ново<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>,<br />

глава 13<br />

{


эл<strong>е</strong>м<strong>е</strong>нты управл<strong>е</strong>ни<strong>е</strong> и графич<strong>е</strong>ски<strong>е</strong> фрагм<strong>е</strong>нты<br />

В ним ат<strong>е</strong>льно прочитайт<strong>е</strong> прим <strong>е</strong>чания, которы ми мы снабдили этот скринш от!<br />

•І? Print preview<br />

# Р - | И Ш В Ш В и Close: Page і 1<br />

Для п<strong>е</strong>чати таблицы используйт<strong>е</strong><br />

м<strong>е</strong>тод PrintTableRowQ.<br />

I<br />

, Информация о л<strong>е</strong>вом пол<strong>е</strong><br />

хранится в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

e.MarginBounds. Эллипс начина<strong>е</strong>т<br />

ся в точк<strong>е</strong> e.MarginBounds.X + 2.<br />

.------ -а<br />

Воспользуйт<strong>е</strong>сь визуализатором<br />

для отображ<strong>е</strong>ния формы<br />

Hive. Нарисуйт<strong>е</strong> вокруг<br />

ч<strong>е</strong>рную рамку с шириной Z.<br />

Используйт<strong>е</strong> свойство Width n.<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной e.MarginBounds.<br />

чтобы получить окно в половину<br />

ширины страницы.<br />

Bees 6<br />

Flowers 10<br />

Honey in Hive 0.2Ш<br />

Nectar in Flowers 2S.300<br />

Frames Run 286<br />

Frame Rate<br />

16 (62.5ms)<br />

сд<strong>е</strong>лайт<strong>е</strong> то ж<strong>е</strong> само<strong>е</strong><br />

для формы Field: ,<br />

<strong>е</strong><strong>е</strong> ширину сд<strong>е</strong>лайт!<br />

равной ширин<strong>е</strong> cmpti ^<br />

НиЦЫ с ПОМОШрУО ПС-‘ч ' ч<br />

X ы Y парам<strong>е</strong>тра<br />

e.MarginBounds. Постарайт<strong>е</strong>сь<br />

npudai V-<br />

илд нужны<strong>е</strong> пропорции. 1-%<br />

I<br />

Опр<strong>е</strong>д<strong>е</strong>лив высоту изображ<strong>е</strong>ния, выровняйт<strong>е</strong><br />

<strong>е</strong>го относит<strong>е</strong>льно нижн<strong>е</strong>й части страницы.<br />

’4<br />

Подсказка: Чтобы вычислить высоту каждой формы в окн<strong>е</strong> пр<strong>е</strong>дварит<strong>е</strong>льного просмотра, у м ­<br />

ножьт<strong>е</strong> соотнош<strong>е</strong>ни<strong>е</strong> высоты и ширины на итоговую ширину формы. Координата в<strong>е</strong>рхн<strong>е</strong>й части<br />

формы Field рассчитыва<strong>е</strong>тся по формул<strong>е</strong>: (e.MarginBounds.Y + e.MarginBounds.Height - fieldHeight).<br />

дальш<strong>е</strong> > 627


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> упражн<strong>е</strong>ния<br />

ражн<strong>е</strong>нк<strong>е</strong><br />

р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот код кнопки P r i n t , щ<strong>е</strong>лчок на которой вызыва<strong>е</strong>т окно пр<strong>е</strong>дварит<strong>е</strong>льного просмотра<br />

со статистикой и формами Hive и Field.<br />

o " Z 2 T e Z l t o p L T ^ -<br />

u s i n g S y s t e m . D r a w i n g . P r i n t i n g ; /<br />

p r i v a t e v o i d d o c u m e n t _ P r i n t P a g e ( o b j e c t s e n d e r , P r in t P a g e E v e n t A r g s e ) {<br />

G r a p h ic s g = e . G r a p h i c s ;<br />

S iz e s t r i n g S i z e ;<br />

u s i n g ( F o n t a r i a l 2 4 b o l d = n e w F o n t ( " A r i a l<br />

s t r i n g S i z e = S i z e . C e i l i n g (<br />

g . M e a s u r e S t r i n g ( "B e e S i m u l a t o r "<br />

g . F i l l E l l i p s e ( B r u s h e s . G r a y ,<br />

}<br />

, 2 4 , F o n t S t y l e . B o l d ) ) {<br />

a r i a l 2 4 b o l d ) ) ;<br />

n e w R e c t a n g l e ( e . M a r g i n B o u n d s . X + 2 , e . M a r g in B o u n d s . Y + 2 ,<br />

s t r i n g S i z e . W i d t h + 3 0 , s t r i n g S i z e . H e i g h t + 30 ));<br />

g . F i l l E l l i p s e ( B r u s h e s . B l a c k ,<br />

n e w R e c t a n g l e ( e . M a r g i n B o u n d s . X , e . M a r g in B o u n d s . Y ,<br />

s t r i n g S i z e . W i d t h + 3 0 , s t r i n g S i z e . H e i g h t + 3 0 ));<br />

g . D r a w S t r i n g ( " B e e S i m u l a t o r " , a r i a l 2 4 b o l d .<br />

B r u s h e s . G r a y , e . M a r g in B o u n d s . X + 1 7 , e . M a r g in B o u n d s . Y + 1 7 ) ;<br />

g . D r a w S t r i n g ( " B e e S i m u l a t o r " , a r i a l 2 4 b o l d .<br />

B r u s h e s . W h i t e , e . M a r g in B o u n d s . X + 1 5 , e . M a r g in B o u n d s . Y + 1 5 ) ;<br />

Э т у часть<br />

кода М 1?1 бяМ<br />

ы ж <strong>е</strong> давали.<br />

Зд<strong>е</strong>сь рисц<strong>е</strong>


Д л я рисования рамки вокруг снимков<br />

экрана вам потр<strong>е</strong>бу<strong>е</strong>мся ч<strong>е</strong>рная<br />

ручка с толш,иной линии 2- пикс<strong>е</strong>ла.<br />

f u s i n g (P e n b l a c k P e n = n e w P e n ( B r u s h e s . B l a c k , 2 ) )<br />

/ ^ ^ u s i n g ( B it m a p h i v e B i t m a p = n e w B it m a p ( h iv e F o r m . C l i e n t S i z e . W i d t h ,<br />

/ / h i v e F o r m . C l i e n t S i z e . H e i g h t ) )<br />

I \ u s i n g ( B it m a p f i e l d B i t m a p = n e w B i t m a p ( f i e l d F o r m . C l i e n t S i z e . W i d t h ,<br />

Так как<br />

f i e l d F o r m . C l i e n t S i z e . H e i g h t ] _<br />

объ<strong>е</strong>кты<br />

Pen {<br />

u s i n g ( G r a p h ic s h i v e G r a p h i c s = G r a p h i c s . F r o m lm a g e ( h i v e B it m a p ) )<br />

и Bitmap<br />

посл<strong>е</strong> {<br />

r e n d e r e r . P a i n t H i v e ( h i v e G r a p h i c s ) ;<br />

прим<strong>е</strong>н<strong>е</strong>ния<br />

нужно }<br />

буд<strong>е</strong>т<br />

удалить,<br />

мы пом<strong>е</strong>стили<br />

их в блок<br />

using.<br />

i n t h i v e W i d t h = e . M a r g in B o u n d s . W id t h / 2<br />

f l o a t r a t i o = ( f l o a t ) h i v e B i t m a p . H e i g h t / ( f l o a t ) h i v e B i t m a p . W i d t h ;<br />

i n t h i v e H e i g h t = ( i n t ) ( h i v e W i d t h * r a t i o ) ;<br />

i n t h i v e X = e . M a r g in B o u n d s . X + ( e . M a r g in B o u n d s . W id t h - h i v e W i d t h )<br />

i n t h i v e Y = e . M a r g i n B o u n d s . H e i g h t / 3 ;<br />

g . D r a w lm a g e ( h iv e B it m a p , h i v e X , h i v e Y , h i v e W i d t h , h i v e H e i g h t ) ;<br />

g . D r a w R e c t a n g le ( b la c k P e n , h i v e X , h i v e Y , h i v e W i d t h , h i v e H e i g h t ) ;<br />

Разм<strong>е</strong>р объ<strong>е</strong>ктов<br />

Bitmaps долж<strong>е</strong>н<br />

совпадать с од<br />

^ластью формы,<br />

i ^р<strong>е</strong>ЭнйЗнач<strong>е</strong>ннои<br />

Зля рисования,


мини-л0боратория<br />

А <strong>е</strong>щ<strong>е</strong> мо)кно было бы...<br />

Вы построили н<strong>е</strong>большой, но симпатичный симулятор, так зач<strong>е</strong>м останавливаться? Вот<br />

ид<strong>е</strong>и, которы<strong>е</strong> при ж<strong>е</strong>лании вы мож<strong>е</strong>т<strong>е</strong> р<strong>е</strong>ализовать самостоят<strong>е</strong>льно.<br />

Добавьт<strong>е</strong> пан<strong>е</strong>ль управл<strong>е</strong>ния<br />

Пр<strong>е</strong>вратит<strong>е</strong> константы классов World и Hive в свойства.<br />

Зат<strong>е</strong>м добавьт<strong>е</strong> новую форму с пан<strong>е</strong>лью управл<strong>е</strong>ния<br />

и ползунками.<br />

Создайт<strong>е</strong> врагов<br />

Пусть ул<strong>е</strong>й атакуют враги. Ч<strong>е</strong>м больш<strong>е</strong> цв<strong>е</strong>тов, т<strong>е</strong>м<br />

больш<strong>е</strong> должно быть врагов. Вам потр<strong>е</strong>буются Sting<br />

Patrol для борьбы с врагами и Hive Maintenance для<br />

восстановл<strong>е</strong>ния улья. И вс<strong>е</strong> эти пч<strong>е</strong>лы потр<strong>е</strong>бляют м<strong>е</strong>д.<br />

Усов<strong>е</strong>рш<strong>е</strong>нствуйт<strong>е</strong> ул<strong>е</strong>й<br />

При наличии достаточного колич<strong>е</strong>ства м<strong>е</strong>да ул<strong>е</strong>й раст<strong>е</strong>т.<br />

Ч<strong>е</strong>м больш<strong>е</strong> ул<strong>е</strong>й, т<strong>е</strong>м больш<strong>е</strong> в н<strong>е</strong>м пч<strong>е</strong>л. Но при этом<br />

раст<strong>е</strong>т потр<strong>е</strong>бл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>да и учащаются атаки врагов. При<br />

значит<strong>е</strong>льном ущ<strong>е</strong>рб<strong>е</strong> ул<strong>е</strong>й снова долж<strong>е</strong>н стать м<strong>е</strong>ньш<strong>е</strong>.<br />

Пусть пч<strong>е</strong>линая матка откладыва<strong>е</strong>т яйца<br />

Для заботы о яйцах вам потр<strong>е</strong>буются рабочи<strong>е</strong> пч<strong>е</strong>лы Baby<br />

В<strong>е</strong><strong>е</strong> Саг<strong>е</strong>. Ч<strong>е</strong>м больш<strong>е</strong> м<strong>е</strong>да в уль<strong>е</strong>, т<strong>е</strong>м больш<strong>е</strong> яиц откладыва<strong>е</strong>т<br />

матка. А значит, тр<strong>е</strong>буются дополнит<strong>е</strong>льны<strong>е</strong><br />

пч<strong>е</strong>лы-няньки, которы<strong>е</strong> <strong>е</strong>дят м<strong>е</strong>д.<br />

Добавьт<strong>е</strong> анимацию<br />

Анимируйт<strong>е</strong> фоново<strong>е</strong> изображ<strong>е</strong>ни<strong>е</strong> формы Hive, заставив<br />

солнц<strong>е</strong> двигаться по н<strong>е</strong>бу. Пусть ночью становится т<strong>е</strong>мно<br />

и появляются луна и зв<strong>е</strong>зды. Добавьт<strong>е</strong> п<strong>е</strong>рсп<strong>е</strong>ктиву:<br />

пусть пч<strong>е</strong>лы, сидящи<strong>е</strong> на ближних цв<strong>е</strong>тах, им<strong>е</strong>ют больший<br />

разм<strong>е</strong>р, ч<strong>е</strong>м пч<strong>е</strong>лы, располож<strong>е</strong>нны<strong>е</strong> дальш<strong>е</strong>.<br />

Используйт<strong>е</strong> сво<strong>е</strong> воображ<strong>е</strong>ни<strong>е</strong>!<br />

Придумайт<strong>е</strong> собств<strong>е</strong>нны<strong>е</strong> способы сд<strong>е</strong>лать симулятор инт<strong>е</strong>рактивным<br />

и бол<strong>е</strong><strong>е</strong> инт<strong>е</strong>р<strong>е</strong>сным.<br />

Хороший<br />

симулятор<br />

позволя<strong>е</strong>т<br />

пользоват<strong>е</strong> -<br />

ли> выбирать,<br />

каким способом<br />

пойд<strong>е</strong>т<br />

развити<strong>е</strong><br />

сист<strong>е</strong>мы.<br />

Вы создали удачную в<strong>е</strong>рсию симулятора? Покажит<strong>е</strong><br />

<strong>е</strong><strong>е</strong> нам, загрузит<strong>е</strong> код на форму Head First <strong>C#</strong> www.<br />

headfirstlabs.com/books/hfcsharp /<br />

630 «rraea 13


Head First<br />

$2.98<br />

глава<br />

14


O b je c tv ille<br />

Home of


пр<strong>е</strong>ступл<strong>е</strong>ни<strong>е</strong> повт орилось<br />

V<br />

^Возьмі Возьми 8 руку кйрандаш-<br />

Вот код, описы ваю щ ий б итву м <strong>е</strong>ж ду В <strong>е</strong>ликол<strong>е</strong>пны м и Ж ул и ком (а такж <strong>е</strong><br />

с а рм и<strong>е</strong>й клонов). Н арисуйт<strong>е</strong>, что происходит в куч<strong>е</strong> при создании<br />

экз<strong>е</strong> м пляров кл асса F i n a l B a t t l e .<br />

c l a s s F i n a l B a t t l e {<br />

p u b l i c C l o n e F a c t o r y F a c t o r y = new C l o n e F a c t o r y ( ) ;<br />

p u b l i c L i s t < C l o n e > C lo n e s = ne w L i s t < C l o n e > 0 { .<br />

p u b l i c S w in d le r s E s c a p e P l a n e e s c a p e P la n e ;<br />

]<br />

p u b l i c F i n a l B a t t l e () {<br />

V i l l a i n s w i n d l e r = new V i l l a i n ( t h i s ) ;<br />

u s i n g ( S u p e r h e r o c a p t a in A m a z in g = ne w S u p e r h e r o O ) {<br />

F a c t o r y . P e o p l e l n F a c t o r y . A d d ( c a p t a i n A m a z i n g ) ;<br />

F a c t o r y . P e o p l e l n F a c t o r y . A d d ( s w i n d l e r )<br />

c a p t a i n A m a z i n g . T h i n k (" Я у н и ч т о ж у с с ы л к и н а к л о н ы ,<br />

о д н у з а о д н о й " ) ;<br />

c a p t a i n A m a z i n g . I d e n t i f y T h e C l o n e s ( C l o n e s ) ;<br />

c a p t a in A m a z in g . R e m o v e T h e C lo n e s ( C lo n e s ) ;<br />

s w i n d l e r . T h i n k ( " Ч <strong>е</strong> р <strong>е</strong> з н <strong>е</strong> с к о л ь к о м и н у т м о я а р м и я с т а н <strong>е</strong> т м у с о р о м " ) ;<br />

s w i n d l e r . T h i n k ( " ( б у д <strong>е</strong> т с о б р а н а<br />

e<br />

e s c a p e P la n e = ne w S w i n d l e r s E s c a p e P l a n e ( s w i n d l e r ) ;<br />

s w i n d l e r . T r a p C a p t a i n A m a z i n g ( F a c t o r y ) ;<br />

M e s s a g e B o x .S h o w (" Ж у л и к у б <strong>е</strong> ж а л " ) ;<br />

[ S e r i a l i z a b l e ]<br />

c l a s s S u p e r h e r o : I D i s p o s a b l e {<br />

Как 5ydem выгляд<strong>е</strong>ть куча посл<strong>е</strong><br />

зітуска конструктора FinalBattle<br />

(финальная 5итваУ<br />

p r i v a t e L i s t < C l o n e > c lo n e s T o R e m o v e = ne w L i s t < C l o n e > ( ) ;<br />

p u b l i c v o i d I d e n t i f y T h e C l o n e s ( L i s t < C l o n e > c lo n e s ) {<br />

f o r e a c h ( C lo n e c l o n e i n c lo n e s )<br />

C lo n e s T o R e m o v e . A d d ( c lo n e ) ;<br />

}<br />

p u b l i c v o i d R e m o v e T h e C lo n e s ( L is t < C lo n e > c l o n e s ) {<br />

f o r e a c h ( C lo n e c l o n e i n c lo n e s T o R e m o v e )<br />

c l o n e s . R e m o v e ( c l o n e ) ;<br />

, ■■■ ^2>&cb долж<strong>е</strong>н 5ыть дополнит<strong>е</strong>льный код (вклю-<br />

^ т ю щ Т м <strong>е</strong> т о д PisposeQ. р<strong>е</strong>ализующии ин-<br />

, ■■■ \ т<strong>е</strong>р%<strong>е</strong>йс IDisposable). Но он скрыт, так как н<strong>е</strong><br />

^ им<strong>е</strong><strong>е</strong>т знач<strong>е</strong>ния Эля р<strong>е</strong>ш<strong>е</strong>ния задачи.<br />

c l a s s V i l l a i n {<br />

p r i v a t e F i n a l B a t t l e f i n a l B a t t l e ;<br />

p u b l i c V i l l a i n ( F i n a l B a t t l e f i n a l B a t t l e ) {<br />

t h i s . f i n a l B a t t l e = f i n a l B a t t l e ;<br />

}<br />

p u b l i c v o i d T r a p C a p t a in A m a z i n g ( C lo n e F a c t o r y f a c t o r y ) {<br />

f a c t o r y . S e l f D e s t r u c t . T i c k += new E v e n t H a n d l e r ( S e l f D e s t r u c t _ T i c k ) ;<br />

f a c t o r y . S e l f D e s t r u c t . I n t e r v a l = 600; ~<br />

f a c t o r y . S e l f D e s t r u c t . ^ t a r t ( ) ;<br />

}<br />

p r i v a t e v o i d S e l f D e s t r u c t _ T i c k ( o b j e c t s e n d e r , E v e n t A r g s e ) {<br />

f i n a l B a t t l e . F a c t o r y = n u l l ;<br />

}<br />

Можно пр<strong>е</strong>дположить, что<br />

клоны были созданы при<br />

помощи инициализаторй<br />

колл<strong>е</strong>кции. I<br />

Р'^сунок<br />

1<br />

Нарисуйт<strong>е</strong>, что<br />

происходит о м о ­<br />

м <strong>е</strong> н т создания эк­<br />

з<strong>е</strong>мпляра ооь<strong>е</strong>кта<br />

SwindlersEscapePlane<br />

(План поб<strong>е</strong>га Жулика).<br />

634 глава t4


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

c l a s s S w in d le r s E s c a p e P l a n e {<br />

p u b l i c V i l l a i n P i l o t s S e a t ;<br />

p u b l i c S w i n d l e r s E s c a p e P l a n e ( V i l l a i n e s c a p e e )<br />

P i l o t s S e a t = e s c a p e e ;<br />

}<br />

}<br />

c l a s s C l o n e F a c t o r y {<br />

p u b l i c T im e r S e l f D e s t r u c t = new T im e r();<br />

p u b l i c L i s t < o b j e c t > P e o p l e l n F a g t o r y = new L i s t < o b j e c t > ()<br />

Класс Clone такж<strong>е</strong><br />

н<strong>е</strong> показыва<strong>е</strong>тся<br />

как н <strong>е</strong> с у щ <strong>е</strong> с т б <strong>е</strong> н<br />

и ш для р<strong>е</strong>м<strong>е</strong>ныя<br />

данной задачи-<br />

Н<strong>е</strong> забывайт<strong>е</strong> про<br />

м<strong>е</strong>тки объ<strong>е</strong>ктов,<br />

указывающих на<br />

ссылочны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

}<br />

Мы начали отв<strong>е</strong>чать на п<strong>е</strong>рвый<br />

вопрос. Линии д<strong>е</strong>монстрируют<br />

архит<strong>е</strong>ктуру. Скаж<strong>е</strong>м^ мы пров<strong>е</strong>ли<br />

линию м<strong>е</strong>жду фабрикой клонов<br />

и объ<strong>е</strong>ктом Villain, так как ф а­<br />

брика ссыла<strong>е</strong>тся на этот объ<strong>е</strong>кт<br />

(ч<strong>е</strong>р<strong>е</strong>з сво<strong>е</strong> пол<strong>е</strong> PeoplelnFactory).<br />

Зд<strong>е</strong>сь нмисовано<br />

н<strong>е</strong> ос<strong>е</strong>. Остальны<strong>е</strong><br />

объ<strong>е</strong>кты вставьт<strong>е</strong><br />

самостоят<strong>е</strong>льно.<br />

<strong>е</strong><br />

Нарисуйт<strong>е</strong>, что<br />

'происходит в куч<strong>е</strong><br />

о остальных двцх<br />

точках. ^<br />

В каком м <strong>е</strong>ст<strong>е</strong> кода ум и ра<strong>е</strong>т капитан В <strong>е</strong>ликол<strong>е</strong>пны й?<br />

О ставьт<strong>е</strong> соотв<strong>е</strong>тствую щ и й ком м <strong>е</strong>нтарий на д и аграм м <strong>е</strong>.<br />

дальш<strong>е</strong> ► 635


что бы могли означать эти цифры<br />

Ьзьми в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот как вы глядит куча, по м <strong>е</strong>р<strong>е</strong> вы полн<strong>е</strong>ния програм м ы<br />

F i n a l B a t t l e .<br />

указыва<strong>е</strong>т на объ<strong>е</strong>кт<br />

Superhero, а ссылка<br />

swmdfer ~ на объ<strong>е</strong>кт Villain<br />

>^яш<strong>е</strong>и фабрики клонов<br />

o s l S r ““ “<br />

Э т о объ<strong>е</strong>кт ,<br />

который оы<br />

Эолжнь»! Ь ы т<br />

Эобабиил» к Эйд<br />

граМЛЛ£-<br />

О<br />

Пока сущ<strong>е</strong>ству<strong>е</strong>т ссылка<br />

escapePlane на oovckvsa<br />

sv-j'mditr, э т о т oovcKm н<strong>е</strong><br />

буд<strong>е</strong>т отправл<strong>е</strong>н в мусор-<br />

ь Г -<br />

При появл<strong>е</strong>нии события selfDestruct<br />

ссылка factory начина<strong>е</strong>т указывать на<br />

знач<strong>е</strong>ни<strong>е</strong> nullj а значит^ отправля<strong>е</strong>тся<br />

в мусор и исч<strong>е</strong>за<strong>е</strong>т с наш<strong>е</strong>й диаграммы.<br />

Т<strong>е</strong>п<strong>е</strong>рь ссылка<br />

escapePlane указыва<strong>е</strong>т<br />

на новый<br />

экз<strong>е</strong>мпляр объ<strong>е</strong>кта<br />

SwindlersEscapePlane<br />

а пол<strong>е</strong> PilotSeat ~ на<br />

объ<strong>е</strong>кт Villain.<br />

<strong>е</strong><br />

escape<br />

Plane<br />

^ J -<br />

Всл<strong>е</strong>д за ссылкой factory в мусор<br />

отправля<strong>е</strong>тся объ<strong>е</strong>кт CloneFactory,<br />

это приводит к исч<strong>е</strong>знов<strong>е</strong>нию<br />

объ<strong>е</strong>кта List... а это было посл<strong>е</strong>дним,<br />

что сохраняло наш объ<strong>е</strong>кт<br />

SuperHero. Он исч<strong>е</strong>зн<strong>е</strong>т при сл<strong>е</strong>дующ<strong>е</strong>м<br />

проход<strong>е</strong> сборщика мусора.<br />

Вот м ом <strong>е</strong>нт исч<strong>е</strong>знов<strong>е</strong>ния наш <strong>е</strong>го суп<strong>е</strong>рг<strong>е</strong>роя:<br />

void SelfPestruct_Tick(ohJect sender^ EventArgs e) {<br />

finalBattle.faciory = nciK;.................................................<br />

С сы л ка f i n a l B a t t l e F a c t o r y стала указы вать на null, и это*^<br />

прив<strong>е</strong>ло к исч<strong>е</strong>знов<strong>е</strong>нию посл<strong>е</strong>дн<strong>е</strong>й ссы лки на капитана!<br />

f i n a i B a t t i e .<br />

Так как экз<strong>е</strong>мпляр Superhero н<strong>е</strong><br />

им<strong>е</strong><strong>е</strong>т клонов, на которы<strong>е</strong> мог бы<br />

сослаться объ<strong>е</strong>кт factory, он пр<strong>е</strong>дназнача<strong>е</strong>тся<br />

для сборщика мусора.<br />

636 глава 14


это тво<strong>е</strong> посл<strong>е</strong>дн<strong>е</strong><strong>е</strong> слово?<br />

М <strong>е</strong>тод заб<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта<br />

Иногда нужно, чтобы н<strong>е</strong>ки<strong>е</strong> д<strong>е</strong>йствия произош ли до того,<br />

как объ<strong>е</strong>кт отправится в мусор, наприм<strong>е</strong>р вы свобожд<strong>е</strong>ни<strong>е</strong><br />

н<strong>е</strong>управля<strong>е</strong>мых р<strong>е</strong>сурсов.<br />

Так называ<strong>е</strong>мый м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта (finalizer) позволя<strong>е</strong>т<br />

написать код, который буд<strong>е</strong>т выполняться п<strong>е</strong>р<strong>е</strong>д<br />

уничтож<strong>е</strong>ни<strong>е</strong>м объ<strong>е</strong>кта. Его можно пр<strong>е</strong>дставить, как п<strong>е</strong>рсональный<br />

блок f i n a l l y : он вс<strong>е</strong>гда выполня<strong>е</strong>тся посл<strong>е</strong>дним.<br />

Вот прим<strong>е</strong>р такого м<strong>е</strong>тода для класса C lone:<br />

[ S e r i a l i z a b l e ]<br />

c l a s s C lo n e {<br />

s t r i n g L o c a t i o n ;<br />

i n t C lo n e lD ;<br />

Это конструктором<br />

заполня<strong>е</strong>т поля<br />

ClonelP и Location при<br />

каждом создании оОъ-^<br />

<strong>е</strong>кта Clone.<br />

Вам н<strong>е</strong> прид<strong>е</strong>тся писать м<strong>е</strong>тод зав<strong>е</strong>рш <strong>е</strong>­<br />

ния для объ<strong>е</strong>ктов, обладающих управля<strong>е</strong>мыми<br />

р<strong>е</strong>сурсам и. Вс<strong>е</strong>, с ч<strong>е</strong>м вы<br />

сталкивались в этой книг<strong>е</strong> было управля<strong>е</strong>мым<br />

— оно управлялось CLR. Но<br />

бывают случаи, когда программистам<br />

тр<strong>е</strong>бу<strong>е</strong>тся доступ к базовым р<strong>е</strong>сурсами<br />

W indow s, которы<strong>е</strong> н<strong>е</strong> являются частью<br />

■NET Framework. Скаж<strong>е</strong>м, код с атрибутом<br />

[ D l lI n ç ) o r t ] мож<strong>е</strong>т использовать<br />

н<strong>е</strong>управля<strong>е</strong>мы<strong>е</strong> р<strong>е</strong>сурсы . Если их<br />

вовр<strong>е</strong>мя н<strong>е</strong> удалить (наприм<strong>е</strong>р, соотв<strong>е</strong>тствующ<br />

им м<strong>е</strong>тодом), эти р<strong>е</strong>сурсы могут<br />

повлиять на стабильность сист<strong>е</strong>мы.<br />

И м<strong>е</strong>нно для такой ц<strong>е</strong>ли тр<strong>е</strong>бу<strong>е</strong>тся м<strong>е</strong>тод<br />

зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта.<br />

p u b l i c C lo n e ( i n t c l o n e l D , s t r i n g l o c a t i o n ) {<br />

t h i s . C l o n e l D = c l o n e l D ;<br />

t h i s . L o c a t i o n = l o c a t i o n ;<br />

}<br />

p u b l i c v o i d T e l l L o c a t i o n ( s t r i n g l o c a t i o n , i n t c l o n e l D ) {<br />

C o n s o l e . W r i t e L i n e ("Мой н ом <strong>е</strong>р { 0 } и " +<br />

"ты найд<strong>е</strong>ш ь м <strong>е</strong>н я т у т : { 1 } ClonelD, location)<br />

}<br />

p u b l i c v o i d W rea k H a v o c( ) {<br />

o n e О {<br />

T e l l L o c a t i o n ( t h i s . L o c a t i o n ,<br />

C o n s o l e .W r it e L in e ( " { 0 } h a s<br />

Знак ~ указыва<strong>е</strong>т, ч т о код в<br />

, этом блок<strong>е</strong> выполня<strong>е</strong>тся, когда<br />

объ<strong>е</strong>кт отправля<strong>е</strong>тся о мусор.<br />

t h i s . C l o n e l D ) ;<br />

b e e n d e s t r o y e d " C lo n e lD )<br />

Зто м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния<br />

объ<strong>е</strong>кта. Он<br />

отправля<strong>е</strong>т н<strong>е</strong>-<br />

Ю Г“ ^°общ<strong>е</strong>ни<strong>е</strong> с<br />

н<strong>е</strong>счастного клона.<br />

Но только посл<strong>е</strong><br />

объ<strong>е</strong>кт<br />

она<strong>е</strong>т пом<strong>е</strong>ч<strong>е</strong>н для<br />

с-оорки Мусора.<br />

М<strong>е</strong>тод зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта отлича<strong>е</strong>тся<br />

от конструктора т<strong>е</strong>м, что<br />

вм<strong>е</strong>сто модификатора доступа<br />

п<strong>е</strong>р<strong>е</strong>д им<strong>е</strong>н<strong>е</strong>м класса пом<strong>е</strong>ща<strong>е</strong>тся<br />

знак И .NET выполнит этот код<br />

в прямо п<strong>е</strong>р<strong>е</strong>д отправкой объ<strong>е</strong>кта<br />

в мусор.<br />

Этот м<strong>е</strong>тод н<strong>е</strong> им<strong>е</strong><strong>е</strong>т парам<strong>е</strong>тров,<br />

так как .NET должна уничтожить<br />

объ<strong>е</strong>кт.<br />

Рр у д ы п <strong>е</strong><br />

Часть кода в книг<strong>е</strong> пр<strong>е</strong>дназнач<strong>е</strong>на<br />

только для уч<strong>е</strong>бных ц<strong>е</strong>л<strong>е</strong>й.<br />

о а ц ь р о ж н ь ї і<br />

Пока вы только слышали, что объ<strong>е</strong>кт<br />

отправля<strong>е</strong>тся в мусор, как только исч<strong>е</strong>за<strong>е</strong>т ссылка на н<strong>е</strong>го.<br />

Мы готовы показать вам код, автоматич<strong>е</strong>ски запускающий<br />

сборку мусора при помощи м<strong>е</strong>тода GC. C o lle c t () и вызывающ<br />

ий M sssageBox в м<strong>е</strong>тод<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>ктов.<br />

Эти в<strong>е</strong>щи затрагивают «с<strong>е</strong>рдц<strong>е</strong>» CLR. Мы показыва<strong>е</strong>м их,<br />

чтобы объяснить принцип сборки мусора. Никогда н<strong>е</strong> используйт<strong>е</strong><br />

их в рабочих программах.<br />

638<br />

глава 14


637


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Когда запуска<strong>е</strong>т м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта<br />

М<strong>е</strong>тод зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта запуска<strong>е</strong>тся посл<strong>е</strong><br />

исч<strong>е</strong>знов<strong>е</strong>ния вс<strong>е</strong>х ссылок, но до отправки<br />

объ<strong>е</strong>кта в мусор. В<strong>е</strong>дь сборка мусора н<strong>е</strong><br />

вс<strong>е</strong>гда запуска<strong>е</strong>тся сразу посл<strong>е</strong> исч<strong>е</strong>знов<strong>е</strong>ния<br />

ссылок.<br />

Пр<strong>е</strong>дположим, у нас <strong>е</strong>сть объ<strong>е</strong>кт и ссылка<br />

на н<strong>е</strong>го. Запущ<strong>е</strong>нный .NET сборщик мусора<br />

пров<strong>е</strong>ря<strong>е</strong>т <strong>е</strong>го состояни<strong>е</strong>. Обнаружив ссылку,<br />

сборщик игнориру<strong>е</strong>т этот объ<strong>е</strong>кт, и он оста<strong>е</strong>тся<br />

в памяти.<br />

Зат<strong>е</strong>м посл<strong>е</strong>дний объ<strong>е</strong>кт, ссылавшийся на<br />

ваш объ<strong>е</strong>кт, удаля<strong>е</strong>тся. Доступ к н<strong>е</strong>му пропада<strong>е</strong>т.<br />

По сути объ<strong>е</strong>кт ум<strong>е</strong>р.<br />

Д р у г о й о б т г <strong>е</strong> к т<br />

С с ы л а <strong>е</strong> т с я на<br />

вам объ<strong>е</strong>кт-<br />

Ваш объ<strong>е</strong>кт вс<strong>е</strong><br />

<strong>е</strong>ш,& в куч<strong>е</strong>...<br />

Это ваш объ<strong>е</strong>кт<br />

в памяти. ■<br />

--■НО ссылок на н<strong>е</strong>го<br />

уж<strong>е</strong> н<strong>е</strong> осталось.<br />

Н о д<strong>е</strong>ло в том, что сборкой мусора управля<strong>е</strong>т<br />

.NET, а н<strong>е</strong> объ<strong>е</strong>кты. Поэтому до запуска проц<strong>е</strong>дуры<br />

сборки объ<strong>е</strong>кт жив<strong>е</strong>т в памяти. Его<br />

н<strong>е</strong>возможно использовать, но он <strong>е</strong>сть. И <strong>е</strong>го<br />

м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> начал<br />

свою работу.<br />

И вот .NET в оч<strong>е</strong>р<strong>е</strong>дной раз запуска<strong>е</strong>т сборщик<br />

мусора. Запуска<strong>е</strong>тся и м<strong>е</strong>тод зав<strong>е</strong>рш <strong>е</strong>ния<br />

объ<strong>е</strong>кта... возможно, ч<strong>е</strong>р<strong>е</strong>з н<strong>е</strong>сколько минут<br />

посл<strong>е</strong> исч<strong>е</strong>знов<strong>е</strong>ния посл<strong>е</strong>дн<strong>е</strong>й ссылки,<br />

и только посл<strong>е</strong> этого объ<strong>е</strong>кт окончат<strong>е</strong>льно<br />

исч<strong>е</strong>за<strong>е</strong>т.<br />

» к “<br />

/<br />

И д кои<strong>е</strong>ц л о я б л я <strong>е</strong> т -<br />

в к c l ones) {<br />

f o r e a c h (Clone c l o n e in c l o n e s T o R e m o v e )<br />

c l o n e s . R e m o v e ( c l o n e ) ;<br />

GC.Collect();<br />

Мы н<strong>е</strong> мож<strong>е</strong>м <strong>е</strong>щ<strong>е</strong> раз н<strong>е</strong> подч<strong>е</strong>ркнуть, н а-<br />

\ сколько плохой ид<strong>е</strong><strong>е</strong>й явля<strong>е</strong>тся вызов м <strong>е</strong>т ода<br />

' ac.CollectQ в с<strong>е</strong>рь<strong>е</strong>зных программах, так как вы<br />

мож <strong>е</strong>т<strong>е</strong> сбить настро<strong>е</strong>нную проц<strong>е</strong>дуру сборки<br />

мусора. Но для обуч<strong>е</strong>ния н<strong>е</strong>т нич<strong>е</strong>го лучш<strong>е</strong>,<br />

п оэт ом у мы создадим игровую npozpaMMyj<br />

в которой воспользу<strong>е</strong>мся этим м<strong>е</strong>тодом.<br />

дальш<strong>е</strong> > 639


собира<strong>е</strong>м мусор<br />

ЯВно<strong>е</strong> U н<strong>е</strong>явно<strong>е</strong> Высвобожд<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>сурсов<br />

М <strong>е</strong> т о д D i s p o s e о запуска<strong>е</strong>тся, когда объ<strong>е</strong>кт, с о з д а н н ы й п р и п о м о щ и<br />

оп<strong>е</strong>ратора using, получа<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> null. Е с л и оп<strong>е</strong>ратор u s i n g н<strong>е</strong><br />

прим<strong>е</strong>нялся, ссылка на знач<strong>е</strong>ни<strong>е</strong> null н<strong>е</strong> стан<strong>е</strong>т п р и ч и н о й вызова м <strong>е</strong> т о ­<br />

да D i s p o s e () — вам прид<strong>е</strong>тся в ы з ы в а т ь <strong>е</strong>го вручную. М <strong>е</strong> т о д з а в <strong>е</strong> р ш <strong>е</strong> ­<br />

н и я объ<strong>е</strong>кта работа<strong>е</strong>т со с б о р щ и к о м мусора. П о с м о т р и м на практик<strong>е</strong>,<br />

ч <strong>е</strong> м эти м <strong>е</strong> т о д ы отличаются друг от друга:<br />

Как вы уж<strong>е</strong> вид<strong>е</strong>ли, м <strong>е</strong>­<br />

тод DfsposeQ работа<strong>е</strong>м<br />

и д<strong>е</strong>з оп<strong>е</strong>ратора using. Его<br />

многократно<strong>е</strong> прим<strong>е</strong>н<strong>е</strong>ни<strong>е</strong><br />

н<strong>е</strong> им<strong>е</strong><strong>е</strong>т побочных эф ­<br />

ф<strong>е</strong>ктов.<br />

|п ] ^ а ж н <strong>е</strong> н и <strong>е</strong><br />

Создайт<strong>е</strong> класс C lo n e , р<strong>е</strong>ализую щ ий инт<strong>е</strong>рср<strong>е</strong>йс I D i s p o s a b l e<br />

Класс д о л ж <strong>е</strong> н и м <strong>е</strong> т ь автоматич<strong>е</strong>ско<strong>е</strong> свойство I d т и п а int, а такж<strong>е</strong><br />

конструктор, м <strong>е</strong> т о д D i s p o s e () и м <strong>е</strong> т о д з а в <strong>е</strong> р щ <strong>е</strong> н и я объ<strong>е</strong>кта:<br />

c l a s s C l o n e : I D i s p o s a b l e {<br />

p u b l i c int I d {<br />

p u b l i c C l o n e ( i n t Id)<br />

}<br />

t h i s . I d = Id;<br />

get; p r i v a t e set;<br />

{<br />

Так как класс р<strong>е</strong>ализу<strong>е</strong>т<br />

инт<strong>е</strong>рф<strong>е</strong>йс IDisposable, в н<strong>е</strong>м<br />

долж<strong>е</strong>н присут ст воват ь<br />

м<strong>е</strong>тод DisposeQ.<br />

Напомина<strong>е</strong>м:<br />

Вызов окна<br />

MessageBox<br />

в м<strong>е</strong>тод<strong>е</strong> зав<strong>е</strong>рил<strong>е</strong>ния<br />

объ<strong>е</strong>кта<br />

м о ж <strong>е</strong> т<br />

вн<strong>е</strong>сти пит а-<br />

ницу в работу<br />

CLR. Прим<strong>е</strong>нять<br />

<strong>е</strong>го в ц<strong>е</strong>лях,<br />

отличных<br />

от цч<strong>е</strong>бных, н<strong>е</strong><br />

сл<strong>е</strong>ду<strong>е</strong>т.<br />

О<br />

М<strong>е</strong>тод<br />

созда<strong>е</strong>т<br />

экз<strong>е</strong>мпляр<br />

Clone и н<strong>е</strong>м<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нно<br />

убива<strong>е</strong>т<br />

<strong>е</strong>го, убирая<br />

вс<strong>е</strong> ссылки.<br />

p u b l i c v o i d D i s p o s e 0 {<br />

}<br />

M e s s a g e B o x .S h o w ( " I ' v e b e e n d i s p o s e d ! " ,<br />

" C l o n e #" + I d + " s a y s . . . " ) ;<br />

M e s s a g e B o x .S h o w ( " A a a r g h ! Y o u g o t m e !",<br />

Создайт<strong>е</strong> qx)pMy с тр<strong>е</strong>лля кнопкам и -<br />

" C l o n e #" + Id + " s a y s . . . " ) ;<br />

вот так выглядит<br />

вама ^<br />

форМй-<br />

П р и п о м о щ и о п <strong>е</strong>ратора u s i n g создайт<strong>е</strong> экз<strong>е</strong>мпляр C l o n e в обработч<br />

и к <strong>е</strong> с о б ы т и я Click. Э т о п<strong>е</strong>рвая часть кода кнопки:<br />

p r i v a t e v o i d c l o n e l _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s<br />

u s i n g (Clone c l o n e l = n e w C l o n e (1)) {<br />

--- ^ // Н и ч <strong>е</strong> г о<br />

}<br />

}<br />

н<strong>е</strong> д<strong>е</strong>лайт<strong>е</strong>!<br />

У<br />

Так как cionei был объявл<strong>е</strong>н<br />

при помощи оп<strong>е</strong>ратора<br />

using, запуска<strong>е</strong>тся <strong>е</strong>го м<strong>е</strong>тод<br />

DisposeQ.<br />

e) {<br />

оста<strong>е</strong>тся I<br />

cSo/ku<br />

aone#i<br />

,aone#2<br />

GC<br />

640 глава 14


о П одклю чит<strong>е</strong> дв<strong>е</strong> други<strong>е</strong> кнопки<br />

Создайт<strong>е</strong> <strong>е</strong>щ<strong>е</strong> один экз<strong>е</strong>мпляр C l o n e в обработчик<strong>е</strong> события C l i c k<br />

второй кнопки и присвойт<strong>е</strong> <strong>е</strong>му знач<strong>е</strong>ни<strong>е</strong> null:<br />

p r i v a t e v o i d c l o n e 2 _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e) {<br />

C l o n e c l o n e 2 = n e w C l o n e (2);<br />

c l o n e 2 = null;<br />

Так как в данном случа<strong>е</strong>, отсутству<strong>е</strong>т<br />

} оп<strong>е</strong>ратор using, м<strong>е</strong>тод DisposeQ за ­<br />

пущ<strong>е</strong>н н<strong>е</strong> буд<strong>е</strong>т. Но сработа<strong>е</strong>т м<strong>е</strong>тод<br />

зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта.<br />

Для тр<strong>е</strong>ть<strong>е</strong>й кнопки вызовит<strong>е</strong> м<strong>е</strong>тод G C . C o l l e c t о , чтобы запустить<br />

проц<strong>е</strong>дуру сборки мусора.<br />

p r i v a t e v o i d g c _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s<br />

G C . C o l l e c t 0 ;<br />

} — Эта строчка ■*£--------—<br />

принудит<strong>е</strong>льно<br />

запуска<strong>е</strong>т сбор<br />

Запустит<strong>е</strong> проградш у<br />

мусора.<br />

Щ <strong>е</strong>лкнит<strong>е</strong> на п<strong>е</strong>рвой кнопк<strong>е</strong>, чтобы вызвать м<strong>е</strong>тод D i s p o s e ().<br />

Clone #1 says,«<br />

I’ve beendisposed!<br />

OK<br />

“ 1<br />

e) {<br />

Помнит<strong>е</strong>, что подобного<br />

д<strong>е</strong>лать н<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т. В данном<br />

случа<strong>е</strong> мы д<strong>е</strong>ла<strong>е</strong>м это<br />

исключит<strong>е</strong>льно для уч<strong>е</strong>бных<br />

и д<strong>е</strong>монстрационных<br />

ц<strong>е</strong>л<strong>е</strong>/А.<br />

Хотя объ<strong>е</strong>кта С!оп<strong>е</strong>±<br />

I f<br />

втван<br />

он вс<strong>е</strong><br />

em в куч<strong>е</strong> и ожида<strong>е</strong>т<br />

сборщика мусора.<br />

Мусор в итог<strong>е</strong> собран. В большинств<strong>е</strong> случа<strong>е</strong>в вы н<strong>е</strong><br />

увидит<strong>е</strong> окна с сообщ<strong>е</strong>ни<strong>е</strong>м об этом, так как м<strong>е</strong>жду<br />

присво<strong>е</strong>ни<strong>е</strong>м объ<strong>е</strong>кту знач<strong>е</strong>ния null и сборкой мусора<br />

проходит н<strong>е</strong>которо<strong>е</strong> вр<strong>е</strong>мя.<br />

Щ <strong>е</strong>лкнит<strong>е</strong> на второй кнопк<strong>е</strong>. Нич<strong>е</strong>го н<strong>е</strong> произойд<strong>е</strong>т,<br />

так как мы н<strong>е</strong> использовали оп<strong>е</strong>ратор using. Окно<br />

диалога с сообщ<strong>е</strong>ни<strong>е</strong>м от м<strong>е</strong>тода зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта<br />

появится только посл<strong>е</strong> сборки мусора.<br />

Щ <strong>е</strong>лкнит<strong>е</strong> на тр<strong>е</strong>ть<strong>е</strong>й кнопк<strong>е</strong>, чтобы принудит<strong>е</strong>льно<br />

запустить эту проц<strong>е</strong>дуру. Появятся два окна диалога:<br />

для объ<strong>е</strong>ктов C l o n e l и С1оп<strong>е</strong>2.<br />

Куча<br />

объ<strong>е</strong>кт<br />

С\оп<strong>е</strong>Я- ' ~<br />

илакж<strong>е</strong> пока<br />

остаг,тся<br />

б к уч<strong>е</strong>, но<br />

ссылок Нй<br />

н<strong>е</strong>го уж<strong>е</strong> н<strong>е</strong>т.<br />

'Опгг<br />

К у ч а<br />

СЬп<strong>е</strong>*2:^. ИММ Done #1 says... 1т^Й<br />

АвагдЫYoujot me!<br />

Aaargh! Yougot me!<br />

i


н<strong>е</strong>стабильная ср<strong>е</strong>да<br />

Возможны<strong>е</strong> пробл<strong>е</strong>мы<br />

Вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> завис<strong>е</strong>ть от запуска м<strong>е</strong>тода зав<strong>е</strong>рш<strong>е</strong>ния<br />

объ<strong>е</strong>кта в произвольный мом<strong>е</strong>нт. Даж<strong>е</strong><br />

вызов м<strong>е</strong>тода G C . C o l l e c t O —которым н<strong>е</strong> стоит<br />

пользоваться, <strong>е</strong>сли у вас н<strong>е</strong>т в<strong>е</strong>ских на то причин —<br />

только пр<strong>е</strong>длага<strong>е</strong>т запустить сборш,ик мусора. И<br />

н<strong>е</strong>т гарантии, что это случится н<strong>е</strong>м<strong>е</strong>дл<strong>е</strong>нно. Бол<strong>е</strong><strong>е</strong><br />

того, узнать, в каком порядк<strong>е</strong> будут удаляться объ<strong>е</strong>кты,<br />

н<strong>е</strong>возможно.<br />

Что это означа<strong>е</strong>т на практик<strong>е</strong>? Пр<strong>е</strong>дставим, что у<br />

вас <strong>е</strong>сть ссылаюш;и<strong>е</strong>ся друг на друга объ<strong>е</strong>кты. Если<br />

объ<strong>е</strong>кт #1 буд<strong>е</strong>т удал<strong>е</strong>н п<strong>е</strong>рвым, ссылка объ<strong>е</strong>кта #2<br />

начн<strong>е</strong>т указывать в никуда. И наоборот. Другими<br />

словами, вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> полагаться на ссылки в м<strong>е</strong>тод<strong>е</strong><br />

зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта. То <strong>е</strong>сть пом<strong>е</strong>щать в м<strong>е</strong>тод<br />

зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта оп<strong>е</strong>рации, зависящи<strong>е</strong> от ссылок,<br />

явно н<strong>е</strong> стоит.<br />

Хорошим прим<strong>е</strong>ром проц<strong>е</strong>дуры, которая н и в<br />

к о <strong>е</strong>м сл уч а<strong>е</strong> н <strong>е</strong> д о л ж н а ок а за т ь ся в н у тр и м <strong>е</strong>т о ­<br />

д а за в <strong>е</strong> р ш <strong>е</strong>н и я о б ъ <strong>е</strong>к т а , явля<strong>е</strong>тся с<strong>е</strong>риализация.<br />

Если объ<strong>е</strong>кт ссыла<strong>е</strong>тся на множ<strong>е</strong>ство других объ<strong>е</strong>ктов,<br />

с<strong>е</strong>риализации подв<strong>е</strong>рга<strong>е</strong>тся вся ц<strong>е</strong>почка. Но<br />

<strong>е</strong>сли сборка мусора уж<strong>е</strong> произошла, вы мож<strong>е</strong>т<strong>е</strong> н <strong>е</strong> ­<br />

д о сч и т а т ь с я важных част<strong>е</strong>й программы, так как<br />

н<strong>е</strong>которы<strong>е</strong> объ<strong>е</strong>кты могут быть отправл<strong>е</strong>ны в мусор<br />

до запуска м<strong>е</strong>тода их зав<strong>е</strong>рш<strong>е</strong>ния.<br />

К счастью, <strong>C#</strong> пр<strong>е</strong>длага<strong>е</strong>т удачно<strong>е</strong> р<strong>е</strong>ш <strong>е</strong>ни<strong>е</strong> данной<br />

пробл<strong>е</strong>мы: инт<strong>е</strong>рф<strong>е</strong>йс I D i s p o s a b l e . Вс<strong>е</strong> р<strong>е</strong>дактирования<br />

ключ<strong>е</strong>вых данных или данных, зависящих<br />

от находящихся в памяти объ<strong>е</strong>ктов, нужно<br />

д<strong>е</strong>лать частью м<strong>е</strong>тода D i s p o s e ().<br />

Иногда пользоват<strong>е</strong>ли считают м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния<br />

объ<strong>е</strong>кта бол<strong>е</strong><strong>е</strong> над<strong>е</strong>жным вариантом м<strong>е</strong>тода<br />

D i s p o s e О . И н<strong>е</strong> б<strong>е</strong>з оснований — на прим<strong>е</strong>р<strong>е</strong><br />

объ<strong>е</strong>ктов C l o n e вы уж<strong>е</strong> вид<strong>е</strong>ли, что р<strong>е</strong>ализация<br />

инт<strong>е</strong>рф<strong>е</strong>йса I D i s p o s a b l e н<strong>е</strong> означа<strong>е</strong>т вызова м<strong>е</strong>тода<br />

D i s p o s e {). П ри этом <strong>е</strong>сли м<strong>е</strong>тод D i s p o s e ()<br />

зависит от объ<strong>е</strong>ктов, находящихся в куч<strong>е</strong>, <strong>е</strong>го вызов<br />

в м<strong>е</strong>тод<strong>е</strong> зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта мож<strong>е</strong>т прив<strong>е</strong>сти<br />

к пробл<strong>е</strong>мам. Лучш<strong>е</strong> вс<strong>е</strong>го в с<strong>е</strong>гд а и сп о л ь зо в а т ь<br />

о п <strong>е</strong> р а т о р u s i n g для создания объ<strong>е</strong>ктов, р<strong>е</strong>ализующих<br />

и н т<strong>е</strong>рф <strong>е</strong>й с I D i s p o s a b l e .<br />

Пр<strong>е</strong>дположим, у вас <strong>е</strong>сть два<br />

объ<strong>е</strong>кта, ссы лаю щ и<strong>е</strong>ся друг<br />

на д р уга...<br />

...о н и оба пом<strong>е</strong>ч<strong>е</strong>ны для сборки мусора,<br />

но объ<strong>е</strong>кт #1 удаля<strong>е</strong>тся п<strong>е</strong>рвы м ...<br />

-Бах! —<br />

/ 1 \<br />

...хотя п<strong>е</strong>рвы м мог бы ть удал<strong>е</strong>н<br />

и объ<strong>е</strong>кт #2. Порядок вы полн<strong>е</strong>ния этой<br />

проц<strong>е</strong>дуры узнать н<strong>е</strong>возм ож но...<br />

...и м <strong>е</strong>н н о поэтому м<strong>е</strong>тод<br />

зав<strong>е</strong>рш <strong>е</strong>ния одного объ<strong>е</strong>кта н<strong>е</strong><br />

мож<strong>е</strong>т полагаться на объ<strong>е</strong>кты , до<br />

сих пор присутствую щ и<strong>е</strong> в куч<strong>е</strong>.<br />

642 глава 14


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

С<strong>е</strong>риализу<strong>е</strong>м объ<strong>е</strong>кт 6 м<strong>е</strong>тод<strong>е</strong> D isp ose d<br />

Т<strong>е</strong>п<strong>е</strong>рь, когдавы понялиразницум<strong>е</strong>жду м<strong>е</strong>тодом D i s p o s e ()<br />

и м<strong>е</strong>тодом зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта, напиш<strong>е</strong>м объ<strong>е</strong>кт, автоматич<strong>е</strong>ски<br />

с<strong>е</strong>риализуюш;ий с<strong>е</strong>бя п<strong>е</strong>р<strong>е</strong>д удал<strong>е</strong>ни<strong>е</strong>м.<br />

У п р а ж н <strong>е</strong> н и <strong>е</strong><br />

Сд<strong>е</strong>ла<strong>е</strong>м с<strong>е</strong>риализу<strong>е</strong>мы м класс C lo n e (со с. 6 4 0 )<br />

Просто добавьт<strong>е</strong> в в<strong>е</strong>рхнюю часть класса атрибут S e r i a l i z e a b l e .<br />

о<br />

о<br />

[ S e r i a l i z a b l e ]<br />

c l a s s C l o n e :<br />

I D i s p o s a b l e<br />

О тр<strong>е</strong>дактиру<strong>е</strong>м м <strong>е</strong>тод D i s p o s e ()<br />

Воспользу<strong>е</strong>мся классом B i n a r y F o r m a t t e r для записи объ<strong>е</strong>кта C l o n e в файл<br />

внутри м<strong>е</strong>тода D i s p o s e О :<br />

_<br />

^ ^ ^ ___________ Аля доступа<br />

u s i n g S y s t e m . 10; " " ■— к м т о л ь з у <strong>е</strong> л № 1 М ^<br />

u s i n g S y s t e m . R u n t i m e . S e r i a l i z a t i o n . F o r m a t t e r s . B i n a r y ; ^<br />

H&CKOAbKO dupCK-<br />

/ / с у щ <strong>е</strong> с т в у ю щ и й к о д using.<br />

p u b l i c v o i d D i s p o s e 0 {<br />

s t r i n g f i l e n a m e = 0 " C : \ T e m p \ C l o n e . d a t "<br />

}<br />

s t r i n g d i r n a m e = @ " C : \ T e m p \ " ;<br />

if ( F i l e . E x i s t s ( f i l e n a m e ) = = false) {<br />

D i r e c t o r y . C r e a t e D i r e c t o r y ( d i r n a m e ) ;<br />

}<br />

B i n a r y F o r m a t t e r b f = n e w B i n a r y F o r m a t t e r ();<br />

u s i n g ( S t r e a m o u t p u t = F i l e . O p e n W r i t e ( f i l e n a m e ) )<br />

b f .S e r i a l i z e ( o u t p u t , this);<br />

}<br />

M e s s a g e B o x .S h o w ( " Д о л ж <strong>е</strong> н ..<br />

" C l o n e #'<br />

. с <strong>е</strong> р и а л и з о в а т ь . . .<br />

+ I d + " г о в о р и т .<br />

о б ъ <strong>е</strong> к т !<br />

Запустит<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong><br />

Вы увидит<strong>е</strong> ровно то ж<strong>е</strong> само<strong>е</strong>, что и н<strong>е</strong>сколькими страницами ран<strong>е</strong><strong>е</strong>... но т<strong>е</strong>п<strong>е</strong>рь<br />

п<strong>е</strong>р<strong>е</strong>д удал<strong>е</strong>ни<strong>е</strong>м объ<strong>е</strong>кт C l o n e l буд<strong>е</strong>т сохран<strong>е</strong>н в файл. О ткройт<strong>е</strong> этот<br />

файл, и вы увидит<strong>е</strong> двоично<strong>е</strong> пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>кта.<br />

ШТУРМ<br />

Как, по-ваш<strong>е</strong>му, выглядит полный код объ<strong>е</strong>кта<br />

S u p e r H e r o ? Часть <strong>е</strong>го показана на с. 634. Вы<br />

мож<strong>е</strong>т<strong>е</strong> написать остально<strong>е</strong>?<br />

Имя файла было<br />

включ<strong>е</strong>но в код в вид<strong>е</strong><br />

строковой константы.<br />

Для уч<strong>е</strong>бной<br />

программы это нор -<br />

малш о. но мож<strong>е</strong>т<br />

сопровождаться пробл<strong>е</strong>мами.<br />

Понима<strong>е</strong>т<strong>е</strong><br />

ли вы, каки<strong>е</strong> это<br />

пробл<strong>е</strong>мы и видит<strong>е</strong><br />

ли пути их р<strong>е</strong>ш<strong>е</strong>нияР<br />

Правда ли, что м<strong>е</strong>тод<br />

DisposeQ н<strong>е</strong> им<strong>е</strong><strong>е</strong>т<br />

побочных эфф<strong>е</strong>ктов?<br />

Что произойд<strong>е</strong>т, <strong>е</strong>сли<br />

<strong>е</strong>го вызвать бол<strong>е</strong><strong>е</strong><br />

одного раза? Р<strong>е</strong>ализця<br />

инт<strong>е</strong>рф<strong>е</strong>йс IDisposable,<br />

им<strong>е</strong><strong>е</strong>т смысл заран<strong>е</strong><strong>е</strong><br />

думать о таких<br />

в<strong>е</strong>ш,ах.<br />

дальш<strong>е</strong> > 643


что случилось с капитаном?<br />

Б<strong>е</strong>с<strong>е</strong>да у камина<br />

М <strong>е</strong>тод Disposée) и м <strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния<br />

объ<strong>е</strong>кта спорят о то м , к т о из них<br />

ц<strong>е</strong>нн<strong>е</strong><strong>е</strong>.<br />

Disposée)<br />

Ч<strong>е</strong>стно говоря, приглаш<strong>е</strong>ни<strong>е</strong> сюда м<strong>е</strong>ня удивило.<br />

Я думал, программисты уж<strong>е</strong> пришли к соглаш<strong>е</strong>нию.<br />

О том, что я бол<strong>е</strong><strong>е</strong> ц<strong>е</strong>нный. Ты выглядишь<br />

жалко. Ты н<strong>е</strong> в состоянии с<strong>е</strong>риализовать с<strong>е</strong>бя<br />

или отр<strong>е</strong>дактировать ключ<strong>е</strong>вы<strong>е</strong> данны<strong>е</strong>. Ты ж<strong>е</strong><br />

н<strong>е</strong>стабил<strong>е</strong>н, разв<strong>е</strong> н<strong>е</strong> так?<br />

И нт<strong>е</strong>рф <strong>е</strong>йс сущ<strong>е</strong>ству<strong>е</strong>т им <strong>е</strong>нно потому, что я<br />

оч<strong>е</strong>нь важ<strong>е</strong>н. Бол<strong>е</strong><strong>е</strong> того, я <strong>е</strong>динств<strong>е</strong>нный м<strong>е</strong>тод<br />

этого инт<strong>е</strong>рф<strong>е</strong>йса!<br />

Да, <strong>е</strong>сли программисты н<strong>е</strong> используют оп<strong>е</strong>ратор<br />

u s in g , они должны вызвать м<strong>е</strong>ня вручную. Но<br />

они вс<strong>е</strong>гда знают, когда я запускаюсь, и могут вызывать<br />

м<strong>е</strong>ня, когда н<strong>е</strong>обходимо удалить объ<strong>е</strong>кт.<br />

Я мощный, над<strong>е</strong>жный и л<strong>е</strong>гкий в прим<strong>е</strong>н<strong>е</strong>нии. Я<br />

унив<strong>е</strong>рсал<strong>е</strong>н. А ты? Н икто н<strong>е</strong> зна<strong>е</strong>т, когда ты появишься,<br />

и в каком состоянии в этот мом<strong>е</strong>нт буд<strong>е</strong>т<br />

прилож<strong>е</strong>ни<strong>е</strong>.<br />

По сути ты н<strong>е</strong> д<strong>е</strong>ла<strong>е</strong>шь нич<strong>е</strong>го, ч<strong>е</strong>го н<strong>е</strong> мог бы<br />

сд<strong>е</strong>лать я. Н о ты счита<strong>е</strong>шь с<strong>е</strong>бя важным только<br />

потому, что запуска<strong>е</strong>шься при сборк<strong>е</strong> мусора.<br />

М <strong>е</strong> т о д зав<strong>е</strong>рш <strong>е</strong>ния о б ъ <strong>е</strong> к т а<br />

Потрясающ<strong>е</strong>! Я жалок... хорошо. Я н<strong>е</strong> хот<strong>е</strong>л п<strong>е</strong>р<strong>е</strong>ходить<br />

на личности, но посл<strong>е</strong> такого выпада...<br />

мн<strong>е</strong>, по крайн<strong>е</strong>й м<strong>е</strong>р<strong>е</strong>, н<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся инт<strong>е</strong>рф<strong>е</strong>йс<br />

для работы. А ты б<strong>е</strong>з инт<strong>е</strong>рф<strong>е</strong>йса I D is p o s a b le —<br />

н<strong>е</strong> бол<strong>е</strong><strong>е</strong>, ч<strong>е</strong>м <strong>е</strong>щ<strong>е</strong> один б<strong>е</strong>спол<strong>е</strong>зный м<strong>е</strong>тод.<br />

Кон<strong>е</strong>чно, кон<strong>е</strong>чно... продолжай ут<strong>е</strong>шать с<strong>е</strong>бя.<br />

А что произойд<strong>е</strong>т, <strong>е</strong>сли пользоват<strong>е</strong>ль при создании<br />

экз<strong>е</strong>мпляра забуд<strong>е</strong>т оп<strong>е</strong>ратор u s in g ? Т<strong>е</strong>бя<br />

даж<strong>е</strong> никто н<strong>е</strong> найд<strong>е</strong>т!<br />

Обработчики используются<br />

программами для н<strong>е</strong>поср<strong>е</strong>д -<br />

ств<strong>е</strong>нного взаимод<strong>е</strong>йствия с<br />

Windows. Так как .NET о них н<strong>е</strong><br />

зна<strong>е</strong>т, она н<strong>е</strong> мож<strong>е</strong>т удалить<br />

их за вас.<br />

Хорошо. Но <strong>е</strong>сли нужно сд<strong>е</strong>лать что-то в самый<br />

посл<strong>е</strong>дний мом<strong>е</strong>нт п<strong>е</strong>р<strong>е</strong>д отправкой объ<strong>е</strong>кта на<br />

удал<strong>е</strong>ни<strong>е</strong>, б<strong>е</strong>з м<strong>е</strong>ня н<strong>е</strong> обойтись. Я освобождаю ,<br />

с<strong>е</strong>т<strong>е</strong>вы<strong>е</strong> р<strong>е</strong>сурсы, а такж<strong>е</strong> обработчики и п о то к и /<br />

\Vindows и вс<strong>е</strong>, что мож<strong>е</strong>т стать причиной пробл<strong>е</strong>м,<br />

<strong>е</strong>сли <strong>е</strong>го вовр<strong>е</strong>мя н<strong>е</strong> удалить. Я гарантирую<br />

аккуратно<strong>е</strong> удал<strong>е</strong>ни<strong>е</strong> объ<strong>е</strong>ктов, и на это ты нич<strong>е</strong>го<br />

возразить н<strong>е</strong> смож<strong>е</strong>шь.<br />

Ты слишком много мнишь о с<strong>е</strong>б<strong>е</strong>, прият<strong>е</strong>ль.<br />

644 глава 14


Мож<strong>е</strong>т пи м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния пользоваться полями<br />

и м<strong>е</strong>тодами объ<strong>е</strong>ктов?<br />

Часзг>°<br />

Q ; Кон<strong>е</strong>чно, вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> п<strong>е</strong>р<strong>е</strong>давать <strong>е</strong>му парам<strong>е</strong>тры, но<br />

мож<strong>е</strong>т<strong>е</strong> пользоваться полями объ<strong>е</strong>ктов как напрямую, так и при<br />

помощи ключ<strong>е</strong>вого слова t h i s . Но будьт<strong>е</strong> аккуратны в случаях,<br />

когда поля ссылаются на други<strong>е</strong> объ<strong>е</strong>кты. Можно такж<strong>е</strong> вызывать<br />

други<strong>е</strong> м<strong>е</strong>тоды для утилизиру<strong>е</strong>мых объ<strong>е</strong>ктов.<br />

Что случа<strong>е</strong>тся с исключ<strong>е</strong>ниями, появившимися в м<strong>е</strong>тод<strong>е</strong><br />

зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта?<br />

^ ! Д<strong>е</strong>йствит<strong>е</strong>льно, ничто н<strong>е</strong> м<strong>е</strong>ша<strong>е</strong>т пом<strong>е</strong>стить в этот м<strong>е</strong>тод<br />

блок t r y / c a t c h . Создайт<strong>е</strong> исключ<strong>е</strong>ни<strong>е</strong> «д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> на ноль»<br />

в блок<strong>е</strong> t r y написанной нами программы для клонов. Пусть<br />

окно с сообщ<strong>е</strong>ни<strong>е</strong>м «I just caught ап exception» появля<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>д<br />

сообщ<strong>е</strong>ни<strong>е</strong>м «...I’ve been destroyed». Запустит<strong>е</strong> программу и<br />

щ<strong>е</strong>лкнит<strong>е</strong> на п<strong>е</strong>рвой и тр<strong>е</strong>ть<strong>е</strong>й кнопках. По оч<strong>е</strong>р<strong>е</strong>ди появятся<br />

оба окна диалога. (Разум<strong>е</strong><strong>е</strong>тся, вызывать окна диалога в м<strong>е</strong>тод<strong>е</strong><br />

зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>ктов ни в ко<strong>е</strong>м случа<strong>е</strong> н<strong>е</strong> нужно.)<br />

з а д а в а <strong>е</strong> м ы <strong>е</strong><br />

БоПр>ос;ь1<br />

Бt Как часто происходит автоматич<strong>е</strong>ская сборка мусора?<br />

Q ; На этот вопрос н<strong>е</strong>т отв<strong>е</strong>та. Н<strong>е</strong> сущ<strong>е</strong>ству<strong>е</strong>т постоянного<br />

цикла, и вы никак н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> контролировать этот проц<strong>е</strong>сс. Он<br />

гарантированно запуска<strong>е</strong>тся при выход<strong>е</strong> из программы или посл<strong>е</strong><br />

вызова м<strong>е</strong>тода GC . C o l l e c t ().<br />

Как быстро начина<strong>е</strong>тся сбор мусора посл<strong>е</strong> вызова м<strong>е</strong>тода<br />

G C . C o l l e c t () ?<br />

j; М<strong>е</strong>тод G C . C o l l e c t {) просит .NETосущ<strong>е</strong>ствить<br />

cbop мусора как можно быстр<strong>е</strong><strong>е</strong>. Обычно .NET приступа<strong>е</strong>т<br />

к этой проц<strong>е</strong>дур<strong>е</strong> посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния т<strong>е</strong>кущих заданий. То<br />

<strong>е</strong>сть мусор убира<strong>е</strong>тся довольно оп<strong>е</strong>ративно, но вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong><br />

контролировать этот проц<strong>е</strong>сс.<br />

Если мн<strong>е</strong> обязат<strong>е</strong>льно нужно что-то запустить, им<strong>е</strong><strong>е</strong>т ли<br />

смысл пом<strong>е</strong>стить это в м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта?<br />

! Код этого м<strong>е</strong>тода мож<strong>е</strong>т и н<strong>е</strong> быть запущ<strong>е</strong>н. Но в общ<strong>е</strong>м<br />

случа<strong>е</strong> да, м<strong>е</strong>тод зав<strong>е</strong>рш<strong>е</strong>ния объ<strong>е</strong>кта обязат<strong>е</strong>льно запуска<strong>е</strong>тся.<br />

дальш<strong>е</strong> ► 645


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Структура напомина<strong>е</strong>т объ<strong>е</strong>кт...<br />

О д н и м из т и п о в .N E T, о к о т о р ы х м ы <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> уп о м и н а л и , явл<br />

я ю тс я с т р у к т у р ы (s tru c tu re ). О н и ка к и о б ъ <strong>е</strong>кты обладаю т<br />

полям и и свойствам и. И х м о ж н о даж<strong>е</strong> п<strong>е</strong>р<strong>е</strong>дать м<strong>е</strong>тоду, п р и ­<br />

ним аю щ <strong>е</strong>м у парам <strong>е</strong>тры т и п а с Ь j ect:<br />

м о г у т<br />

инт<strong>е</strong>рф <strong>е</strong>йса., но<br />

н<strong>е</strong> могцт быть<br />

'унасл<strong>е</strong>дованы.<br />

p u b l i c s t r u c t A l m o s t S u p e r h e r o<br />

}<br />

p u b l i c i n t S u p e r S t r e n g t h ;<br />

p u b l i c i n t S u p e r S p e e d {<br />

I D i s p o s a b l e {<br />

get; p r i v a t e set<br />

p u b l i c v o i d R e m o v e V i l l a i n ( V i l l a i n v i l l a i n )<br />

{<br />

C o n s o l e - W r i t e L i n e ( " O K , " + v i l l a i n . N a m e +<br />

if<br />

e l s e<br />

" с д а в а й с я и п р <strong>е</strong> к р а щ а й б <strong>е</strong> з у м и <strong>е</strong> !");<br />

( v i l l a i n .S u r r e n d e r e d )<br />

v i l l a i n .G o T o J a i l ();<br />

v i l l a i n .K i l l ();<br />

p u b l i c v o i d D i s p o s e 0 { ... }<br />

...HO объ<strong>е</strong>ктом н<strong>е</strong> ябля<strong>е</strong>тся<br />

С тр уктуры м о гут им <strong>е</strong>ть п о л я и м <strong>е</strong>тоды , н о для н и х н<strong>е</strong>возм о­<br />

ж <strong>е</strong> н м <strong>е</strong>тод зав<strong>е</strong>рш <strong>е</strong>ния объ<strong>е</strong>кта. Н асл<strong>е</strong>дования для н и х такж <strong>е</strong><br />

н<strong>е</strong>возм ож но.<br />

Вс<strong>е</strong> структуры являются<br />

производными от<br />

класса 5^&Ыт.Уа1и<strong>е</strong>Тию<strong>е</strong>,<br />

который в свою оч<strong>е</strong>р<strong>е</strong>дь<br />

насл<strong>е</strong>ду<strong>е</strong>т от класса<br />

Ву5Ъ<strong>е</strong>т.дЬ]<strong>е</strong>с±. Поэтому<br />

каждая ст рукт ц-<br />

ра облада<strong>е</strong>т м<strong>е</strong>тодом<br />

ТоЗЬппдО). Но этим<br />

способность к насл<strong>е</strong>-<br />

Ообанию у структур<br />

и исч<strong>е</strong>рпыва<strong>е</strong>тся<br />

о т объ<strong>е</strong>ктов.<br />

Вм<strong>е</strong>сто отд<strong>е</strong>льных<br />

объ<strong>е</strong>ктов можно использовать<br />

ст рцк-<br />

1^уры , но они н<strong>е</strong> в<br />

состоянии участвооать<br />

в постро<strong>е</strong>нии<br />

и<strong>е</strong>рархий.<br />

структуры н<strong>е</strong> им<strong>е</strong>ют<br />

647


созда<strong>е</strong>м копию<br />

Знач<strong>е</strong>ния копируются, а ссылки присбаиВаются<br />

В ы уж <strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, ч<strong>е</strong>м о д и н т и п отл ича<strong>е</strong>тся о т д р уго го . С о д н о й с т о р о н ы им <strong>е</strong>­<br />

ю тс я значимы<strong>е</strong> типы, та ки <strong>е</strong> как int, b o o l и decimal. С д р уго й с т о р о н ы —<br />

объ<strong>е</strong>кты, та ки <strong>е</strong> ка к List, S t r e a m и E x c e p t i o n . И о н и р а б о та ю т по-разному.<br />

В случа<strong>е</strong> значи м ы х т и п о в о п <strong>е</strong> р а то р п р и с в а и в а н и я копиру<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong>. П <strong>е</strong> ­<br />

р <strong>е</strong> м <strong>е</strong>нны <strong>е</strong> п р и этом н и к а к н<strong>е</strong> связаны д р уг с другом . В случа<strong>е</strong> ж <strong>е</strong> ссы л ок о п <strong>е</strong> ­<br />

р а то р п р и с в а и в а н и я нац<strong>е</strong>лива<strong>е</strong>т об<strong>е</strong> ссылки на один и тот ж<strong>е</strong> объ<strong>е</strong>кт.<br />

Вспомним, ч<strong>е</strong>м<br />

от личают ся значимы<strong>е</strong><br />

т ипы от<br />

одь<strong>е</strong>ктов.<br />

О О б ъ явл<strong>е</strong>ни<strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н ы х и о п <strong>е</strong> р а ц и я п р и сваивания одинако-<br />

Помнит<strong>е</strong>, мы вы для о б о и х ти п о в ;<br />

у ^qqI — э т о значимы<strong>е</strong> типы,<br />

говорили, что g вр<strong>е</strong>м я как List ы Exception<br />

м<strong>е</strong>тоды и one- h o w M a n v = 25- принадл<strong>е</strong>жат т ипу object,<br />

раторы ВСЕГДА ^ ^ ^ ,<br />

находятся внутри b o o l S c a r y - true;<br />

классов?Это н<strong>е</strong> L i s t < d o u b l e > t e m p e r a t u r e s = n e w L i s t < d o u b l e > ();<br />

совс<strong>е</strong>м так, в<strong>е</strong>дь<br />

они м огут находиться<br />

и внутри<br />

ст рукт ур.<br />

О<br />

E x c e p t i o n e x = n e w E x c e p t i o n<br />

^<br />

'Does n o t c o m p u t e " )<br />

Присво<strong>е</strong>ни<strong>е</strong> н а­<br />

чальных знач<strong>е</strong>ни<strong>е</strong>^<br />

осущ<strong>е</strong>ствля<strong>е</strong>тся<br />

стандарт ным<br />

способом.<br />

Р азличия н а ч и н а ю тся п р и п р и с в о <strong>е</strong> н и и зн а ч <strong>е</strong> н и й . Д ля зн а ч и м ы х т и п о в эта оп<strong>е</strong>рация осущ<br />

<strong>е</strong>ствля<strong>е</strong>тся м <strong>е</strong>тодом ко п и р о в а н и я :<br />

Знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

г1П<strong>е</strong><strong>е</strong>пМог<strong>е</strong> копирц<strong>е</strong>тся й<br />

lnt flfteenMore = howMany;<br />

р<strong>е</strong>м<strong>е</strong>нную<br />

Изм<strong>е</strong>н<strong>е</strong>ни<strong>е</strong> зна- f i f t e e n M o r e -1-= 15;<br />

к н<strong>е</strong>му прибавля<strong>е</strong>т ^<br />

ч<strong>е</strong>ныя п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>н ^ ■<br />

ной Р1Н:<strong>е</strong><strong>е</strong>пМог<strong>е</strong> C o n s o l e . W r i t e L i n e ( " h o w M a n y h a s {0}, f i f t e e n M o r e h a s {!]",<br />

никак н<strong>е</strong> влия<strong>е</strong>т<br />

h o w M a n y , f i f t e e n M o r e ) ;<br />

НЙ п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную^,<br />

howM any. Р<strong>е</strong>зультат д<strong>е</strong>м онстр иру<strong>е</strong>т, ч т о п <strong>е</strong> р <strong>е</strong> м <strong>е</strong>нны <strong>е</strong> f i f t e e n M o r e и h o w M a n y ни-<br />

______ ксцсн<strong>е</strong> связаны :<br />

О<br />

h o w M a n y h a s 25, f i f t e e n M o r e h a s 40<br />

В случа<strong>е</strong> о б ъ <strong>е</strong>ктов п р и св а и в а ю тся ссы л ки, а н<strong>е</strong> знач<strong>е</strong>ния:<br />

t e m p e r a t u r e s . A d d (56.5 D ) ;<br />

Q t e m p e r a t u r e s . A d d (27.4 D ) ;<br />

r ^ L i s t < f l o a t > d i f f e r e n t L i s t = t e m p e r a t u r e s ;<br />

d i f f e r e n t L i s t . A d d ( 6 2 . 9D) ;<br />

H a O b e ссылки<br />

ы кязы б я ю т НД<br />

один объ<strong>е</strong>кт.<br />

И зм <strong>е</strong> н <strong>е</strong> н и <strong>е</strong> объ<strong>е</strong>кта L i s t м <strong>е</strong>ня<strong>е</strong>т знач<strong>е</strong>ния об <strong>е</strong> их<br />

ссы лок:<br />

C o n s o l e . W r i t e L i n e ( " t e m p e r a t u r e s h a s {0}, d i f f e r e n t l i s t h a s {1}",<br />

t e m p e r a t u r e s . C o u n t 0 , d i f f e r e n t L i s t .C o u n t ());<br />

Р<strong>е</strong>зультат д<strong>е</strong>м о нстриру<strong>е</strong>т, ч т о об<strong>е</strong> ссы л ки н ац<strong>е</strong>л<strong>е</strong>ны М<strong>е</strong>тод<br />

на один и тот ж<strong>е</strong> объ<strong>е</strong>кт: н Г который ц>^а -<br />

t e m p e r a t u r e s h a s J., d i f f e r e n t L i s t h a s 3<br />

648 глава 14


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

С тр уктуры — это значимы<strong>е</strong>; а объ<strong>е</strong>кты — ссылочны<strong>е</strong> типы<br />

Создавая структуру, вы созда<strong>е</strong>т<strong>е</strong> значимый тип. Э то означа<strong>е</strong>т,<br />

ч т о о п <strong>е</strong> р а ц и я п р и с в а и в а н и я пр<strong>е</strong>дставля<strong>е</strong>т со б о й копировани<strong>е</strong><br />

стр уктур ы в н о вую п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нную . Так ч т о х о т я структура выглядит<br />

как объ<strong>е</strong>кт, та ко вы м она н<strong>е</strong> явля<strong>е</strong>тся.<br />

У з 1 ] ^ а ж н <strong>е</strong> н и ^<br />

Создайт<strong>е</strong> структуру Dog<br />

В о т п р о ста я стр уктура для хр а н <strong>е</strong> н и я д а н н ы х о собак<strong>е</strong>. Д обавьт<strong>е</strong> <strong>е</strong><strong>е</strong> в ново<strong>е</strong><br />

консольно<strong>е</strong> прилож<strong>е</strong>ни<strong>е</strong>.<br />

"р;ьиГ:Г.1Па1; \ А«, кл«« н.<br />

p u b l i c s t r i n g B r e e d ; С<br />

p u b l i c D o g ( s t r i n g na m e , s t r i n g b r e e d ) {<br />

t h is . N a m e = n a m e ;<br />

t h i s . B r e e d = b r e e d ;<br />

}<br />

О<br />

О<br />

}<br />

p u b l i c v o i d S p e a k 0 {<br />

C o n s o l e . W r i t e L i n e ("М <strong>е</strong> н я з о в у т { 0 } и я { 1 } . " , N am e, B r e e d ) ;<br />

}<br />

Создайт<strong>е</strong> класс Canine<br />

С к о п и р у й т<strong>е</strong> структур у Dog, зам<strong>е</strong>нив s t r u c t на c la s s , а Dog — зам<strong>е</strong>нив на<br />

Canine. (Н <strong>е</strong> забудьт<strong>е</strong> п<strong>е</strong>р<strong>е</strong>им <strong>е</strong>новать и к о н с тр у к т о р .) Т <strong>е</strong>п<strong>е</strong>рь у вас <strong>е</strong>сть класс<br />

Canine, п р а к ти ч <strong>е</strong> с к и и д <strong>е</strong> н т и ч н ы й стр уктур<strong>е</strong> Dog.<br />

Добавьт<strong>е</strong> м<strong>е</strong>тод M ain(), д<strong>е</strong>лающий копии Dog и Canine<br />

В о т код э т о го м<strong>е</strong>тода:<br />

C a n in e s p o t = new C a n i n e ( " S p o t '<br />

C a n in e b o b = s p o t ;<br />

b o b .N a m e = " S p i k e " ;<br />

b o b . B r e e d = " b e a g l e " ;<br />

s p o t . S p e a k 0 ;<br />

" p u g '<br />

D og j a k e = ne w D o g ( " J a k e " , " p o o d l e " ) ;<br />

D og b e t t y = j a k e ;<br />

b e t t y . N a m e = " B e t t y " ;<br />

b e t t y . B r e e d = " p i t b u l l " ;<br />

ja k e . S p e a k 0 ;<br />

Вы уж<strong>е</strong> работали со<br />

структурами. Помнит<strong>е</strong> Point<br />

из глав 12 и 13 и DateTime из<br />

главы 9 ? Это были структуры!<br />

возьми В руку карандаш<br />

C o n s o l e . R e a d K e y 0 ;<br />

П<strong>е</strong>р<strong>е</strong>д запуском проградАмы...<br />

З а п и ш и т<strong>е</strong> р<strong>е</strong>зультат, к о т о р ы й , с ваш <strong>е</strong>й т о ч к и зр <strong>е</strong> н и я , буд<strong>е</strong>т вы в<strong>е</strong>д<strong>е</strong>н на ко нсоль:<br />

дальш<strong>е</strong> ^ 649


1 ^ з ь м и в руку карандаш<br />

Р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong><br />

Вот, что произошло...<br />

На консоли буд<strong>е</strong>т написано:<br />

Му name is Spike and j'm a beagle.<br />

My name is Jake and I'm a poodle.<br />

С с ы л к и b o b и s p o t указывали на о д и н и тот ж <strong>е</strong> объ<strong>е</strong>кт,<br />

соотв<strong>е</strong>тств<strong>е</strong>нно, м <strong>е</strong> н я л и о д н и и т<strong>е</strong> ж <strong>е</strong> П О Л Я и об<strong>е</strong> и м <strong>е</strong> ­<br />

л и доступ к м<strong>е</strong>тоду S p e a k (). Н о структуры р а б о т а ю т<br />

н<strong>е</strong> так. Создав структуру betty, в ы с к о п и р о в а л и в н<strong>е</strong><strong>е</strong><br />

д а н н ы <strong>е</strong> из структуры j ак<strong>е</strong>. П р и э т о м друг от друга эти<br />

структуры н<strong>е</strong> зависят.<br />

Создан обь<strong>е</strong>кт<br />

Canine, на который<br />

т <strong>е</strong>п<strong>е</strong>рь указы ва<strong>е</strong>т<br />

ссылка spot.<br />

Spot<br />

C a n i n e s p o t = n e w C a n i n e ("Spot",<br />

" p u g " ) ; ( i )<br />

C a n i n e b o b = spot;<br />

b o b . N a m e = " S p i k e " ;<br />

b o b . B r e e d = " b e a g l e " ;<br />

s p o t .S p e a k ( ) ; fg<br />

Выла создана новая<br />

ссылочная п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная hob,<br />

но нового объ<strong>е</strong>кт а в куч<strong>е</strong> н<strong>е</strong><br />

появилось — п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> bob<br />

и sp o t указы ваю т на один<br />

и т от ж <strong>е</strong> объ<strong>е</strong>кт.<br />

Так как п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> sp o t и bob<br />

указы ваю т на один объ<strong>е</strong>кт<br />

записи spot.SpeakQ и bob.<br />

SpeakQ вызывают один и т от<br />

ж <strong>е</strong> м <strong>е</strong>т од с одним и т <strong>е</strong>м ж <strong>е</strong><br />

р<strong>е</strong>зульт ат ом — Spike и beagie.<br />

spot<br />

b o b I Spike<br />

D o g j a k e = n e w D o g ( " J a k e " , " p o o d l e " )<br />

D o g b e t t y = j a k e ; ^ ^<br />

b e t t y . N a m e = " B e t t y " ;<br />

b e t t y . B r e e d = " p i t b u l l " ;<br />

j a k e . S p e a k 0<br />

Создани<strong>е</strong> ст рукт уры<br />

напомина<strong>е</strong>т создани<strong>е</strong> ---<br />

объ<strong>е</strong>кт а — вы получа<strong>е</strong>т <strong>е</strong><br />

п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нную для дост упа<br />

к полям и м <strong>е</strong>т одам .<br />

poodle I<br />

jake<br />

А<br />

Оп<strong>е</strong>рация присваивания<br />

вот и отличи<strong>е</strong>.<br />

/Добавив п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>н -<br />

ную Ь<strong>е</strong>Ну, вы полу-,<br />

в случа<strong>е</strong> структур приводит<br />

к появл<strong>е</strong>нию н<strong>е</strong>за­<br />

чили ново<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong><br />

висимой копшданньк. нГЙКТзГн<strong>е</strong>ни<strong>е</strong> ^<br />

В<strong>е</strong>дь струка — это<br />

пол<strong>е</strong>й ст рукт уры jake.<br />

ЗНАЧИМЫМ ТИП.<br />

® ' '<br />

\<br />

Jake \<br />

! poodle j<br />

betty<br />

Betty \<br />

pit bull j<br />

betty<br />

Jake<br />

poodle<br />

jake<br />

Jake<br />

poodle<br />

'•■Ч__ . '<br />

jake


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Г<br />

Сравн<strong>е</strong>ни<strong>е</strong> ст<strong>е</strong>ка и кучи<br />

П о н я т ь , ч<strong>е</strong>м отл ича<strong>е</strong>тся структура о т объ<strong>е</strong>кта, н<strong>е</strong>слож н о . Н о ка к о п<strong>е</strong>рация<br />

к о п и р о в а н и я в ы гл я д и т изнутри?<br />

.N E T C L R пом <strong>е</strong>щ а<strong>е</strong>т д анны <strong>е</strong> в разны <strong>е</strong> области пам яти . В ы уж <strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, ч т о<br />

о б ъ <strong>е</strong> кты ж и в у т в куч<strong>е</strong>. Д ругая часть п а м я ти — ст<strong>е</strong>к — х р а н и т вс<strong>е</strong> объявля<strong>е</strong>мы<strong>е</strong><br />

вам и в м <strong>е</strong>тодах л окальны <strong>е</strong> п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> нны <strong>е</strong> и п<strong>е</strong>р<strong>е</strong>дава<strong>е</strong>мы<strong>е</strong> эти м м<strong>е</strong>тодам<br />

парам <strong>е</strong>тры . С т<strong>е</strong>к м о ж н о п р<strong>е</strong>дста ви ть в вид<strong>е</strong> н абора м<strong>е</strong>ст, в к о то р ы <strong>е</strong> вы п о ­<br />

м<strong>е</strong>щ а<strong>е</strong>т<strong>е</strong> зн ач<strong>е</strong>ния. П р и вы зов<strong>е</strong> м <strong>е</strong>тода C L R добавля<strong>е</strong>т в ст<strong>е</strong>к д ополнит<strong>е</strong>ль-<br />

1ы <strong>е</strong> м<strong>е</strong>ста. П осл <strong>е</strong> зав<strong>е</strong>рш <strong>е</strong>ния р а б о ты о н и удаляю тся.<br />

Н<strong>е</strong>смотря на<br />

возможность<br />

назначить<br />

Код<br />

ст рукт уру п <strong>е</strong>­<br />

р<strong>е</strong>м<strong>е</strong>нной т ипа Это код, который вы мож<strong>е</strong>т<strong>е</strong><br />

object, ст р ук- обнаружить в программ<strong>е</strong>.<br />

туры и объ<strong>е</strong>кты<br />

отличаются.<br />

C a n i n e s p o t = n e w C a n i n e ( " S p o t " , " p u g " ) ;<br />

D o g j a k e = n e w D o g ( " J a k e " , " p o o d l e " ) ;<br />

с Д <strong>е</strong> н о й /<br />

Помнит<strong>е</strong>, что в п р о ­<br />

ц<strong>е</strong>сс<strong>е</strong> работы ва ­<br />

ш<strong>е</strong>й программы CLR<br />

управля<strong>е</strong>т памят ью ,<br />

выд<strong>е</strong>ляя м<strong>е</strong>ст о в куч<strong>е</strong><br />

и собирая мусор.<br />

Вот как выглядит С т <strong>е</strong> к<br />

ст <strong>е</strong>к посл<strong>е</strong> вы полстрок<br />

^ д а ^ находятся структуры<br />

и локальны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong>.<br />

C a n i n e s p o t = n e w C a n i n e ( " S p o t " , " p u g " ) ;<br />

D o g j a k e = n e w D o g { " J a k e " , " p o o d l e " ) ;<br />

D o g b e t t y = jake;<br />

При создании новой ст рукт уры - или<br />

драгой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной значимого илилд<br />

в ст<strong>е</strong>к<strong>е</strong> появля<strong>е</strong>тся ново<strong>е</strong> м<strong>е</strong>сто. Сюда<br />

копиру<strong>е</strong>тся указанно<strong>е</strong> вами знач<strong>е</strong>ни<strong>е</strong>.<br />

C a n i n e s p o t = n e w C a n i n e ( " S p o t " , " p u g " ) ;<br />

D o g j a k e = n e w D o g ( " J a k e " , " p o o d l e " ) ;<br />

D o g b e t t y = jake;<br />

S p e a k T h r e e T i m e s (j a k e ) ;<br />

p u b l i c S p e a k T h r e e T i m e s (Dog dog) {<br />

----------------- — ------— _ При вызов<strong>е</strong> Oi?l300t' м<strong>е</strong>тода<br />

CLR пом<strong>е</strong>щ а<strong>е</strong>т <strong>е</strong>го<br />

for ( i = 0; i < 5; i++) локальны<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong><br />

нав<strong>е</strong>рх ст<strong>е</strong>ка. И цдаd<br />

o g .S p e a k () ; посл<strong>е</strong> заЬ<strong>е</strong>р -<br />

J<br />

ш<strong>е</strong>ния работы м<strong>е</strong>тода.<br />

дальш<strong>е</strong> > 651


н<strong>е</strong> ограничивайт<strong>е</strong> м<strong>е</strong>ня<br />

А зач<strong>е</strong>м мн<strong>е</strong> вс<strong>е</strong> это знать? В<strong>е</strong>дь я ж<strong>е</strong> н<strong>е</strong> могу<br />

никак повлиять на эти проц<strong>е</strong>ссы, разв<strong>е</strong> н<strong>е</strong> так?<br />

Чтобы опр<strong>е</strong>д<strong>е</strong>лить,<br />

структура ли п<strong>е</strong>р<strong>е</strong>д<br />

вами или другой значимый<br />

тип, упакованный<br />

в «оболочку»<br />

и пом<strong>е</strong>щ<strong>е</strong>нный в кучу<br />

используйт<strong>е</strong> ключ<strong>е</strong>во<strong>е</strong><br />

слом !5-<br />

И вс<strong>е</strong>-таки ж<strong>е</strong>лат<strong>е</strong>льно понимать, как копиру<strong>е</strong>мая по знач<strong>е</strong>нию<br />

структура отлича<strong>е</strong>тся от копиру<strong>е</strong>мого по ссылк<strong>е</strong> объ<strong>е</strong>кта.<br />

И н о гд а б ы ва<strong>е</strong>т н <strong>е</strong>обхо д и м о н а п и са ть м <strong>е</strong>тод, к о т о р ы й р абота <strong>е</strong>т и л и со<br />

значим ы м ти п о м или со с сы л о ч н ы м ти п о м . Н а п р и м <strong>е</strong> р , м <strong>е</strong>тод, р а б ота ю ­<br />

щ и й со с тр у к турой D o g и л и с объ<strong>е</strong>ктом Canine. В этом случа<strong>е</strong> п р и м <strong>е</strong> н я ­<br />

<strong>е</strong>тся кл ю ч<strong>е</strong>во<strong>е</strong> слово obj ect:<br />

p u b l i c v o i d W a l k D o g O r C a n i n e ( o b j e c t g e t s W a l k e d ) { ... }<br />

П <strong>е</strong>р<strong>е</strong>данная этом у м <strong>е</strong>тоду стр уктур а упаковыва<strong>е</strong>тся в сп<strong>е</strong>циальную «оболочку»,<br />

п озволяю щ ую <strong>е</strong>й н а хо д и ть ся в куч<strong>е</strong>. В это вр<strong>е</strong>м я работа ть со<br />

с тр у к турой н<strong>е</strong>возм о ж н о . Е<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся сначала «распаковать». К счастью ,<br />

э то п р о и с х о д и т автоматич<strong>е</strong>ски п р и п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> м <strong>е</strong>тоду вм <strong>е</strong>сто объ<strong>е</strong>кта знач<br />

и м о го ти п а .<br />

В о т как ст<strong>е</strong> к и куча в ы глядят посл<strong>е</strong> создания п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й т и п а<br />

obj e c t и п р и с в о <strong>е</strong> н и я <strong>е</strong>й стр у к туры Dog.<br />

D og s i d = new D o g ( " S i d " , " h u s k y " ) ;<br />

O b j e c t o b j = s i d ;<br />

- В Л -<br />

О<br />

Посл<strong>е</strong> упаковки<br />

структуры<br />

появляются дв<strong>е</strong><br />

копии данных: —<br />

в ст<strong>е</strong>к<strong>е</strong> и в<br />

куч<strong>е</strong>.<br />

Sid<br />

husky /<br />

Dog Sid (упакован)<br />

О б ъ <strong>е</strong> кт д о с та то ч н о п р и в <strong>е</strong> с т и к правильн о м у типу, и о н буд<strong>е</strong>т распакован<br />

авто м а ти ч<strong>е</strong>ски . Со значимыми типами использовать ключ<strong>е</strong>во<strong>е</strong><br />

слово a s н<strong>е</strong>льзя, поэто м у прив<strong>е</strong>д<strong>е</strong>м <strong>е</strong>го к Dog.<br />

D og h a p p y ^&=T(Dog)<br />

Посл<strong>е</strong> этой<br />

строчки вы<br />

получа<strong>е</strong>т<strong>е</strong><br />

тр<strong>е</strong>т ью ко<br />

паю дашы^<br />

Pj,empyKmype<br />

карру, которая<br />

получа<strong>е</strong>т сво<strong>е</strong><br />

собств<strong>е</strong>нно<strong>е</strong>.<br />

м <strong>е</strong>ст о в clwKe.<br />

Dog sid (упакован)<br />

652 глава 14


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

с Д <strong>е</strong> н о и<br />

ъ<br />

Когда вызыва<strong>е</strong>тся м<strong>е</strong>тод, он ищ<strong>е</strong>т свои аргум<strong>е</strong>нты в ст<strong>е</strong>к<strong>е</strong>.<br />

С т<strong>е</strong> к и гр а <strong>е</strong> т важ ную роль в способ<strong>е</strong>, к о то р ы м C L R запуска<strong>е</strong>т ваш и п р о гр а м м ы . М ы п р и н и м а <strong>е</strong> м как<br />

д олж но<strong>е</strong> т о т факт, ч т о о д и н м <strong>е</strong>тод м о ж <strong>е</strong> т вы зы вать д р уго й и дал<strong>е</strong><strong>е</strong> п о ц <strong>е</strong> п о чк<strong>е</strong> . М <strong>е</strong> то д м о ж <strong>е</strong> т даж<strong>е</strong><br />

вы зы вать сам с<strong>е</strong>бя (это назы ва<strong>е</strong>тся р<strong>е</strong>курсия). Э ту в о зм о ж н о сть м ы им <strong>е</strong><strong>е</strong>т благодаря ст<strong>е</strong>ку.<br />

В о т пара м <strong>е</strong>тодов из сим улятора<br />

собачь<strong>е</strong>го п и то м н и к а . О н и<br />

п р о с ты : м <strong>е</strong>тод F e e d D o g O в ы ­<br />

зы ва<strong>е</strong>т м <strong>е</strong>тод E a t (), к о т о р ы й<br />

в свою оч<strong>е</strong>р<strong>е</strong>дь вы зы ва<strong>е</strong>т м<strong>е</strong>тод<br />

C h e c k B o w l ().<br />

Н а п ом ним<br />

p u b l i c v o i d F e e d D o g ( C a n in e d o g T o F e e d , B o w l d o g B o w l) {<br />

d o u b le e a t e n = E a t ( d o g T o F e e d . M e a l S iz e , d o g B o w l) ;<br />

r e t u r n e a t e n + , 0 5 d ; / / Н <strong>е</strong> м н о г о в с <strong>е</strong> г д а р а з л и в а <strong>е</strong> т с я<br />

p u b l i c v o i d E a t ( d o u b l e m e a l S iz e , B o w l d o g B o w l) {<br />

d o g B o w l . C a p a c i t y - = m e a l S iz e ;<br />

C h e c k B o w l ( d o g B o w l . C a p a c i t y ) ;<br />

}<br />

Ш - s s F -<br />

лд<strong>е</strong>тоЭу-<br />

p u b l i c v o i d C h e c k B o w l( d o u b le c a p a c i t y ) {<br />

}<br />

i f ( c a p a c i t y < 1 2 . 5 d ) {<br />

s t r i n g m e s s a g e = "М о я м и с к а п о ч т и п у с т а ! '<br />

}<br />

C o n s o le . W r i t e L in e ( m e s s a g e ) ;<br />

В о т как вы глядит ст<strong>е</strong>к, когда м<strong>е</strong>тод<br />

F e e d D o g () вы зыва<strong>е</strong>т м<strong>е</strong>тод<br />

E a t ( ) , к о то р ы й вы зы ва<strong>е</strong>т м<strong>е</strong>тод<br />

C h e c k B o w l О , вы зы ваю щ и й м<strong>е</strong>тод<br />

C o n s o l e .W r i t e L i n e ():<br />

М<strong>е</strong>тод F e e d D o g ()<br />

им<strong>е</strong><strong>е</strong>т два парам<strong>е</strong>тра:<br />

ссылку C a n in e<br />

и ссылку Bow l. При<br />

<strong>е</strong>го вызов<strong>е</strong> в ст<strong>е</strong>к<strong>е</strong><br />

оказываются два<br />

п<strong>е</strong>р<strong>е</strong>данных <strong>е</strong>му<br />

аргум<strong>е</strong>нта.<br />

Q М<strong>е</strong>тод F e e d D o g ()<br />

долж<strong>е</strong>н п<strong>е</strong>р<strong>е</strong>дать<br />

м<strong>е</strong>тоду E a t О два<br />

аргум<strong>е</strong>нта, которы<strong>е</strong><br />

такж<strong>е</strong> оказываются<br />

в ст<strong>е</strong>к<strong>е</strong>.<br />

О По м<strong>е</strong>р<strong>е</strong> вызова<br />

м<strong>е</strong>тодов разм<strong>е</strong>р<br />

ст<strong>е</strong>ка ув<strong>е</strong>личива<strong>е</strong>тся.<br />

Посл<strong>е</strong> зав<strong>е</strong>рш<strong>е</strong>ния<br />

м<strong>е</strong>тода C o n s o l e .<br />

W r i t e L in e О <strong>е</strong>го<br />

аргум<strong>е</strong>нты удаляются<br />

из ст<strong>е</strong>ка. М<strong>е</strong>тод E a t ()<br />

продолжа<strong>е</strong>т работу,<br />

как будто нич<strong>е</strong>го н<strong>е</strong><br />

случилось. Вот как<br />

пол<strong>е</strong>з<strong>е</strong>н ст<strong>е</strong>к!<br />

дальш<strong>е</strong> ► 653


ссылки по запросу<br />

Модификатор out<br />

С ущ <strong>е</strong>ствую т различны <strong>е</strong> сп о со б ы п о л уч<strong>е</strong>ния зн а ч <strong>е</strong> н и й о т п р о гр а м м ы . О н и р<strong>е</strong>ализую<br />

тся п р и п о м о щ и д о б а вл<strong>е</strong>нны х к объя вл<strong>е</strong>нию м <strong>е</strong>тода модификаторов,<br />

в ч а с тн о с ти , м одиф и ка то р а out. В о т как о н работа<strong>е</strong>т. С оздайт<strong>е</strong> ново<strong>е</strong> п р и ­<br />

л о ж <strong>е</strong> н и <strong>е</strong> W indow s Form s и добавьт<strong>е</strong> к ф орм <strong>е</strong> пусто<strong>е</strong> объявл<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода. О ба<br />

парам <strong>е</strong>тра пом <strong>е</strong>тьт<strong>е</strong> кл ю ч <strong>е</strong>вы м словом o u t:<br />

p u b l i c i n t R e t u r n T h r e e V a l u e s (out d o u b le h a l f , out i n t t w i c e )<br />

}<br />

r e t u r n 1 ;<br />

П о п ы та в ш и с ь п о с т р о и т ь код, вы п о л учит<strong>е</strong> два со о б щ <strong>е</strong> н и я об ош и б к<strong>е</strong>: До п<strong>е</strong>р<strong>е</strong>дачи<br />

управл<strong>е</strong>ния из т<strong>е</strong>кущ<strong>е</strong>го м<strong>е</strong>тода парам<strong>е</strong>тру, пом<strong>е</strong>ч<strong>е</strong>нному ключ<strong>е</strong>вым<br />

словом out, ‘h alf должно быть присво<strong>е</strong>но знач<strong>е</strong>ни<strong>е</strong> (а н а л о ги ч н о для<br />

парам <strong>е</strong>тра ‘tw ic e ’ ). Работая с кл ю ч <strong>е</strong> вы м словом o u t , вы вс<strong>е</strong>гдад,олж<strong>е</strong>к задавать<br />

парам <strong>е</strong>тр до возвращ <strong>е</strong>ния м <strong>е</strong>тодом знач<strong>е</strong>ния. В о т как в ы гл я д и т м <strong>е</strong>тод ц <strong>е</strong>ликом:<br />

R andom ra n d o m = new R a n d o m ( ) ;<br />

Парам<strong>е</strong>тр out<br />

да<strong>е</strong>т м<strong>е</strong>тоду<br />

возможность<br />

в<strong>е</strong>рнуть бол<strong>е</strong><strong>е</strong><br />

одного<br />

знач<strong>е</strong>ния.<br />

p u b l i c i n t R e t u r n T h r e e V a lu e s ( o u t d o u b le h a l f , o u t i n t t w ic e ) {<br />

i n t v a lu e = r a n d o m .N e x t( 1 0 0 0 ) ;<br />

}<br />

h a l f = ( ( d o u b le ) v a lu e ) / 2 ;<br />

t w ic e - v a lu e * 2 ;<br />

r e t u r n v a lu e ;<br />

Пt арам <strong>е</strong>т рам Ul/V\J , e пом<strong>е</strong>ч<strong>е</strong>нным ГЧ./V ключ<strong>е</strong>вым<br />

r V /C - U C « '! /V i<br />

/ 'Д Л К Л Д Л ^ f .-i- --Ч ^ ..........<br />

словом out. нужно заран<strong>е</strong><strong>е</strong> присвоит ь<br />

знач<strong>е</strong>ния, инач<strong>е</strong> код компилироват ься<br />

н<strong>е</strong> буд<strong>е</strong>т. ^<br />

В оспользу<strong>е</strong>м ся заданны м и парам <strong>е</strong>трам и. Д обавьт<strong>е</strong> к н о п к у со сл<strong>е</strong>дую щ им о б р а б о тч и ко м со б ы тий:<br />

p r i v a t e v o i d b u t t o n l _ C l i c k ( o b j e c t s e n d e r , E v e n tA r g s e ) {<br />

d o u b le b ;<br />

i n t c ;<br />

a = R e t u r n T h r e e V a lu e s ( b , c)<br />

C o n s o le . W r it e L in e ( " v a l u e = {0}, h a l f = { 1 } , d o u b le = {2}",<br />

b , c ) ;<br />

О и ! С нова о ш и б к и п о стр о <strong>е</strong> н и я ; Аргум<strong>е</strong>нт 1 д о л ж <strong>е</strong> н быть п<strong>е</strong>р<strong>е</strong>дан с к л ю ч <strong>е</strong> в ы м словом out. В п р о ц <strong>е</strong> с­<br />

с<strong>е</strong> вы зова м <strong>е</strong>тода с парам <strong>е</strong>тром o u t н у ж н о исп ользовать это клю ч<strong>е</strong>во<strong>е</strong> слово п р и п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> <strong>е</strong>му аргум<strong>е</strong>нта.<br />

В о т ка к э то д о л ж н о вы гляд<strong>е</strong>ть:<br />

^ ^ j<br />

а = R e t u r n T h r e e V a lu e s (out b , out с ) ;<br />

Т <strong>е</strong>п<strong>е</strong>рь п р о гр а м м у м о ж н о п о с т р о и т ь и запустить. М <strong>е</strong> то д R e tu r n T h r e e V a lu e s () зада<strong>е</strong>т и возвращ а<strong>е</strong>т<br />

т р и знач<strong>е</strong>ния: а получа<strong>е</strong>т возвращ а<strong>е</strong>м о<strong>е</strong> зн ач<strong>е</strong>ни<strong>е</strong> м<strong>е</strong>тода, Ь - знач<strong>е</strong>ни<strong>е</strong>, возвращ а<strong>е</strong>мо<strong>е</strong> парам <strong>е</strong>тром<br />

h a l f , а с - знач<strong>е</strong>ни<strong>е</strong>, возвращ а<strong>е</strong>мо<strong>е</strong> парам <strong>е</strong>тром t w i c e . ^<br />

654 глава 14


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Модификатор ref<br />

Вам снова и снова п р и д <strong>е</strong> тся сталкиваться с т<strong>е</strong>м , ч т о п р и п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> м <strong>е</strong>тоду з н а ч <strong>е</strong> н и й т и п а<br />

i n t , d o u b l e , s t r u c t и л и д р уго го зн а ч и м о го т и п а вы ф а кти ч <strong>е</strong> ски п<strong>е</strong>р<strong>е</strong>да<strong>е</strong>т<strong>е</strong> к о п и ю это ­<br />

го знач<strong>е</strong>ния. П р оц<strong>е</strong>дура та к и назы ва<strong>е</strong>тся; п<strong>е</strong>р<strong>е</strong>дача по знач<strong>е</strong>нию.<br />

Н о аргум <strong>е</strong>нты м о ж н о п<strong>е</strong>р<strong>е</strong>давать и м <strong>е</strong>тодом , к о т о р ы й назы ва<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>дача по ссылк<strong>е</strong>.<br />

Э то р<strong>е</strong>ализу<strong>е</strong>тся п р и п о м о щ и м одиф и ка то р а r e f . К а к и м о д и ф и ка то р o u t , о н и сп о л ь ­<br />

зу<strong>е</strong>тся п р и о б ъ я вл<strong>е</strong>нии и п р и вы зов<strong>е</strong> м<strong>е</strong>тода. З начим ом у и л и ссы л о чном у т и п у п р и н а д ­<br />

л <strong>е</strong> ж и т п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная, в данном случа<strong>е</strong> н<strong>е</strong> им <strong>е</strong><strong>е</strong>т знач<strong>е</strong>ния, поско л ь ку лю бая п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная<br />

с м одиф и ка то р о м r e f буд<strong>е</strong>т р <strong>е</strong>дактироваться н <strong>е</strong> п о ср <strong>е</strong> д ств<strong>е</strong>нно м<strong>е</strong>тодом.<br />

Д обавьт<strong>е</strong> к програм м <strong>е</strong> м<strong>е</strong>тод, ч т о б ы п о см о тр <strong>е</strong> ть, как э^о работа<strong>е</strong>т;<br />

public void ModifyAnlntAndButton(ref int value, ref Button button)<br />

}<br />

int i value;<br />

i *= 5;<br />

value = i - 3-<br />

button = buttonl;<br />

? Задавая знач<strong>е</strong>ни<strong>е</strong> и парам <strong>е</strong>т ры кнопки,<br />

м<strong>е</strong>т од м<strong>е</strong>ня<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> а и Ь<br />

в вызвавш<strong>е</strong>м <strong>е</strong>го м<strong>е</strong>тод<strong>е</strong> ЬиПопг^Сиск{).<br />

Д обавим к н о п к у с о б р а б о тчико м со б ы ти я для вы зова м<strong>е</strong>тода;<br />

В отличи<strong>е</strong> от а р ­<br />

гум <strong>е</strong>нт а, пом<strong>е</strong>ч<strong>е</strong>нного<br />

м одиф икат о­<br />

ром ref, аргум<strong>е</strong>нт ,<br />

пом<strong>е</strong>ч<strong>е</strong>нный м одиф<br />

икат ором out, н<strong>е</strong><br />

т р<strong>е</strong>бу<strong>е</strong>т инициализации<br />

п<strong>е</strong>р<strong>е</strong>д <strong>е</strong>го<br />

п<strong>е</strong>р<strong>е</strong>оач<strong>е</strong>й.<br />

private void button2_Click{object sender, EventArgs e) { быбоЭытся d? = 4^7,<br />

int q - 100;<br />

b.Text = buttonl-, так как<br />

Button b = buttons;<br />

М<strong>е</strong>тод пом<strong>е</strong>нял Знач<strong>е</strong>ния<br />

ModifyAnlntAndButton(ref q, ref b);<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нных q и b.<br />

Console.WriteLine("q = {0}, b.Text = {1}' q, b .Text);<br />

П р и вы зов<strong>е</strong> о б р а б о тчиком b u t t o n 2 _ C l i c k {) м <strong>е</strong>тода M o d i f y A n l n t A n d B u t t o n () п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нны <strong>е</strong> q и b<br />

п<strong>е</strong>р<strong>е</strong>даю тся п о ссы лк<strong>е</strong>. М <strong>е</strong> то д M o d i f y A n l n t A n d B u t t o n ( ) работа<strong>е</strong>т с н и м и , как с л ю б ы м и д р уги м и п<strong>е</strong>р<br />

<strong>е</strong> м <strong>е</strong>нны м и . Н о благодаря п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> п о ссы лк<strong>е</strong> о н вс<strong>е</strong> вр<strong>е</strong>м я о б н о вля<strong>е</strong>т э т и п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нны <strong>е</strong>, а н<strong>е</strong> п р о с то<br />

к о п и р у <strong>е</strong> т и х. П о сл <strong>е</strong> зав<strong>е</strong>рш <strong>е</strong>ния м <strong>е</strong>тода q и Ь будут им <strong>е</strong>ть о тр <strong>е</strong> д а кти р о в а н н ы <strong>е</strong> знач<strong>е</strong>ния.<br />

Запустит<strong>е</strong> р <strong>е</strong> ж и м отладки и добавьт<strong>е</strong> к п <strong>е</strong>р<strong>е</strong>м <strong>е</strong> н н ы м q и Ь ко н тр о л ь н ы <strong>е</strong> знач<strong>е</strong>ния, ч т о б ы п о н я ть , как всё<br />

работа<strong>е</strong>т.<br />

Рассмотрим парам<strong>е</strong>тр out. встро<strong>е</strong>нный в значимый тип. Иногда строку вида ’"5S.&7”<br />

нужно пр<strong>е</strong>образовать в знач<strong>е</strong>ни<strong>е</strong> типа double. Это можно сд<strong>е</strong>лать при помош,и м <strong>е</strong>­<br />

тода double.Parse("3S,(p7”). Но запись double.ParseC'xyz“) прив<strong>е</strong>д<strong>е</strong>т к исключ<strong>е</strong>нию<br />

FormatEKception. Иногда тр<strong>е</strong>бу<strong>е</strong>тся им<strong>е</strong>нно такой р<strong>е</strong>зульт ат , а иногда тр<strong>е</strong>бу<strong>е</strong>тся<br />

пров<strong>е</strong>рить возможность пр<strong>е</strong>образования строки в знач<strong>е</strong>ни<strong>е</strong>. Зд<strong>е</strong>сь вам пригодится<br />

м<strong>е</strong>тод TryParseQ: запись double.TryParse("xyz'’, out d) в<strong>е</strong>рн<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> false и присвоит<br />

парам<strong>е</strong>тру i знач<strong>е</strong>ни<strong>е</strong> Oj в то вр<strong>е</strong>мя как запись doub(e.TryParseC'3S.t>7”, out d)<br />

в<strong>е</strong>рн<strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> true и присвоит п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной d знач<strong>е</strong>ни<strong>е</strong> 35.


н<strong>е</strong>обязат<strong>е</strong>льны<strong>е</strong> аргум<strong>е</strong>нты<br />

Н<strong>е</strong>обязат<strong>е</strong>льны<strong>е</strong> парам<strong>е</strong>тры<br />

Б ы ва<strong>е</strong>т так, ч т о м<strong>е</strong>тод снова и снова вы зы ва<strong>е</strong>тся с о д н и м и и т<strong>е</strong> м и ж <strong>е</strong> а ргум <strong>е</strong>нтам и, н о иногд а <strong>е</strong>му тр<strong>е</strong>бу<strong>е</strong>тся<br />

д о п о л н и т<strong>е</strong> л ь н ы й парам <strong>е</strong>тр. Н а п р и м <strong>е</strong> р , п р и н а л и ч и и зн а ч <strong>е</strong> н и й п о ум о л ч а н и ю аргум <strong>е</strong>нты указы ваю<br />

тся , <strong>е</strong>сли п р и вы зов<strong>е</strong> м <strong>е</strong>тода ч то -то пом <strong>е</strong>нялось.<br />

в та к о й с и туа ц и и вам на п о м о щ ь п р и д у т н<strong>е</strong>обязат<strong>е</strong>льны <strong>е</strong> парам <strong>е</strong>тры . В о б ъ я вл<strong>е</strong>нии м<strong>е</strong>тода за та ки м и<br />

парам <strong>е</strong>трам и сл<strong>е</strong>ду<strong>е</strong>т знак рав<strong>е</strong>нства и зн а ч<strong>е</strong>ни<strong>е</strong> п о ум о л чанию . К о л и ч <strong>е</strong> с тв о н <strong>е</strong>обяза т<strong>е</strong> л ьны х парам<strong>е</strong>т<br />

р о в м о ж <strong>е</strong> т б ы ть произвольн ы м .<br />

В о т п р и м <strong>е</strong> р м<strong>е</strong>тода, в к о то р о м с п о м о щ ь ю н<strong>е</strong>обяза т<strong>е</strong> льны х парам <strong>е</strong>тров пров<strong>е</strong>ря<strong>е</strong>тся, н <strong>е</strong> т л и у ч<strong>е</strong>лов<strong>е</strong>ка<br />

в ы с о к о й т<strong>е</strong>м п<strong>е</strong>ратуры :<br />

v o i d C h e c k T e m p e r a t u r e ( d o u b le t e m p e r a t u r e , d o u b le t o o H i g h = 99.5, d o u b le to o L o w = 96.5)<br />

i f ( t e m p e r a t u r e < t o o H i g h && t e m p e r a t u r e > to o L o w )<br />

C o n s o l e . W r i t e L i n e ( " Ч у в с т в у ю с <strong>е</strong> б я х о р о ш о ! " ) ;<br />

e l s e<br />

}<br />

C o n s o l e . W r i t e L i n e (" О й - о й ! В ы з о в и т <strong>е</strong> в р а ч а ! " ) ; I<br />

Н <strong>е</strong> о б я за т<strong>е</strong> л ьны й парам <strong>е</strong>тр t o o H i g h им <strong>е</strong><strong>е</strong>т зн ач<strong>е</strong>ни<strong>е</strong> п о ум о л ч а н и ю 99.5, а н<strong>е</strong>обязат<strong>е</strong>льны й парам <strong>е</strong>тр<br />

t o o L o w - зн ач<strong>е</strong>ни<strong>е</strong> п о ум о л ч а н и ю 96.5. П р и вы зов<strong>е</strong> м <strong>е</strong>тода C h e c k T e m p e r a t u r e () с о д ним аргум <strong>е</strong>нтом<br />

для п арам <strong>е</strong>тров t o o H i g h и t o o L o w использую тся и м <strong>е</strong> н н о э т и знач<strong>е</strong>ния. Е сли ж <strong>е</strong> в вы зов<strong>е</strong> м <strong>е</strong>тода указать<br />

два аргум <strong>е</strong>нта, в то р о й аргум <strong>е</strong> нт буд<strong>е</strong>т п р и с в о <strong>е</strong> н п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й tooHigh, в т о вр<strong>е</strong>м я как п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная<br />

t o o L o w остан<strong>е</strong>тся с заданны м п о ум о л ч а н и ю знач<strong>е</strong>ни<strong>е</strong>м . Е сли ж <strong>е</strong> указать т р и аргум <strong>е</strong>нта, и х знач<strong>е</strong>ния<br />

будут п<strong>е</strong>р<strong>е</strong>даны вс<strong>е</strong>м тр <strong>е</strong>м парам <strong>е</strong>трам .<br />

Д ля п<strong>е</strong>р<strong>е</strong>дачи знач<strong>е</strong>ния опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нном у парам <strong>е</strong>тру сущ <strong>е</strong>ству<strong>е</strong>т и такая ф ун кц и я , ка к и м <strong>е</strong> н о в а н н ы <strong>е</strong> а р гу ­<br />

м <strong>е</strong> н т ы . Д о с та то ч н о п р и с в о и т ь парам <strong>е</strong>тру им я, указав ч<strong>е</strong>р<strong>е</strong>з д в о <strong>е</strong> то ч и <strong>е</strong> <strong>е</strong>го знач<strong>е</strong>ния.<br />

Д обавим к ф орм <strong>е</strong> м <strong>е</strong>тод C h e c k T e m p e r a t u r e () и к н о п к у со сл<strong>е</strong>дую щ им о б р а б о тчико м со б ы ти я . В оспользуйт<strong>е</strong>сь<br />

п р о ц <strong>е</strong> д ур о й отладки, ч т о б ы п о н я ть , ка к вс<strong>е</strong> это работа<strong>е</strong>т:<br />

p r i v a t e v o i d b u t t o n 3 _ C l i c k ( o b j e c t s e n d e r , E v e n t A r g s e) Для м<strong>е</strong>тодов<br />

{<br />

/ / Т а к о в а т <strong>е</strong> м п <strong>е</strong> р а т у р а с р <strong>е</strong> д н <strong>е</strong> с т а т и с т и ч <strong>е</strong> с к о г о ч <strong>е</strong> л о в <strong>е</strong> к а С О З Н Я . Ч С Н И Я ] У в И<br />

C h e c k T e m p e r a t u r e ( 1 0 1 . 3 ) ;<br />

ПОумолчанию<br />

/ / Т <strong>е</strong> м п <strong>е</strong> р а т у р а с о б а к и д о л ж н а б ы т ь м <strong>е</strong> ж д у 1 0 0 . 5 и 1 0 2 . 5 п о Ф а р <strong>е</strong> н г <strong>е</strong> й т у „ « „ л<br />

C h e c k T e m p e r a tu r e ( 1 0 1 . 3 , 1 0 2 . 5 , 1 0 0 . 5 ) ; l l C l I U J l b o y i l “<br />

/ / У Б о б а в с <strong>е</strong> г д а с л и ш ко м н и з к а я т <strong>е</strong> м п <strong>е</strong> р а т у р а , п о э т о м у п р и с в о и м Н в О б Я З Я “<br />

/ / п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й to o L o w з н а ч <strong>е</strong> н и <strong>е</strong> 9 5 .5<br />

C h e c k T e m p e r a t u r e ( 9 6 . 2 , to 6 L o w : 9 5 . 5 ) ; т<strong>е</strong>льны<strong>е</strong> паф<br />

^ рам<strong>е</strong>тры и<br />

им<strong>е</strong>нованны<strong>е</strong><br />

656 ..а..» аргум<strong>е</strong>нты.


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Типы, gonyckaiouiue знач<strong>е</strong>ни<strong>е</strong> null<br />

H a м и н уту в<strong>е</strong>рн<strong>е</strong>м ся к карточкам с к о н т а к т н о й и н ф о р м а ц и <strong>е</strong> й , к о то р ы <strong>е</strong> в<br />

глав<strong>е</strong> 1 стали о с н о в о й для базы д а н н ы х. П о м н и т<strong>е</strong> , ка ким образом в ы б и р а ­<br />

лись парам <strong>е</strong> тры та б л и ц ы , ч т о б ы п о зволить п р и с в о <strong>е</strong> н и <strong>е</strong> в каж дом столбц<strong>е</strong><br />

знач<strong>е</strong>ния n u ll на случай, <strong>е</strong>сли и н ф о р м а ц и я н<strong>е</strong> буд<strong>е</strong>т вв<strong>е</strong>д<strong>е</strong>на и л и буд<strong>е</strong>т<br />

вв<strong>е</strong>д<strong>е</strong>на н <strong>е</strong> к о р р <strong>е</strong> к тн о . К сож ал<strong>е</strong>нию , структурам и другим значим ы м типам<br />

н<strong>е</strong>возм ож но п р и своить знач<strong>е</strong>ни<strong>е</strong> n u ll. В о т таки<strong>е</strong> оп<strong>е</strong>раторы .<br />

bool myBool = null;<br />

DateTime myDate = null;<br />

на ста д и и к о м п и л я ц и и ста н ут п р и ч и н о й со о б щ <strong>е</strong> н и я об ош и б к<strong>е</strong> !<br />

П р <strong>е</strong> д п о л о ж и м , вам н уж н ы <strong>е</strong> д анны <strong>е</strong> о дат<strong>е</strong> и вр<strong>е</strong>м <strong>е</strong>ни. Для э т о го и сп о л ь ­<br />

зу<strong>е</strong>тся п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нная DateTime. Н о ч т о д<strong>е</strong>лать, <strong>е</strong>сли <strong>е</strong>й н<strong>е</strong> во вс<strong>е</strong>х случаях<br />

тр<strong>е</strong>бу<strong>е</strong>тся п р и сваивать знач<strong>е</strong>ни<strong>е</strong>? В оспользуйт<strong>е</strong>сь ти п а м и , д о п ускаю щ и м и<br />

знач<strong>е</strong>ни<strong>е</strong> n u ll. Д о ста то ч н о п о ста в и ть знак (?) посл<strong>е</strong> указания ти п а ;<br />

bool? myNulableInt = null;<br />

Вам н<strong>е</strong> показалось<br />

странным, что даж<strong>е</strong><br />

в столбц<strong>е</strong> Client мы допустили<br />

присутстви<strong>е</strong><br />

пустых знач<strong>е</strong>ний? А в<strong>е</strong>дь<br />

ч<strong>е</strong>лов<strong>е</strong>к мож<strong>е</strong>т или быть<br />

кли<strong>е</strong>нтом или н<strong>е</strong> быть<br />

им, н<strong>е</strong> так ли? Но н<strong>е</strong>т<br />

никакой гарантии, что<br />

пол<strong>е</strong> Client заполн<strong>е</strong>но на<br />

вс<strong>е</strong>х карточках. Соотв<strong>е</strong>тств<strong>е</strong>нно,<br />

знач<strong>е</strong>ни<strong>е</strong><br />

null тр<strong>е</strong>бу<strong>е</strong>тся на случай,<br />

когда мы vwocmo н<strong>е</strong> зна<strong>е</strong>м,<br />

каки<strong>е</strong> данны<strong>е</strong> вводить.<br />

Nullable_<br />

Value: DateTime<br />

HasValue: bool<br />

GetValueOrDefault(): DateTime<br />

DateTime? myNullableDate = null;<br />

С во й ств о V a l u e указы ва<strong>е</strong>т на т и п п р о в <strong>е</strong> р я <strong>е</strong> м ы х зн а ч <strong>е</strong> н и й . К прим <strong>е</strong>ру, для<br />

D a t e T i m e ? свойство V a l u e р а вно DateTime, для i n t ? - с о о тв <strong>е</strong> тств<strong>е</strong>нно in t<br />

и т. п. С во й ств о H a s V a l u e возвращ а<strong>е</strong>т зн ач<strong>е</strong>ни<strong>е</strong> tru e , <strong>е</strong>сли парам <strong>е</strong>тр н<strong>е</strong> рав<strong>е</strong>н n u ll.<br />

З н а ч и м ы й т и п вс<strong>е</strong>гда м о ж н о пр<strong>е</strong>образовать к типу, допускаю щ <strong>е</strong>м у знач<strong>е</strong>ни<strong>е</strong> n u ll:<br />

DateTime myDate = DateTime.Now;<br />

DateTime? myNullableDate = myDate;<br />

H o о б р а тн о <strong>е</strong> пр<strong>е</strong>образовани<strong>е</strong> со провож д а<strong>е</strong>тся о п <strong>е</strong> р а ц и <strong>е</strong> й п р и в<strong>е</strong>д<strong>е</strong>ния;<br />

myDate = (DateTime) myNullableDate;<br />

Стриктура<br />

Ыи[1аЫ<strong>е</strong> позволя<strong>е</strong>т<br />

хранить как<br />

значимы<strong>е</strong> типы, так<br />

и знач<strong>е</strong>ни<strong>е</strong> п^лИ. На<br />

диаграмм<strong>е</strong> вы оиди<br />

т<strong>е</strong> м<strong>е</strong>тоды и свойства<br />

с т р у к у щ р ы<br />

ЫullableФaterlme>.<br />

Е сли свойств о H a s V a l u e им <strong>е</strong><strong>е</strong>т знач<strong>е</strong>ни<strong>е</strong> false, свойств о V a l u e вы зы ва<strong>е</strong>т и с к л ю ­<br />

ч <strong>е</strong> н и <strong>е</strong> I n v a l i d O p e r a t i o n E x c e p t i o n , ка к и о п <strong>е</strong> р а ц и я п р и в<strong>е</strong> д <strong>е</strong> н и я (в<strong>е</strong>дь она<br />

п р о и зводится с использовани<strong>е</strong>м свойства Value).<br />

Посл<strong>е</strong> добавл<strong>е</strong>ния к любому ка к ст рукт у-<br />

decimal?) компилятор<br />

ру Nulkble (Nu{lahle <br />

Д о ^ й б ь т <strong>е</strong> к п р о г р а м м <strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную<br />

м создайт<strong>е</strong> контрольно<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong>.<br />

Nullable. пом<strong>е</strong>стить<strong>е</strong><br />

прим<strong>е</strong>р пс<strong>е</strong>вдонима (alias). Нав<strong>е</strong>дит<strong>е</strong><br />

В окн<strong>е</strong> w a t c h отобразится пр<strong>е</strong>образовано в структуру System .lnt3Z:<br />

курсор на любо<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> типа mt. Оно дуа<strong>е</strong>т пр<strong>е</strong>.^^ у<br />

Struct System.Int32<br />

■Represents a 32-bit signed integer.<br />

intParseO и intrryParseO - ил<strong>е</strong>ни э т о й структуры ................. ........<br />

дальш<strong>е</strong> ► 657


почувствуй вкус над<strong>е</strong>жности<br />

Типы, допускаюи^и<strong>е</strong> знач<strong>е</strong>ни<strong>е</strong> null, уб<strong>е</strong>личиВают робастность программы<br />

П ользоват<strong>е</strong>ли п о р о й д<strong>е</strong>лаю т сумасш <strong>е</strong>дш и<strong>е</strong> в<strong>е</strong>щ и. О н и м о гут щ <strong>е</strong>лкать на к н о п к а х в А ^Ш и в ш -<br />

н <strong>е</strong> в<strong>е</strong> р н о м порядк<strong>е</strong>, вводить п о 256 проб<strong>е</strong>лов в т<strong>е</strong> ксто во <strong>е</strong> пол<strong>е</strong> и л и п р и п о м о щ и Д исп<br />

<strong>е</strong> тч <strong>е</strong> р а задач п р <strong>е</strong> р ы в а ть п рогр а м м у на с<strong>е</strong>р<strong>е</strong>дин<strong>е</strong> проц<strong>е</strong>сса записи в ф айл. В глав<strong>е</strong> 10 B%thdau\/aluf^^n/;<br />

м ы го в о р и л и о том , ч т о п р о гр а м м ы , ум <strong>е</strong>ю щ и<strong>е</strong> обрабаты вать н <strong>е</strong> к о р р <strong>е</strong> к тн ы <strong>е</strong> д а нны <strong>е</strong><br />

внимани<strong>е</strong><br />

назы ваю тся р о б а с т н ы м и (ro b u s t). У в <strong>е</strong> л и ч и ть р о б а стн о сть п р о гр а м м ы п о зволяю т ё '’ IntelliSense.<br />

и т и п ы , д опускаю щ и <strong>е</strong> зн ач<strong>е</strong>ни<strong>е</strong> n u ll. У б<strong>е</strong>дит<strong>е</strong>сь в этом сами: с о зд а й т<strong>е</strong> к о н с о л ь н о <strong>е</strong><br />

'<br />

ТТГ)ИЛГП'Ж'^‘НИ


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Б б а с с <strong>е</strong> й н <strong>е</strong><br />

Возьмит<strong>е</strong> фрагм<strong>е</strong>нты кода из басс<strong>е</strong>йна<br />

и заполнит<strong>е</strong> проб<strong>е</strong>лы. Один и<br />

тот ж<strong>е</strong> фрагм<strong>е</strong>нт мож<strong>е</strong>т использоваться<br />

н<strong>е</strong>сколько раз. В басс<strong>е</strong>йн<strong>е</strong><br />

<strong>е</strong>сть и лишни<strong>е</strong> фрагм<strong>е</strong>нты.<br />

Получит<strong>е</strong> код, выводящий<br />

на консоль запись «в<strong>е</strong>рнусь<br />

ч<strong>е</strong>р<strong>е</strong>з 20 минут» при со зд ании<br />

экз<strong>е</strong>м п л яра кл асса Faucet:<br />

p u b l i c c l a s s F a u c e t {<br />

}<br />

p u b l i c F a u c e t () {<br />

T a b le w in e = ne w T a b l e ( ) ;<br />

H in g e b o o k = ne w H i n g e ( ) ;<br />

w i n e . S e t ( b o o k ) ;<br />

b o o k . S e t ( w i n e ) ;<br />

w in e . L a m p ( 1 0 ) ;<br />

b o o k . g a r d e n . L a m p { " b a c k i n " ) ;<br />

b o o k . b u l b * = 2 ;<br />

w i n e . L a m p ( " m i n u t e s " ) ;<br />

w i n e . L a m p ( b o o k ) ;<br />

При создании объ<strong>е</strong>кта Faucet<br />

появля<strong>е</strong>тся строка:<br />

С^ а с к i n 20 m in u te s ^<br />

п о л у ч и т ь -<br />

p u b l i c T a b le {<br />

p u b l i c s t r i n g s t a i r s ;<br />

p u b l i c H in g e f l o o r ;<br />

p u b l i c v o i d S e t ( H i n g e b ) {<br />

f l o o r = b ;<br />

}<br />

p u b l i c v o i d L a m p ( o b j e c t o i l )<br />

i f ( o i l ______ i n t )<br />

___________ . b u l b = ( i n t ) o i l ;<br />

e l s e i f ( o i l ______ s t r i n g )<br />

s t a i r s = ( s t r i n g ) o i l ;<br />

e l s e i f ( o i l ______ H in g e ) {<br />

___________ v i n e = o i l ______ ,<br />

C o n s o l e . W r i t e L i n e ( v i n e . T a b l e ()<br />

p u b l i c H in g e {<br />

p u b l i c i n t b u l b ;<br />

p u b l i c T a b le g a r d e n ;<br />

+ " " + __________. b u l b + " " + s t a i r s )<br />

p u b l i c v o i d S e t ( T a b le a) {<br />

g a r d e n = a ;<br />

}<br />

p u b l i c s t r i n g T a b le 0 {<br />

}<br />

r e t u r n ___________ . s t a i r s ;<br />

Дополнит<strong>е</strong>льно<strong>е</strong> задани<strong>е</strong>;<br />

Обв<strong>е</strong>дит<strong>е</strong> строчки, в которых<br />

происходит упаковка.<br />

{<br />

Ф рагм <strong>е</strong>нты<br />

м ож но и с­<br />

пользо в ать<br />

бол<strong>е</strong><strong>е</strong> одного<br />

раза.<br />

Brush<br />

Lam p<br />

bulb<br />

Table<br />

stairs<br />

public<br />

private<br />

if<br />

class o r garden<br />

new is floor<br />

a b stract on W indow<br />

interface as D oor<br />

oop H inge<br />

stru ct<br />

string<br />

int<br />

flo at<br />

single<br />

double<br />

QrnBem Ha c. 668-<br />

дальш<strong>е</strong> >


над<strong>е</strong>жность структур<br />

Часто<br />

Какая мн<strong>е</strong> разница, что происходит<br />

в ст<strong>е</strong>к<strong>е</strong>?<br />

S Так как понимани<strong>е</strong> различий м<strong>е</strong>жду<br />

ст<strong>е</strong>ком и куч<strong>е</strong>й позволя<strong>е</strong>т корр<strong>е</strong>ктно<br />

пользоваться ссылочными и значимыми<br />

типами. Л<strong>е</strong>гко забыть, что структуры и<br />

объ<strong>е</strong>кты функционируют по-разному, в<strong>е</strong>дь<br />

оп<strong>е</strong>рация присваивания для них выглядит<br />

одинаково. Пр<strong>е</strong>дставл<strong>е</strong>ни<strong>е</strong> о том, каки<strong>е</strong><br />

проц<strong>е</strong>ссы происходят в .NET и CLR позволя<strong>е</strong>т<br />

понять, ч<strong>е</strong>м им<strong>е</strong>нно отличаются<br />

ссылочны<strong>е</strong> и значимы<strong>е</strong> типы.<br />

А зач<strong>е</strong>м нужна информация по поводу<br />

упаковки?<br />

Q ; Потому что нужно понимать, когда<br />

д<strong>е</strong>йстви<strong>е</strong> п<strong>е</strong>р<strong>е</strong>ходит в ст<strong>е</strong>к, и когда<br />

данны<strong>е</strong> начинают копироваться туда<br />

и обратно. Упаковка тр<strong>е</strong>бу<strong>е</strong>т м<strong>е</strong>ста в<br />

памяти и занима<strong>е</strong>т вр<strong>е</strong>мя. Разум<strong>е</strong><strong>е</strong>тся,<br />

вы н<strong>е</strong> зам<strong>е</strong>тит<strong>е</strong> особой разницы, <strong>е</strong>сли<br />

эта проц<strong>е</strong>дура выполня<strong>е</strong>тся р<strong>е</strong>дко. Но<br />

пр<strong>е</strong>дставьт<strong>е</strong> программу, выполняющую<br />

однотипны<strong>е</strong> д<strong>е</strong>йствия много раз в с<strong>е</strong>кунду,<br />

как это д<strong>е</strong>лал, к прим<strong>е</strong>ру, симулятор улья.<br />

Работа такой программы буд<strong>е</strong>т тр<strong>е</strong>бовать<br />

вс<strong>е</strong> больш<strong>е</strong> р<strong>е</strong>сурсов, программа буд<strong>е</strong>т<br />

зам<strong>е</strong>дляться, поэтому, нав<strong>е</strong>рно<strong>е</strong>, им<strong>е</strong><strong>е</strong>т<br />

смысл изб<strong>е</strong>гать упаковки в часто повторяющ<strong>е</strong>йся<br />

части кода.<br />

Я понял, что при оп<strong>е</strong>рации присваивания<br />

одна структурная п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная<br />

копиру<strong>е</strong>тся в другую. Но как я могу<br />

использовать эти знания?<br />

Возьми Вруку карандаш<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

B o n j^ o C b i<br />

f i ! Это помож<strong>е</strong>т вам, к прим<strong>е</strong>ру, при<br />

I нкапсуляции. Посмотрит<strong>е</strong> на уж<strong>е</strong><br />

знакомый вам код класса, опр<strong>е</strong>д<strong>е</strong>ляющ<strong>е</strong>го<br />

м<strong>е</strong>стополож<strong>е</strong>ни<strong>е</strong>:<br />

p r i v a t e P o i n t l o c a t i o n ;<br />

p u b l i c P o i n t L o c a t i o n {<br />

}<br />

g e t { r e t u r n l o c a t i o n ; )<br />

Если бы P o i n t был классом, инкапсуляция<br />

н<strong>е</strong> сработала бы. Закрытость поля<br />

l o c a t i o n н<strong>е</strong> им<strong>е</strong>ла бы знач<strong>е</strong>ния, в<strong>е</strong>дь<br />

вы создали открыто<strong>е</strong>, пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong><br />

только для чт<strong>е</strong>ния свойство, возвращающ<strong>е</strong><strong>е</strong><br />

ссылку на это пол<strong>е</strong>, то <strong>е</strong>сть дали<br />

доступ другим объ<strong>е</strong>ктам.<br />

К счастью для нас, P o i n t — это структура.<br />

И открыто<strong>е</strong> свойство L o c a t i o n<br />

возвраща<strong>е</strong>т копию п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной. Работающий<br />

с н<strong>е</strong>й объ<strong>е</strong>кт мож<strong>е</strong>т д<strong>е</strong>лать, что хоч<strong>е</strong>т<br />

— это никак н<strong>е</strong> скаж<strong>е</strong>тся на состоянии<br />

закрытого поля location.<br />

Если P o i n t — это структура, то,<br />

мож<strong>е</strong>т быть, я уж<strong>е</strong> работал и с другими<br />

структурами, сам того н<strong>е</strong> зная?<br />

; Да! При изуч<strong>е</strong>нии графики вы сталкивались<br />

со структурой R e c t a n g le .<br />

Она снабж<strong>е</strong>на пол<strong>е</strong>зными м<strong>е</strong>тодами,<br />

позволяющими указать границы области,<br />

и пров<strong>е</strong>рит, попада<strong>е</strong>т ли в них выбранная<br />

точка. Достаточно указать м<strong>е</strong>стополож<strong>е</strong>ни<strong>е</strong><br />

и разм<strong>е</strong>р структуры, и программа<br />

автоматич<strong>е</strong>ски рассчита<strong>е</strong>т <strong>е</strong><strong>е</strong> остальны<strong>е</strong><br />

парам<strong>е</strong>тры.<br />

Пр<strong>е</strong>дполагалось, что этот м<strong>е</strong>тод убь<strong>е</strong>т объ<strong>е</strong>кт<br />

Clone, но он н<strong>е</strong> работа<strong>е</strong>т Поч<strong>е</strong>му?<br />

p r i v a t e v o i d S e t C l o n e T o N u l l ( C l o n e c lo n e ) {<br />

c l o n e = n u l l ;<br />

Такж<strong>е</strong> вы сталкивались с такой пол<strong>е</strong>зной<br />

структурой как S iz e . С <strong>е</strong><strong>е</strong> помощью<br />

вы опр<strong>е</strong>д<strong>е</strong>ляли разм<strong>е</strong>р строки в м<strong>е</strong>тод<strong>е</strong><br />

M e a s u r e S t r i n g О .<br />

Как опр<strong>е</strong>д<strong>е</strong>лить, что мн<strong>е</strong> нужно в<br />

т<strong>е</strong>кущий мом<strong>е</strong>нт — класс или структура?<br />

^ ! в большинств<strong>е</strong> случа<strong>е</strong>в программисты<br />

работают с классами, потому что<br />

структуры им<strong>е</strong>ют слишком много огранич<strong>е</strong>ний.<br />

Они н<strong>е</strong> подд<strong>е</strong>рживают насл<strong>е</strong>довани<strong>е</strong>,<br />

абстракции и полиморфизм, а вы уж<strong>е</strong><br />

зна<strong>е</strong>т<strong>е</strong>, насколько важны эти в<strong>е</strong>щи при<br />

создании больших прилож<strong>е</strong>ний.<br />

Структуры ж<strong>е</strong> пол<strong>е</strong>зны при повторяющ<strong>е</strong>йся<br />

работ<strong>е</strong> с огранич<strong>е</strong>нными типами<br />

данных. Хорошим прим<strong>е</strong>ром служат<br />

прямоугольники и точки — они прим<strong>е</strong>няются<br />

только в опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нных ситуациях,<br />

зато с удивит<strong>е</strong>льной р<strong>е</strong>гулярностью. При<br />

наличии у вас н<strong>е</strong>больших групп разнородных<br />

данных, которы<strong>е</strong> тр<strong>е</strong>бу<strong>е</strong>тся сохранить<br />

в пол<strong>е</strong> или п<strong>е</strong>р<strong>е</strong>дать м<strong>е</strong>тоду в кач<strong>е</strong>ств<strong>е</strong><br />

парам<strong>е</strong>тра, скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го, им<strong>е</strong><strong>е</strong>т смысл<br />

воспользоваться структурой.<br />

Структура позволя<strong>е</strong>т<br />

улучшить инкапсуляцию<br />

класса,<br />

так как возвращающ<strong>е</strong><strong>е</strong><br />

<strong>е</strong><strong>е</strong>, пр<strong>е</strong>дназнач<strong>е</strong>нно<strong>е</strong><br />

только<br />

для чт<strong>е</strong>ния свойство,<br />

вс<strong>е</strong>гда созда<strong>е</strong>т<br />

новую копию.<br />

-- О т в<strong>е</strong>т на с. 6 6 2 .


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

Ч то осталось о т В<strong>е</strong>ликол<strong>е</strong>пного<br />

П осл <strong>е</strong> разго вора об упаковк<strong>е</strong>, в ы д о л ж н ы сообразить,<br />

поч<strong>е</strong>м у к а п и та н В <strong>е</strong> л и к о л <strong>е</strong> п н ы й п о т<strong>е</strong> р я л свою<br />

силу. В с<strong>е</strong> д<strong>е</strong>ло в то м , ч т о э то уж <strong>е</strong> н<strong>е</strong> о н , а уп ако ванная<br />

стр уктура<br />

; s tг u c t I<br />

'х<br />

сравн<strong>е</strong>ни<strong>е</strong><br />

В о з м о ж н о с т ь л<strong>е</strong>гко<br />

получать копии<br />

явля<strong>е</strong>тся большим<br />

пр<strong>е</strong>имущ<strong>е</strong>ством<br />

структур<br />

и других значимых<br />

типов.<br />

О<br />

Структуры н<strong>е</strong> насл<strong>е</strong>дуют<br />

от классов и н<strong>е</strong> р<strong>е</strong>ализуют<br />

инт<strong>е</strong>рцз<strong>е</strong>йсов<br />

И м <strong>е</strong> н н о поэто м у ка п и та н та к ослаб<strong>е</strong>л.<br />

В<strong>е</strong>дь о н больш <strong>е</strong> н<strong>е</strong> насл<strong>е</strong>ду<strong>е</strong>т н у ж н о го<br />

пов<strong>е</strong>д<strong>е</strong>ния.<br />

Структуры копируются по знач<strong>е</strong>нию<br />

Э то о д но из сам ы х б о л ь ш и х и х пр<strong>е</strong>им у-<br />

©<br />

Вы н<strong>е</strong> мож<strong>е</strong>т<strong>е</strong> создать копию<br />

объ<strong>е</strong>кт<strong>е</strong><br />

в проц<strong>е</strong>сс<strong>е</strong> о п <strong>е</strong> р а ц и и п р и св а и в а н и я<br />

вы ко п и р у<strong>е</strong> т<strong>е</strong> ссылку на ту ж<strong>е</strong> самую<br />

п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нную .<br />

Вы мож<strong>е</strong>т<strong>е</strong> пользоваться<br />

ключ<strong>е</strong>вым словом аз<br />

О б ъ <strong>е</strong> кты м огут ф ункц и о н и р о в а ть,<br />

ш;<strong>е</strong>ств, н<strong>е</strong>зам <strong>е</strong>ним ы х для инка псул я ­<br />

как и х родит<strong>е</strong> л и , т о <strong>е</strong>сть для н и х до­<br />

ц и и .<br />

пусти м п олим орф изм .


расширь это<br />

Помнит<strong>е</strong> модификатор доступа sealed из<br />

. главы 7? С <strong>е</strong>го помош,ью создаются классы,<br />

М<strong>е</strong>тоды расшир<strong>е</strong>ния<br />

н<strong>е</strong> допускающи<strong>е</strong> расшир<strong>е</strong>ния.<br />

И н о гд а тр<strong>е</strong>бу<strong>е</strong>тся р а с ш и р и ть класс, о т к о т о р о го н<strong>е</strong>возм о ж н о насл<strong>е</strong>довани<strong>е</strong> (к прим <strong>е</strong>ру, м н о ги <strong>е</strong> классы<br />

•N E T п о м <strong>е</strong> ч<strong>е</strong>ны м о д и ф икатором sealed). Н а э т о т случай в C # и м <strong>е</strong>ю тся м <strong>е</strong>тоды расшир<strong>е</strong>ния (extension<br />

methods). О н и позволяю т добавить м <strong>е</strong>тоды в сущ<strong>е</strong>ствующи<strong>е</strong> классы. Вам н у ж н о то л ь ко создать стат<br />

и ч <strong>е</strong> с к и й класс и добавить туда с т а т и с ти ч <strong>е</strong> с к и й м<strong>е</strong>тод, в кач<strong>е</strong>ств<strong>е</strong> п <strong>е</strong> р в о го парам <strong>е</strong>тра п р и н и м а ю щ и й<br />

экз<strong>е</strong>м пляр э то го класса.<br />

П р <strong>е</strong> д п о л о ж и м , у вас <strong>е</strong>сть п о м <strong>е</strong> ч <strong>е</strong> н н ы й м одиф и ка то р ом s e a le d класс O rd in a ry H u m a n :<br />

От класса OrdinaryHuman (Обычный ч<strong>е</strong>лов<strong>е</strong>к)<br />

s e a j ^ c l a s s O r d in a r y H u m a n { ^ н<strong>е</strong>возможно насл<strong>е</strong>довать^. Но что <strong>е</strong>сли<br />

добавить в н<strong>е</strong>го м<strong>е</strong>тод?<br />

p r i v a t e i n t a g e ;<br />

i n t w e i g h t ;<br />

p u b l i c O r d i n a r y H u m a n ( i n t w e i g h t ) {<br />

“ « . » e i g h t -<br />

I м о а д клт <strong>е</strong>’вогс Z t ilT s ^ при nop<br />

u b l i c v o i d G o T o W o rk O { / * код похода на работу * / } J<br />

p u b l i c v o i d P a y B i l l s O { / * код оплаты сч<strong>е</strong>тов * / } Р асш и ш т ь и<br />

' “О<br />

•Добавим м <strong>е</strong>тод р а сш и р <strong>е</strong> н и я S u p e r S o ld ie r S e r u m (С у п <strong>е</strong> р с о л д а т ); ^ Словом<br />

s t a t i c c l a s s S u p e r S o ld i e r S e r u m {<br />

p u b l i c s j ^ t i c s t r i n g B r e a k W a l l s (this OrdinaryHuman h> d o u b le w a l l D e n s i t y ) {<br />

r e t u r n (" Я с л о м а л с т <strong>е</strong> н у п л о т н о с т ь ю " + w a l l D e n s i t y + " . " ) ;<br />

П р и д обавл<strong>е</strong>нии класса S u p e r S o ld ie r S e r u m класс O rd in a ry H u m a n<br />

получа<strong>е</strong>т м <strong>е</strong>тод B r e a k W a lls , к о т о р ы й м о ж <strong>е</strong> т использоваться ф орм ой:<br />

T Z Z l l t T a & S S r r<br />

^0 т<strong>е</strong>к nop, пока у н<strong>е</strong>го<br />

доступ к классу<br />

^^^P^'^°^d.ierSerum.<br />

s t a t i c v o i d M a in ( s t r i n g [] a r g s ) ( эт о }д<strong>е</strong>лат Ы<br />

O r d in a r y H u m a n s t e v e = ne w O r d in a r y H u m a n (1 8 5 ) ; >


Часто<br />

. (Н о об это м м ы п о го в о р и м в сл<strong>е</strong>дую щ <strong>е</strong>й глав<strong>е</strong>.)<br />

дальш<strong>е</strong> У 663


лучш<strong>е</strong> быстр<strong>е</strong><strong>е</strong> сильн<strong>е</strong><strong>е</strong><br />

Расширя<strong>е</strong>м фундам<strong>е</strong>нтальный тип: string<br />

Н <strong>е</strong> о б хо д и м о сть м <strong>е</strong>нять пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong> та к о го ф ундам <strong>е</strong>нтального ти п а<br />

ка к strings в о зн и ка <strong>е</strong> т н <strong>е</strong>часто. Н о вы вполн<strong>е</strong> м ож <strong>е</strong>т<strong>е</strong> это сд<strong>е</strong>лать! Созд<br />

айт<strong>е</strong> н о в ы й п р о <strong>е</strong> к т и добавьт<strong>е</strong> к н<strong>е</strong>м у ф айл H u m a n E x t e n s i o n s .cs.<br />

О Пом<strong>е</strong>стим м<strong>е</strong>тоды расшир<strong>е</strong>ния в отд<strong>е</strong>льно<strong>е</strong> пространство им<strong>е</strong>н<br />

С о х р а н и ть р а сш и р <strong>е</strong> н и я отд <strong>е</strong>льного о т о с н о в н о го кода — хо р о ш а я ид<strong>е</strong>я. Э то<br />

п о зволит л <strong>е</strong> гко о б н а р уж и ть и х п р и н <strong>е</strong> о б хо д и м о сти :<br />

О<br />

О<br />

Нам нуж<strong>е</strong>н доступ<br />

к этому классу<br />

из других пространств<br />

им<strong>е</strong>н,<br />

поэтому используй<br />

т <strong>е</strong> м одиф икат<br />

о р public!<br />

Отд<strong>е</strong>льно<strong>е</strong> пространство им<strong>е</strong>н это хо-<br />

> роший организационный инст рум <strong>е</strong>нт .<br />

n a m e s p a c e M y E x t e n s i o n s { ^ г г ’ i ^<br />

p u b l i c s t a t i c c l a s s H u m a n E x t e n s i o n s {<br />

М<strong>е</strong>тоды расшир<strong>е</strong>ния должны н а­<br />

ходиться в статич<strong>е</strong>ском класс<strong>е</strong>.<br />

Создайт<strong>е</strong> статич<strong>е</strong>ский м<strong>е</strong>тод расшир<strong>е</strong>ния, опр<strong>е</strong>д<strong>е</strong>лит<strong>е</strong> <strong>е</strong>го п<strong>е</strong>рвый<br />

парам<strong>е</strong>тр ключ<strong>е</strong>вым словом th is и укажит<strong>е</strong>, что вы расширя<strong>е</strong>т<strong>е</strong><br />

О бъявляя м <strong>е</strong>тод р а сш и р <strong>е</strong> н и я , ука ж и т<strong>е</strong> р а сш и р я <strong>е</strong> м ы й им класс в кач<strong>е</strong>ств<strong>е</strong> п <strong>е</strong> р ­<br />

в о го парам <strong>е</strong>тра. .<br />

p u b l i c s t a t i c b o o l I s D i s t r e s s C a l l<br />

________ «г--------- - чтп г<br />

{thi7~string' S) { Х-^асс<br />

-------------- - М<strong>е</strong>тод расшир<strong>е</strong>ния такж<strong>е</strong><br />

Пом<strong>е</strong>стит<strong>е</strong> в м<strong>е</strong>тод код. оц<strong>е</strong>нивающий строку долж<strong>е</strong>н быть статич<strong>е</strong>ским.<br />

p u b l i c S t a t i c c l a s s H u m a n E x t e n s i o n s {<br />

}<br />

p u b l i c s t a t i c b o o l I s D i s t r e s s C a l l ( t h i s s t r i n g s ) {<br />

if ( s .C o n t a i n s ( " П о м о г и т <strong>е</strong> !"))<br />

r e t u r n true;<br />

^ ^<br />

ЗЭ<strong>е</strong>сь пров<strong>е</strong>ря<strong>е</strong>тся, н<strong>е</strong> сод<strong>е</strong>ржит<br />

r e t u r n false;<br />

ли строка опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нного знач<strong>е</strong>ния<br />

} которо<strong>е</strong> отсутст ву<strong>е</strong>т в исходном<br />

класс<strong>е</strong> string.<br />

Создайт<strong>е</strong> форму и добавьт<strong>е</strong> к н<strong>е</strong>й строку<br />

В пиш и т<strong>е</strong> в в<strong>е</strong>рхн ю ю часть кода ф орм ы строчку u s i n g M y E x t e n s i o n s ;. К ф орм<strong>е</strong> добавьт<strong>е</strong><br />

кн о п ку М ы п ров<strong>е</strong>рим д<strong>е</strong>йстви<strong>е</strong> наш <strong>е</strong>го м<strong>е</strong>тода расш ир<strong>е</strong>ния в н утр и обработчика собы тия.<br />

Т<strong>е</strong>п<strong>е</strong>рь п р и работ<strong>е</strong> с классом strin g вы получит<strong>е</strong> доступ к м<strong>е</strong>тоду расш ир<strong>е</strong>ния. Вв<strong>е</strong>дит<strong>е</strong> им я<br />

строковой п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>нной и п<strong>е</strong>риод и уб<strong>е</strong>дит<strong>е</strong>сь сами:<br />

664<br />

s t r i n g m e s s a g e = " К л о н ы р а з р у ш а ю т ф а б р и к у . П о м о г и т <strong>е</strong> ! " ;<br />

m e s s a g e .<br />

Сразу посл<strong>е</strong> ввода ^<br />

точки появится окно<br />

с п<strong>е</strong>р<strong>е</strong>чн<strong>е</strong>м м<strong>е</strong>тодов<br />

класса string... в их<br />

число включ<strong>е</strong>н и ваш -^<br />

м<strong>е</strong>тод расшир<strong>е</strong>ния.<br />

глава 14<br />

Ф IndexOf<br />

Ф IndexOfAny<br />

Insert<br />

% lo te rs e c to<br />

• % d Z = l<br />

Ф bN orm alired<br />

^ 4 )oin<br />

% l a s t o<br />

LastlndexOf<br />

LastlndexOfAny<br />

^ 4 L astO rD efaulto<br />

Length<br />

% LongCoont< ><br />

% Мг«<br />

ч<strong>е</strong>зн<strong>е</strong>т из окна IntelliSense.<br />

Этот прим<strong>е</strong>р прод<strong>е</strong>монстрировал вам<br />

синтаксис м<strong>е</strong>тодов расшир<strong>е</strong>ния. В сл<strong>е</strong>дующ<strong>е</strong>й<br />

глав<strong>е</strong> вы получит<strong>е</strong> намного<br />

больш<strong>е</strong> информации о них. В<strong>е</strong>дь им<strong>е</strong>нно<br />

при помощи этих м<strong>е</strong>тодов р<strong>е</strong>ализован<br />

LINQ.


см<strong>е</strong>рть объ<strong>е</strong>кта<br />

^ / [ а Г н и ш ы J ^ a c m u J ’ e H u ff<br />

Расположит<strong>е</strong> магниты таким образом, чтобы на выход<strong>е</strong> получилась<br />

строка:<br />

а buck begets more bucks (д<strong>е</strong>ньги к д<strong>е</strong>ньгам)<br />

namespace Upside {<br />

using Upside;<br />

namespace Sideways {<br />

public static class Margin { |<br />

public static void Sendit<br />

)<br />

class Program {<br />

□<br />

public static string ToPrice<br />

□<br />

public static string Green<br />

" i f I n == 1)<br />

return "a buck<br />

b .Green().Sendit();<br />

Д .Sendit0 ; J<br />

static void Main(string[] args) {<br />

strxng s = i.ToPriceO ;<br />

дальш<strong>е</strong> * 665


капитан жив!<br />

^ а Г н и ш<br />

ы ]= » а с :Ш и р *<strong>е</strong> н и я<br />

Вот как нужно было расположить магниты, чтобы получить<br />

на выход<strong>е</strong> поговорку:<br />

а buck begets more bucks<br />

Расшир<strong>е</strong>ния сод<strong>е</strong>ржатся<br />

в прост ранст в<strong>е</strong> им<strong>е</strong>н Upside.<br />

Точка входа находится б п р о ­<br />

ст ранст в<strong>е</strong> им<strong>е</strong>н Sideways.<br />

namespace Upside {<br />

p u b ^ ^ s t a t i ^ c l a s s i t e x ^ n<br />

*^ ^ u b ^ ^ ^ t a ^ ^ v ^ d S e n d ^<br />

3<br />

К ласс Margin расширя<strong>е</strong>т строку пут <strong>е</strong>м<br />

добавл<strong>е</strong>ния м<strong>е</strong>тода SendltQ, который выво -<br />

дит сод<strong>е</strong>ржимо<strong>е</strong> строки на консоль. Тип int<br />

он расширя<strong>е</strong>т при помощи м<strong>е</strong>тода ToPriceQ<br />

возвращающ<strong>е</strong>го знач<strong>е</strong>ни<strong>е</strong> а buck при рав<strong>е</strong>нств<strong>е</strong><br />

ц<strong>е</strong>лой п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной X и тог<strong>е</strong> bucks в остальных<br />

случаях.<br />

Точка входа использу<strong>е</strong>т<br />

расшир<strong>е</strong>ния, добавл<strong>е</strong>нны<strong>е</strong><br />

в класс Marqin. Margin.<br />

using Upside;<br />

namespace Sideways {<br />

class Program {<br />

I<br />

рглЬ11с static string Green (this bool b) {<br />

if (b == true)<br />

return "be"<br />

else<br />

return "gets'<br />

\<br />

Зд<strong>е</strong>сь класс Margin расширя<strong>е</strong>т<br />

бул<strong>е</strong>вы п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> пут <strong>е</strong>м доявл<strong>е</strong>ния<br />

к ним класса QreenQ-<br />

М<strong>е</strong>тод Green расширя<strong>е</strong>т<br />

класс bool — OH возбраилаem<br />

ст року be, <strong>е</strong>сли бул<strong>е</strong>вская<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная им <strong>е</strong><strong>е</strong>т<br />

»/ знач<strong>е</strong>ни<strong>е</strong> true, и get —<br />

У в случа<strong>е</strong> знач<strong>е</strong>ния false.<br />

666 глава 14


м ы ПЕРЕСТРО ИЛИ КЛАСС<br />

SUPERHERO. Н О КАК ВЕРНУТЬ<br />

КАПИТАНА НАЗАД?<br />

Я п р о а н а л и з и р о в а л а \ .<br />

КОД: ВЕЛИКОЛЕПНЫЙ \<br />

и с п о л ь з о в а л с в о ю ]<br />

См<strong>е</strong>рть — это н<strong>е</strong> кон<strong>е</strong>ц!<br />

Объ<strong>е</strong>ктвиль<br />

Статья Баки Барнса<br />

корр<strong>е</strong>спонд<strong>е</strong>нта В С Е Л Е Н Н О Й<br />

Д ~ . р „ , ц „ я „ В <strong>е</strong> л н к о л <strong>е</strong> „ „ „ „<br />

в прошо?|1Ль“"<br />

» Обмтиль.<br />

« м о к а з а л а с ь с т р а „ „ а ^ Т „ “ а ^ <br />

<strong>е</strong>кта C aptain А ш а " in g - Д Н К с б .-<br />

ДВОИЧНОМ формат<strong>е</strong>.<br />

** знач<strong>е</strong>ния, записанны<strong>е</strong> в<br />

источник<strong>е</strong> “ "Р ” ' °


р<strong>е</strong>ш<strong>е</strong>ни<strong>е</strong> р<strong>е</strong>буса<br />

і^<strong>е</strong>їИ<strong>е</strong>ни<strong>е</strong> р*<strong>е</strong>^са Б ёаос<strong>е</strong>йн<strong>е</strong><br />

p u b l i c Struct T a b le {<br />

p u b l i c s t r i n g s t a i r s ;<br />

p u b l i c H in g e f l o o r ;<br />

p u b l i c v o i d S e t ( H i n g e b ) {<br />

м . » » г и т ) » 0 ^ г « ' - / » п р Г в “« о в Ж<br />

м п<strong>е</strong>р<strong>е</strong>т ннт ^1м и^ ■ f ^ к й ч <strong>е</strong> стб <strong>е</strong> п я -<br />

цглочисл<strong>е</strong>ннои<br />

g ^од<strong>е</strong> Bulb ссыл-<br />

“*Т*”<br />

Р<strong>е</strong>зультат посл<strong>е</strong> создания<br />

объ<strong>е</strong>кта Faucet:<br />

b a c k i n 20 m in u te s<br />

p u b l i c c l a s s F a u c e t {<br />

p u b l i c F a u c e t 0 {<br />

T a b le w in e = new T a b l e { ) ;<br />

H in g e b o o k = ne w H i n g e ( ) ;<br />

w i n e . S e t ( b o o k ) ;<br />

b o o k . S e t ( w i n e ) ;<br />

V w i n e . Lam p П ;<br />

C^^^ o o k . g a r d e n . L a m p ( " b a c k ir? ^ T T ~ -^<br />

b o o k . b u l b * = 2 ;<br />

(wine . L a m p ( " m i n u t e s ^ p ;<br />

w i n e . L a m p ( b o o k ) ;<br />

)<br />

Bom поч<strong>е</strong>му Table - это<br />

iJP yxm ypa. Если бы это был кла-^г<br />

Ч ^°°^-^лгоі<strong>е</strong>п " ^<br />

Обв<strong>е</strong>д<strong>е</strong>ны строчки, в которых ^<br />

происходит упаковка. ^<br />

М<strong>е</strong>тод LampQ использу<strong>е</strong>т в кач<strong>е</strong>ств<strong>е</strong><br />

парам<strong>е</strong>тра ооь<strong>е</strong>кт. Значит, упаковка<br />

буд<strong>е</strong>т автоматич<strong>е</strong>ски осущ<strong>е</strong>ствляться<br />

при п<strong>е</strong>р<strong>е</strong>дач<strong>е</strong> <strong>е</strong>му знач<strong>е</strong>ний<br />

типа int или string.<br />

^<br />

}<br />

f l o o r = b ;<br />

p u b l i c v o i d L a m p ( o b j e c t o i l ) {<br />

М<strong>е</strong>тод Lamp<br />

•пом<strong>е</strong>ща<strong>е</strong>т<br />

flo o r . b u l b = ( i n t ) o i l ;<br />

»п<strong>е</strong>р<strong>е</strong>данную<br />

Ш у строку<br />

о пол<strong>е</strong> Stairs.<br />

i f ( o i l is i n t )<br />

e l s e i f ( o i l j s . s t r i n g )<br />

s t a i r s =<br />

( s t r i n g ) о И ;"^<br />

e l s e i f ( o i l is H in g e ) {<br />

}<br />

Hinge v i n e = o i l as Hinoe;<br />

C o n s o l e . W r i t e L i n e ( v i n e . T a b l e ()<br />

" " • + flo o r -b u l b + " " + s t a i r s ) ;<br />

Помнит<strong>е</strong>, что<br />

ключ<strong>е</strong>во<strong>е</strong> слово as<br />

работа<strong>е</strong>т только<br />

с классами?<br />

І<br />

J<br />

Класс Hinge<br />

и структура Table<br />

обладают м <strong>е</strong>т о­<br />

дом SetQ. В класс<strong>е</strong><br />

p u b l i c class H in g e {<br />

, , . ^ Hinae этот r e ­<br />

p u b l i c i n t b u l b ;<br />

mod зада<strong>е</strong>т пол<strong>е</strong><br />

p u b l i c T a b le g a r d e n ; j [ т урьГт М <strong>е</strong>.^ А у<br />

p u b l r c v o r d s e t ( T a b le a"; ( Т <strong>е</strong> ^ ^ Т з Ш ^ ^ Г<br />

g a r d e n = a ;<br />

F^00r в класс<strong>е</strong><br />

Hinge.<br />

}<br />

p u b l i c s t r i n g T a b le 0 {<br />

}<br />

r e t u r n g a rd e n .s t a i r s ;<br />

668 глава 14


^5LINQ<br />

Управля<strong>е</strong>м данными<br />

Этот мир управля<strong>е</strong>тся данными...<br />

вам лучш<strong>е</strong> знать, как в н<strong>е</strong>м жить.<br />

Вр<strong>е</strong>м<strong>е</strong>на, когда можно б ы ло программировать днями и даж <strong>е</strong> н<strong>е</strong>д<strong>е</strong>лями, н<strong>е</strong><br />

касаясь множ<strong>е</strong>ства данных, давно позади. В наш и дни с данными связано<br />

вс<strong>е</strong>. Ч асто приходится работать с данны м и из разны х источников и даж<strong>е</strong> разных<br />

форматов. Базы данных, X M L, колл<strong>е</strong>кции из других программ... вс<strong>е</strong> это<br />

давно стало частью работы программиста на С#. В этом <strong>е</strong>му помога<strong>е</strong>т LIN Q .<br />

Э та функция н<strong>е</strong> только упрощ а<strong>е</strong>т запросы, но и ум<strong>е</strong><strong>е</strong>т разбивать данны<strong>е</strong> на<br />

группы и, наоборот, со<strong>е</strong>динять данны<strong>е</strong> из различных источников.


дьявол в д<strong>е</strong>талях<br />

Простой про<strong>е</strong>кт...<br />

О бъ <strong>е</strong>ктвильская ко м п а н и я п о производству бум аги р<strong>е</strong>ш и ла сд<strong>е</strong>лать совм <strong>е</strong>стную<br />

п р о м о -а кц и ю с ко ф <strong>е</strong> й н ы м м агазином . Э то т м агазин им <strong>е</strong><strong>е</strong>т сп <strong>е</strong>циальн ую программу,<br />

о тсл <strong>е</strong>ж иваю щ ую , ка кой коф <strong>е</strong> п окуп а <strong>е</strong>т ка ж д ы й к л и <strong>е</strong> н т и как часто о н это д<strong>е</strong>ла<strong>е</strong>т.<br />

Б ум аж ная ко м п а н и я хот<strong>е</strong>ла бы узнать, кто из <strong>е</strong><strong>е</strong> кли<strong>е</strong>нтов р<strong>е</strong>гулярно пос<strong>е</strong>ща<strong>е</strong>т коф<br />

<strong>е</strong> й н ы й магазин, ч т о б ы о тп р а в и ть и м б <strong>е</strong>сплатную круж ку и куп о н на п о куп ку и х<br />

л ю б и м о го коф <strong>е</strong>... Вам н у ж н о ско м б и н и р о в а ть д а нны <strong>е</strong> и создать с п и с о к к л и <strong>е</strong> н то в<br />

для р ассы л ки круж <strong>е</strong> к и купонов.<br />

Кли<strong>е</strong>нты бумажной компании,<br />

р<strong>е</strong>гулярно пос<strong>е</strong>щающи<strong>е</strong> коф<strong>е</strong>йный<br />

магазин, получат б<strong>е</strong>сплатную кружку<br />

Скажит<strong>е</strong> только, кому разослать эти<br />

кружки и каки<strong>е</strong> сорта коф<strong>е</strong> эти люди<br />

пр<strong>е</strong>дпочитают.<br />

670 глава 15


UNQ<br />

...НО сначала ну)кно собрать данны<strong>е</strong><br />

К о ф <strong>е</strong> й н ы й м агазин S tarbuzz х р а н и т д анны <strong>е</strong> в классах, с гр у п п и р о в а н н ы х в б о л ь ш о й с п и с о к List. А в о т<br />

бумажная ко м п а н и я им <strong>е</strong><strong>е</strong>т базу д а н н ы х (созд анную в глав<strong>е</strong> 1). Н у ж н о н а й т и п о с<strong>е</strong> ти т<strong>е</strong> л <strong>е</strong> й м агазина, п о ­<br />

т р а т и в ш и х бол<strong>е</strong><strong>е</strong> $90, с р а в н и ть со сп и ско м к о н та к т о в бум аж ной ко м п а н и и и сф орм и ровать св о й с п и ­<br />

сок, в к о то р о м будут указаны сл<strong>е</strong>дую щ и<strong>е</strong> д анны <strong>е</strong>; имя ч<strong>е</strong>лов<strong>е</strong>ка, фирма, гд<strong>е</strong> он работа<strong>е</strong>т, <strong>е</strong>го любимый<br />

сорт коф<strong>е</strong>.<br />

Данны<strong>е</strong> магазина в колл<strong>е</strong>кции List<br />

П р о гр а м м и с ты из S tarbuzz н а п и са л и п р о ­<br />

грамму, связанную с и х сайтом , и п о м <strong>е</strong> сти л и<br />

вс<strong>е</strong> д анны <strong>е</strong> в с п и с о к L i s t < S t a r b u z z D a t a > .<br />

т<br />

Зам н у ж н о получить<br />

данны<strong>е</strong> от коф<strong>е</strong>ино<br />

го магазина и наити<br />

т ам кли<strong>е</strong>нтов, к о ­<br />

торы<strong>е</strong> т а к ж <strong>е</strong> пользу -<br />

ют ся услугам и б у ­<br />

мажной компании.<br />

Это класс м<br />

»^.<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>нм<strong>е</strong> из<br />

1л.йогрйММК>| ко<br />

ф<strong>е</strong>-йного м агази ­<br />

на Starbuzx-<br />

c la s s S ta r b u z z D a ta<br />

{<br />

p u b l i c s t r i n g Name { g e t ; s e t ; }<br />

p u b l i c D r in k F a v o r i t e D r i n k { g e t ;<br />

p u b l i c i n t M o n e y S p e n t { g e t ; s e t ;<br />

p u b l i c i n t V i s i t s { g e t ; s e t ; }<br />

enum D r in k {<br />

B o r in g C o f f e e ,<br />

C h o c o R o c k o L a tte ,<br />

T r ip le E s p r e s s o ,<br />

Z e s ty L e m o n C h a i,<br />

D o u b le C a p p u c c in o ,<br />

H a lf C a fA m e r ic a n o ,<br />

C h o c o M a c c h ia to ,<br />

B a n a n a S p litln A C u p ,<br />

}<br />

—<br />

s e t ; }<br />

}<br />

У вас уж<strong>е</strong> <strong>е</strong>сть данны<strong>е</strong> о заказчиках<br />

С п и с о к ко н та к т о в для о б ъ <strong>е</strong> ктв и л ь ско й бум а ж ной ком ­<br />

п а н и и вы создали <strong>е</strong>щ <strong>е</strong> в глав<strong>е</strong> 1, о н со д <strong>е</strong> р ж и т часть<br />

н у ж н ы х д анны х.<br />

ШТУРМ<br />

База данных<br />

ContactDB<br />

Вс<strong>е</strong> данны<strong>е</strong> о кли<strong>е</strong>нтах фирмы<br />

по і^ оизводст ву бумаги вы<br />

найд<strong>е</strong>т<strong>е</strong> в баз<strong>е</strong>.<br />

Как бы вы скомбинировали данны <strong>е</strong><br />

от двух организаций для получ<strong>е</strong>ния<br />

<strong>е</strong>диного списка контактов?<br />

дальш<strong>е</strong> ► 671


UNQ для спас<strong>е</strong>ния<br />

Сбор данных из разных источников<br />

Вас спас<strong>е</strong>т L IN Q ! Э та аббр<strong>е</strong>виатура р а сш и ф р овы ва<strong>е</strong>тся как<br />

L a nguage In te g ra te d Q u e ry (В с т р о <strong>е</strong> н н ы й я зы к запросов). В ы уж<strong>е</strong><br />

исп ользовали эту т<strong>е</strong> х н о л о ги ю в сим улятор<strong>е</strong> улья для о тсл <strong>е</strong> ж иван<br />

и я за н я ти й гр у п п пч<strong>е</strong>л. П р о с ты <strong>е</strong> за просы пр<strong>е</strong>доставлял и вам<br />

д анны <strong>е</strong> из ко л л <strong>е</strong> кц и и . .А налогичны м способом L IN Q м о ж <strong>е</strong> т раб<br />

о тать с д а н н ы м и из к о ф <strong>е</strong> й н о го магазина. Э ту т<strong>е</strong> х н о л о ги ю м о ж ­<br />

н о п р и м <strong>е</strong> н я ть к л ю б ы м колл<strong>е</strong>кц иям , р<strong>е</strong>ализую щ им и н т<strong>е</strong> р ф <strong>е</strong> й с<br />

IE n u m e ra b le < T > .<br />

L IN Q п озволя<strong>е</strong>т работать и с наборам и ко л л <strong>е</strong> кц и й . Т<strong>е</strong> ж <strong>е</strong> самы<strong>е</strong><br />

запросы извл<strong>е</strong>кут д а нны <strong>е</strong> из базы и л и из докум <strong>е</strong>нта X M L .<br />

В глав<strong>е</strong> 1 2 вы во<strong>е</strong>пользовались<br />

готовым<br />

вариантом кода для<br />

ж<strong>е</strong> мы подробно рассмотрим,,<br />

как это<br />

р£^оот.а<strong>е</strong>п\.<br />

Вот запрос, при помощи<br />

которого в симулятор<br />

ульй мы группировали<br />

и сортировали пч<strong>е</strong>л.<br />

var beeGroups =<br />

from bee in world.Bees<br />

group bee by bee.Currentstate<br />

into beeGroup<br />

orderby beeGroup.Key<br />

select beeGroup;<br />

t<br />

Аналогичный запрос позволит нам<br />

получить данны<strong>е</strong> о кли<strong>е</strong>нтах из<br />

колл<strong>е</strong>кции коф<strong>е</strong>йного магазина.<br />

L IN Q р абота<strong>е</strong>т с л ю б ы м и с т о ч н и к о м д а н н ы х в .N ET. Д о ста то ч н о<br />

в ста вить в в <strong>е</strong> р х н ю ю часть ф айла с кодом с тр о ч к у u s in g S y s te m .<br />

L in q ; Бол<strong>е</strong><strong>е</strong> т о го , И С Р а в то м а ти ч<strong>е</strong>ски пом <strong>е</strong>щ а<strong>е</strong>т в в <strong>е</strong> р х н ю ю<br />

часть создава<strong>е</strong>мых ф айлов классов ссы лку на L IN Q .<br />

рдии и т<strong>е</strong> ж<strong>е</strong> запросы<br />

UNQ работают как<br />

сбаз1ми Эйнных, т а к<br />

(Д с докум<strong>е</strong>нтами X M L.<br />

672 глава 15


UNQ<br />

Колл<strong>е</strong>кции .NET y>ke настро<strong>е</strong>ны nog LINQ<br />

Вс<strong>е</strong> к о л л <strong>е</strong> кц и и .N E T р<strong>е</strong>ализую т и н т <strong>е</strong> р ф <strong>е</strong> й с I E n u m e r a b l e < T > , с<br />

к о то р ы м вы п о знако м и л и сь в глав<strong>е</strong> 8. В сп о м н и м , ка к о н ф ун кц и о ­<br />

н и р у<strong>е</strong>т: вв<strong>е</strong>дит<strong>е</strong> в код с т р о ч к у S y s t e m . C o l l e c t i o n s . G e n e r i c .<br />

I E n u m e r a b l e < i n t > , щ <strong>е</strong> л книт<strong>е</strong> на н <strong>е</strong> й п р а в о й к н о п к о й м ы ш и и вы б<strong>е</strong>р<br />

и т <strong>е</strong> ком анду G o to D e fin itio n (и л и н а ж м и т<strong>е</strong> клавиш у F I 2). В ы у в и д и т<strong>е</strong> ,<br />

ч т о и н т <strong>е</strong> р ф <strong>е</strong> й с l E n u m e r a b l e опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т м <strong>е</strong>тод G e t E n u m e r a t o r ():<br />

и н т <strong>е</strong> р ф <strong>е</strong> й с<br />

ф<strong>е</strong>йс<br />

n a m e s p a c e S y s t e m . C o l l e c t i o n s .G e n e r i c {<br />

i n t e r f a c e I E n u m e r a b l e < T > : l E n u m e r a b l e<br />

11 Р <strong>е</strong> з ю м <strong>е</strong> :<br />

/ / О с у щ <strong>е</strong> с т в л я <strong>е</strong> т п р о с т о й п <strong>е</strong> р <strong>е</strong> б о р э л <strong>е</strong> м <strong>е</strong> н т о в к о л л <strong>е</strong> к ц и и .<br />

/ /<br />

11<br />

11<br />

11<br />

В о з в р а щ а <strong>е</strong> т :<br />

S y s t e m . C o l l e c t i o n s .G e n e r i c .I E n u m e r a t o r < T > ,<br />

и п <strong>е</strong> р <strong>е</strong> б и р а <strong>е</strong> т э л <strong>е</strong> м <strong>е</strong> н т ы к о л л <strong>е</strong> к ц и и .<br />

I E n u m e r a t o r < T > G e t E n u m e r a t o r O<br />

К .<br />

М <strong>е</strong> то д тр<strong>е</strong>бу<strong>е</strong>т указать сп о со б п<strong>е</strong>р<strong>е</strong>м <strong>е</strong>щ <strong>е</strong> ния объ<strong>е</strong>кта<br />

о т о д н о го эл<strong>е</strong>м <strong>е</strong>нта ко л л <strong>е</strong> к ц и и к другому. Э то услови<strong>е</strong><br />

л ю б о го запроса L IN Q . Е сли вы м ож <strong>е</strong>т<strong>е</strong> п р о см а тр и в а ть<br />

ко л л <strong>е</strong> к ц и ю эл<strong>е</strong>м <strong>е</strong>нт за эл<strong>е</strong>м <strong>е</strong>нтом , значи т, м ож <strong>е</strong>т<strong>е</strong> и<br />

р<strong>е</strong>ализовы вать и н т<strong>е</strong> р ф <strong>е</strong> й с I E n u m e r a b l e < T > . С о о т­<br />

в <strong>е</strong> тств <strong>е</strong> н н о L IN Q в с о с т о я н и и п о сы л а ть к о л л <strong>е</strong> кц и и<br />

запросы .<br />

к о т о р ы й<br />

a o to D e U b o n .<br />

Э т о <strong>е</strong>динств<strong>е</strong>нный м <strong>е</strong>т од инт<br />

<strong>е</strong>рф <strong>е</strong>йса. Его р<strong>е</strong>ализу<strong>е</strong>т каждая<br />

колл<strong>е</strong>кция. Вы мож <strong>е</strong>т<strong>е</strong><br />

создават ь и собств<strong>е</strong>нны<strong>е</strong> o6v ^<br />

<strong>е</strong>кт ы , р<strong>е</strong>ализую щ и<strong>е</strong> инт <strong>е</strong>рф<strong>е</strong>йс<br />

IEnumerable... а зат <strong>е</strong>м Работ<br />

а т ь с ними при помощи UNQ.<br />

Для запросов, с о р т и р о в к и и о б н о в л <strong>е</strong> н и я д а н н ы х L IN Q использу<strong>е</strong>т м <strong>е</strong> т о д ы<br />

р а с ш и р <strong>е</strong> н и я . У б <strong>е</strong>дит<strong>е</strong>сь в этом сами. С оздайт<strong>е</strong> массив т и п а i n t с им <strong>е</strong>н<strong>е</strong>м<br />

linqtest, п о м <strong>е</strong> сти т<strong>е</strong> в н <strong>е</strong> го числа и вв<strong>е</strong>дит<strong>е</strong> эту стр очку:<br />

I E n u m e r a b l e < i n t > r e s u l t = f r o m i i n l i n q t e s t w h e r e i < 3 s e l e c t i ;<br />

A т<strong>е</strong> п <strong>е</strong> р ь п р <strong>е</strong> в р а ти т<strong>е</strong> B ко м м <strong>е</strong> н та р и й с тр о ч к у u s i n g S y s t e m . Linq; в загол<br />

овк<strong>е</strong> файла. Т <strong>е</strong>п<strong>е</strong>рь р <strong>е</strong> ш <strong>е</strong> н и <strong>е</strong> п о с т р о и т ь н<strong>е</strong> удастся. В<strong>е</strong>дь и м <strong>е</strong> н н о т<strong>е</strong> м <strong>е</strong>тоды ,<br />

ко то р ы <strong>е</strong> вы вы зы ва<strong>е</strong>т<strong>е</strong>, работая с L IN Q , использовались для р а с ш и р <strong>е</strong> н и я массива.<br />

а с Ц <strong>е</strong> н о й<br />

Т<strong>е</strong>п<strong>е</strong>рь вы видит<strong>е</strong>,<br />

поч<strong>е</strong>му М <strong>е</strong>т о­<br />

ды расш ир<strong>е</strong>ния, с<br />

кот орыми вы п о ­<br />

знакомились в глав<strong>е</strong><br />

14^ т ак важны...<br />

они позволят .NET<br />

(а заодно и вам)<br />

м <strong>е</strong>нят ь пов<strong>е</strong>д<strong>е</strong>ни<strong>е</strong><br />

•сущ <strong>е</strong>ст вующ их<br />

типов.<br />

дальш<strong>е</strong> > 673


просты<strong>е</strong> запросы<br />

Простой способ сд<strong>е</strong>лать запрос<br />

П <strong>е</strong> р <strong>е</strong> д вами п р и м <strong>е</strong> р с и н та ксиса L IN Q . О н в ы б и р а <strong>е</strong> т из м ассива т и п а i n t чи сл а м <strong>е</strong>ньш <strong>е</strong> 37 и располага<strong>е</strong>т<br />

и х в возрастаюш;<strong>е</strong>м порядк<strong>е</strong> . Д ля э т о го исп о л ьзую тся ч <strong>е</strong> ты р <strong>е</strong> п р <strong>е</strong> д л о ж <strong>е</strong> н и я (cla u se s), указы ваю щ и<strong>е</strong> п о ­<br />

рядок запросов, к р и т <strong>е</strong> р и и вы бора, к р и т <strong>е</strong> р и и с о р т и р о в к и и сп осо б возвращ <strong>е</strong>ния р<strong>е</strong>зультата.<br />

int[] values = new int[] {О, 12, 44, 36, 92, 54, 13,<br />

var result = from v in values<br />

Этот запрос<br />

состоит из<br />

where V < 37 < — V<br />

Т о 7 Х й : Iro m , \ o r d e r b y V ^<br />

where, orderby j<br />

и select. I<br />

select v;<br />

foreach(int i in result)<br />

Console.writ e ("{0} ", і);<br />

Console.ReadKey () ;<br />

» f I r ~<br />

8 } ;<br />

Это пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> зам<strong>е</strong>ща<strong>е</strong>т<br />

оукоу V (п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную диапазона)<br />

знач<strong>е</strong>ниями эл<strong>е</strong>М<strong>е</strong>нтоб массиба.<br />

сначала v равно о, зат<strong>е</strong>м — 1 2 ,<br />

зат<strong>е</strong>м — 4 4 , зат<strong>е</strong>м — 3 6 ... и т. д..<br />

Это пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> выбира<strong>е</strong>т<br />

вс<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нны<strong>е</strong> диапазона у,<br />

н<strong>е</strong> пр<strong>е</strong>вышающи<strong>е</strong> 37.<br />

^ат <strong>е</strong>м эти знач<strong>е</strong>ния<br />

И'^орядочиваются по<br />

возрастанию.<br />

. Пользоват<strong>е</strong>лям, знакомым с SQL,<br />

мож<strong>е</strong>т показаться странным<br />

кон<strong>е</strong>чно<strong>е</strong> полож<strong>е</strong>ни<strong>е</strong> пр<strong>е</strong>длож<strong>е</strong>ния<br />

select, но им<strong>е</strong>нно т а к о й<br />

синтаксис использу<strong>е</strong>тся в LINQ-<br />

^ .л п^но по одному<br />

Р<strong>е</strong>зультат:<br />

О 8 12 13 36<br />

Ключ<strong>е</strong>во<strong>е</strong> слово var заст авля<strong>е</strong>т ком пилят ор о п р <strong>е</strong> Э <strong>е</strong> л я т ь т и ^ ,<br />

м<strong>е</strong>нноЙ . .NBT диагност иру<strong>е</strong>т <strong>е</strong>го по т ипу локальной п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, ко<br />

т орую вы использовали для запроса UN0.<br />

В рассмат рива<strong>е</strong>м ом прим <strong>е</strong>р<strong>е</strong> при компиляции этой строки:<br />

va z result =s frcMB v in values<br />

ключ<strong>е</strong>во<strong>е</strong> слово var зам<strong>е</strong>ня<strong>е</strong>т ся на:<br />

IEnumerable<br />

И раз иж МЫ коснулись инт <strong>е</strong>рф<strong>е</strong>йсов, работающий с колл<strong>е</strong>кциям,<br />

вспомним о т ом , чт о инт <strong>е</strong>рф <strong>е</strong>йс Шпит<strong>е</strong>гаЫ<strong>е</strong> позволя<strong>е</strong>т п р о ­<br />

см ат риват ь эл<strong>е</strong>м<strong>е</strong>нт т один за другим. Ш ьш и н ст во запросов UNQ<br />

р<strong>е</strong>ализованы при помощи м<strong>е</strong>т одов, расилиряюи^их эт от инт<strong>е</strong>рф<strong>е</strong>йс.<br />

Т а к чт о ст алкиват ься с ним вам прид<strong>е</strong>тся доволшо часто.<br />

В<strong>е</strong>рнит<strong>е</strong>сь к глав<strong>е</strong> 8 для повтор<strong>е</strong>ния мат<strong>е</strong>риала о работ<strong>е</strong> инт<strong>е</strong>рф<strong>е</strong>йса 1 Е п ш а <strong>е</strong> г а Ы <strong>е</strong> < Т > .<br />

674 глава 15


UNQ<br />

САО)кны<strong>е</strong> запросы<br />

Д ж и м м и продал свою н<strong>е</strong>давно созданную ф ирм у к р уп н о м у и н в <strong>е</strong> с то р у и х о ч <strong>е</strong> т п о т р а т и т ь часть п р и б ы л и<br />

на п о куп ку сам ы х д о р о ги х ком и ксов п р о ка п и та н а В <strong>е</strong> л и ко л <strong>е</strong> п н о го , к о то р ы <strong>е</strong> то л ь ко см о ж <strong>е</strong> т н а й т и . К а­<br />

ким образом L IN Q м о ж <strong>е</strong> т п о м о ч ь <strong>е</strong>му в п о и ск<strong>е</strong> сам ы х д о р о ги х ком иксов?<br />

С сайта ф анатов В <strong>е</strong> л и ко л <strong>е</strong> п н о го Д ж и м м и скачал с п и с о к вс<strong>е</strong>х вы п уско в и п о м <strong>е</strong> сти л и х в ко л л <strong>е</strong> кц и ю<br />

L i s t < T > объ<strong>е</strong>кта Comic. Э то т объ<strong>е</strong>кт им <strong>е</strong><strong>е</strong>т два поля N a m e (Н а звани<strong>е</strong>) и I s s u e (В ы п уск).<br />

©<br />

c l a s s C o m ic {<br />

}<br />

p u b l i c s t r i n g Name { g e t ; s e t ; }<br />

p u b l i c i n t I s s u e { g e t ; s e t ; }<br />

Д ля п о с тр о <strong>е</strong> н и я каталога Д ж и м м и воспользовался и н и ц и а л а м и :<br />

p r i v a t e s t a t i c IE n u m e r a b le < C o m ic > B u i l d C a t a l o g () -----------<br />

{<br />

}<br />

r e t u r n ne w L i s t < C o m ic > {<br />

new C o m ic { Name = " J o h n n y A m e r ic a v s . t h e P i n k o " , I s s u e = 6<br />

Э т о и л >Л€,тод 5ыл цказан<br />

как статич<strong>е</strong>ский |л я т ого,<br />

чтобы <strong>е</strong>го м о ж н о оыао<br />

л<strong>е</strong>гко б м з б а т ь из м <strong>е</strong>т ода<br />

точки входа консольного<br />

прилож<strong>е</strong>ний.<br />

new C o m ic { Name = " R o c k a n d R o l l ( l i m i t e d e d i t i o n ) " , I s s u e =^ 19 } ,<br />

new C o m ic { Name = "W o m a n 's W o r k " , I s s u e = 3 6 } ,<br />

new C o m ic ( Name = " H i p p i e M a d n e s s ( m i s p r i n t e d ) " , I s s u e = 57 } ,<br />

new C o m ic { Name = " R e v e n g e o f t h e New W ave F r e a k ( d a m a g e d ) " , I s s u e = 68 } ,<br />

new C o m ic { Name = " B l a c k M o n d a y " , I s s u e = 7 4 } , ---------<br />

new C o m ic { Name = " T r i b a l T a t t o o M a d n e s s " , I s s u e = 83 } ,<br />

1<br />

new C o m ic { Name = " T h e D e a th o f a n O b j e c t " , I s s u e .= 97 } , }<br />

Выпуск Ф74- комиксов<br />

про капитана В<strong>е</strong>ликол<strong>е</strong>пного<br />

называ<strong>е</strong>тся «Black Monday».<br />

К счастью , сущ <strong>е</strong>ству<strong>е</strong>т зам <strong>е</strong>чат<strong>е</strong>льны й ка та л о г Гр<strong>е</strong>га. Д ж и м м и узнал, ч т о вы п уск #57 « H ip p ie<br />

Madness» из-за о п <strong>е</strong> ч а то к б ы л п р а к ти ч <strong>е</strong> с к и п о л н о с т ь ю у н и ч т о ж <strong>е</strong> н издат<strong>е</strong>л<strong>е</strong>м. О н об н а р уж и л р<strong>е</strong>дкую<br />

к о п и ю , н<strong>е</strong>давно п р о д а н н ую ч<strong>е</strong>р<strong>е</strong>з ката л ог Гр<strong>е</strong>га за $13,525. П о сл <strong>е</strong> д о л ги х п о и с к о в н у ж н о й и н ­<br />

ф о р м а ц и и Д ж и м м и см о г создать словарь, сопоста в л я ю щ и й ном <strong>е</strong> р вы пуска и <strong>е</strong>го ц <strong>е</strong> н у<br />

p r i v a t e s t a t i c D i c t i o n a r y < i n t ,<br />

{<br />

Э т о т<br />

синтаксис<br />

для инициализатора<br />

словар<strong>е</strong>й мы<br />

изучали в<br />

глав<strong>е</strong> 8.<br />

} ;<br />

}<br />

d e c i m a l> G e t P r i c e s O<br />

r e t u r n ne w D i c t i o n a r y < i n t , d e c i m a l> {<br />

{ 6, 36 00 M } ,<br />

{ 1 9 , 500M } ,<br />

650M } ,<br />

1 3 5 2 5 M } ,<br />

{ 6 8 , 250M } ,<br />

{ 7 4 , 75M } ,<br />

{ 8 3 , 2 5 .7 5 M } ,<br />

{ 9 7 , 3 5 .2 5 M } ,<br />

Выпуск * 5 7<br />

стоит $13,SZS.<br />

У<br />

ШТУРМ<br />

Вним ат<strong>е</strong>льно иссл<strong>е</strong>дуйт<strong>е</strong> запрос<br />

на с. 674. Как им<strong>е</strong>нно д о л ­<br />

ж<strong>е</strong>н сф орм ировать свой запрос<br />

<strong>Дж</strong>имми, чтобы найти самый<br />

дорогой выпуск комиксов?<br />

дальш<strong>е</strong> > 675


это н<strong>е</strong> sql<br />

Д н а щ о М и я sa n j> o ca<br />

П р оанализи р о вать данны <strong>е</strong>, ко то р ы <strong>е</strong> собрал Д ж и м м и , м о ж н о пут<strong>е</strong>м <strong>е</strong> д и н ств <strong>е</strong> н н о го запроса<br />

L IN Q . П р<strong>е</strong>длож <strong>е</strong> ни<strong>е</strong> w h e re указыва<strong>е</strong>т, каки<strong>е</strong> эл<strong>е</strong>м <strong>е</strong>нты ко л л <strong>е</strong> кц и и н у ж н о в кл ю ч и ть в ко н <strong>е</strong> ч ­<br />

н ы й р<strong>е</strong>зультат. П р и этом м о ж н о н<strong>е</strong> о гр а н и ч и в а ться п р о с то й о п <strong>е</strong> р а ц и <strong>е</strong> й сравн<strong>е</strong>ния, а в кл ю ч и ть<br />

лю б ы <strong>е</strong> вы р а ж <strong>е</strong> н и я из С#. Н а п р и м <strong>е</strong> р , воспользоваться словарны м пол<strong>е</strong>м v a lu e s для вклю ч<strong>е</strong>н<br />

и я в р<strong>е</strong>зультат ком и ксов, сто я щ и х д орож <strong>е</strong> $500. Зат<strong>е</strong>м получ<strong>е</strong>нная посл<strong>е</strong>доват<strong>е</strong>льность буд<strong>е</strong>т<br />

упорядоч<strong>е</strong>на п р и п о м о щ и пр<strong>е</strong>длож <strong>е</strong>ния o r d e r b y .<br />

Запрос LINQ из-<br />

^ вл<strong>е</strong>ка<strong>е</strong>т объ<strong>е</strong>кты<br />

I Comic из пр<strong>е</strong>д-<br />

IEnumerable comics = B u i l d C a t a l o g () ; лож<strong>е</strong>нного списка,<br />

^ нд основ<strong>е</strong> данных<br />

D i c t i o n a r y < i n t , de ci ma l> values = GetPrices () ;<br />

v a r mo stExpensive =<br />

fr om comic in comics<br />

• П<strong>е</strong>рвым в запрос<strong>е</strong> ид<strong>е</strong>т пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> From<br />

Ь кач<strong>е</strong>ств<strong>е</strong> источника данных оно указыва<strong>е</strong>т<br />

на колл<strong>е</strong>кцию comics, а п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нно1л диапазона<br />

присваива<strong>е</strong>т имя comic.<br />

f r o m where values [c o m i c .Issue] > 500<br />

м о ж н о UCorderby<br />

values Гc o m i c .Issue! de scending<br />

Мы взяли имя<br />

comic. select c o m i c ; 1 (, Появивш<strong>е</strong><strong>е</strong>ся в пр<strong>е</strong>длож<strong>е</strong>нии from<br />

имя comic зат<strong>е</strong>м использу<strong>е</strong>тся<br />

в пр<strong>е</strong>длож<strong>е</strong>ниях where и orderby.<br />

foreach (Comic comic in mostExpensive)<br />

C o n s o l e . W r i t e L i n e ("{0} стоиа? {l:c}<br />

Б пр<strong>е</strong>длож<strong>е</strong>ния where<br />

и orderby можно включить<br />

АЮ5ЫЕ оп<strong>е</strong>раторы С*,<br />

поэтому мы использу<strong>е</strong>м<br />

словарны<strong>е</strong> знач<strong>е</strong>ния для<br />

выбора комиксов, ц<strong>е</strong>на<br />

которых пр<strong>е</strong>выша<strong>е</strong>т $SOO.<br />

Зат<strong>е</strong>м мы сортиру<strong>е</strong>м<br />

р<strong>е</strong>зульт ат по убыванию.<br />

Запись « {1 :с }» в парам<strong>е</strong>трах<br />

м<strong>е</strong>тода WriteLine<br />

означа<strong>е</strong>т, что второй<br />

парам<strong>е</strong>тр нужно выв<strong>е</strong>сти<br />

в формат<strong>е</strong> локальной<br />

валюты.<br />

c o m i c .N a m e , v a l u e s [ c o m i c ,Is s u e ] );<br />

m o S ___u..^^ m s у Г чi,AAj?uun<br />

т о им <strong>е</strong>нно вош/о nв р<strong>е</strong>зультат ,<br />

ТпрЖ кило пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> select - запрос в<strong>е</strong>рнул<br />

набор объ<strong>е</strong>ктов Comic.<br />

Р<strong>е</strong>зультат:<br />

H i p p i e M a d n e s s ( с о п <strong>е</strong> ч а т к а м и ) с т о и т $ 1 3 , 5 2 5 . 0 0<br />

J o h n n y A m e r i c a v s . t h e P i n k o с т о и т $ 3 , 6 0 0 . 0 0<br />

W o m a n 's W o r k с т о и т $ 6 5 0 . 0 0<br />

676 глава 15


UNQ<br />

Я знаю S Q L — им<strong>е</strong>нно на н<strong>е</strong>го<br />

похожи запросы L IN Q , н<strong>е</strong> так ли?<br />

Д й ж <strong>е</strong> <strong>е</strong>сли вы нич<strong>е</strong>го н<strong>е</strong><br />

зна<strong>е</strong>т<strong>е</strong> об SQL. поводов для<br />

б<strong>е</strong>спокойства н <strong>е</strong> т — для<br />

работы с LINQ вам н<strong>е</strong><br />

поплр<strong>е</strong>бцюплся никаки<strong>е</strong> сопутствующи<strong>е</strong><br />

св<strong>е</strong>д<strong>е</strong>ния.<br />

LINQ мож<strong>е</strong>т быть и выглядит, как SQL, но работа<strong>е</strong>т<br />

он по-другому.<br />

У зн а то ко в S Q L м о ж <strong>е</strong> т в о з н и к н у ть соблазн п р о п у с ти ть главу п р о L IN Q ,<br />

р <strong>е</strong> ш и в , ч т о ту т вс<strong>е</strong> и н т у и т и в н о п о н я т н о и о ч<strong>е</strong>видно, в L IN Q и в самом<br />

д<strong>е</strong>л<strong>е</strong> и сп о л ьзую тся п оза и м ствованны <strong>е</strong> из S Q L кл ю ч <strong>е</strong> в ы <strong>е</strong> слова s e l e c t ,<br />

fr o m , w h e re , d e s c e n d in g и j o i n . Н о L IN Q п р и это м сильно отл ича<strong>е</strong>тся<br />

о т S Q L, п о это м у код, н а п и с а н н ы й в п р и в ы ч н о й вам ман<strong>е</strong>р<strong>е</strong>, скор<strong>е</strong><strong>е</strong> вс<strong>е</strong>го,<br />

н<strong>е</strong> буд<strong>е</strong>т работать о ж и д а <strong>е</strong> м ы м образом.<br />

S Q L работа<strong>е</strong>т с таблицами, а н<strong>е</strong> с п<strong>е</strong>р<strong>е</strong>числимыми объ<strong>е</strong>ктами. Т абл ицы н<strong>е</strong><br />

и м <strong>е</strong> ю т порядка. В ы п о л н я я S Q L -запрос s e l e c t , м о ж н о б ы ть ув<strong>е</strong>р<strong>е</strong>нны м ,<br />

ч т о таблица о б н о влять ся н<strong>е</strong> буд<strong>е</strong>т. S Q L снабж <strong>е</strong>н р а зл и ч н ы м и ср<strong>е</strong>дствам и<br />

об <strong>е</strong> сп <strong>е</strong> ч<strong>е</strong>ния б <strong>е</strong>зо п а сн о сти д а н н ы х, к о то р ы м в п о л н <strong>е</strong> м о ж н о дов<strong>е</strong>рять.<br />

Сущ<strong>е</strong>ствуют и други<strong>е</strong><br />

отличия UNO от<br />

мы н<strong>е</strong> буд<strong>е</strong>м<br />

вдаваться 8 подробности!<br />

Аостаточно<br />

чтобы вы поняли, что<br />

ожидать от<br />

L NQ-запросов знакомого<br />

вам пов<strong>е</strong>д<strong>е</strong>ния.<br />

Е сли р ассм о тр<strong>е</strong>ть S Q L бол<strong>е</strong><strong>е</strong> д<strong>е</strong>тально, т о <strong>е</strong>го запросы я вляю тся оп<strong>е</strong>рац<br />

и я м и над м нож <strong>е</strong> ствам и. Э то означа<strong>е</strong>т, ч т о обращ <strong>е</strong>ни<strong>е</strong> к столбцам та б л и ­<br />

ц ы н <strong>е</strong> уп о р я д о ч<strong>е</strong>но. К о л л <strong>е</strong> к ц и и ж <strong>е</strong> , п р и сво<strong>е</strong>й сп о с о б н о с ти со хранять<br />

что угодно—знач<strong>е</strong>ния, с тр уктур ы , о б ъ <strong>е</strong> кты и т. п. — и м <strong>е</strong> ю т о п р <strong>е</strong> д <strong>е</strong> л <strong>е</strong> н н ы й<br />

порядок. L IN Q позволя<strong>е</strong>т осущ <strong>е</strong>ствлять л ю б ы <strong>е</strong> о п <strong>е</strong> р а ц и и , к о то р ы <strong>е</strong> подд<br />

<strong>е</strong> р ж и в а ю т п р о и с х о д я щ и <strong>е</strong> в к о л л <strong>е</strong> к ц и и п р о ц <strong>е</strong> ссы , — вы м ож <strong>е</strong>т<strong>е</strong> даж<strong>е</strong> в ы ­<br />

зы вать м <strong>е</strong>тоды для со д <strong>е</strong>рж а щ ихся в н у тр и объ <strong>е</strong> кто в. П р о с м о т р эл<strong>е</strong>м <strong>е</strong>нт<br />

о в осущ <strong>е</strong>ствля<strong>е</strong>тся ц и к л и ч н о , т о <strong>е</strong>сть в с т р о го о п р<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нном порядк<strong>е</strong>.<br />

М о ж <strong>е</strong> т показаться, ч т о вс<strong>е</strong> э то н<strong>е</strong> им <strong>е</strong> <strong>е</strong>т о со б о го зн а ч<strong>е</strong>ния, н о <strong>е</strong>сли вы<br />

п р и в ы к л и р аботать с S Q L , н а п и санны <strong>е</strong> в а н а л о ги ч н о й м ан<strong>е</strong>р<strong>е</strong> запросы<br />

L IN Q дадут вам р<strong>е</strong>зультат, дал<strong>е</strong>кий о т о ж ида<strong>е</strong>м ого.<br />

дальш<strong>е</strong> ► 677


вот поч<strong>е</strong>му джимми любит LINQ<br />

Унив<strong>е</strong>рсальность LINQ<br />

В ы м ож <strong>е</strong>т<strong>е</strong> н<strong>е</strong> то л ь ко извл<strong>е</strong>кать отд<strong>е</strong>льны <strong>е</strong> эл<strong>е</strong>м <strong>е</strong>нт<br />

ы ко л л <strong>е</strong> кц и и , н о и р<strong>е</strong>дакти р о вать и х . С г<strong>е</strong> н <strong>е</strong> р и р о ­<br />

вав р<strong>е</strong>зультат, L IN Q п р<strong>е</strong>доставл я<strong>е</strong>т набор м<strong>е</strong>тодов<br />

для р а б о ты с н им . То <strong>е</strong>сть вы получа<strong>е</strong>т<strong>е</strong> и н стр ум <strong>е</strong> н ­<br />

т ы для управл<strong>е</strong>ния ваш и м и данны м и .<br />

Отр<strong>е</strong>дактиру<strong>е</strong>м р<strong>е</strong>зультаты запроса<br />

Д обавим в ко н <strong>е</strong> ц каж д ой с т р о к и в этом м ассив<strong>е</strong> д о п о л н и т<strong>е</strong> л ь н ую<br />

строку. В ы со зд а д и т<strong>е</strong> н а б о р м о д и ф и ц и р о в а н н ы х стр о к.<br />

s t r i n g [] s a n d w i c h e s = { " h a m a n d c h e e s e " ,<br />

v a r s a n d w i c h e s O n R y e =<br />

f r o m s a n d w i c h in s a n d w i c h e s<br />

s e l e c t s a n d w i c h + o n r y e '<br />

" t u r k e y a n d swiss'<br />

Вс<strong>е</strong> колл<strong>е</strong>кции р<strong>е</strong>ализуют инт<strong>е</strong>рф<strong>е</strong>йс<br />

IEnumerable — обратно<strong>е</strong> н<strong>е</strong>в<strong>е</strong>рно.<br />

Для принадл<strong>е</strong>жности к колл<strong>е</strong>кции<br />

нужно р<strong>е</strong>ализовывать <strong>е</strong>щ<strong>е</strong> и инт<strong>е</strong>рф<strong>е</strong>йс<br />

ICollection , то <strong>е</strong>сть м<strong>е</strong>тоды Add (),<br />

Clear( ) ,Contains( ) ,СоруТо() и Remove( ) ...<br />

Разум<strong>е</strong><strong>е</strong>тся, iCollection расширя<strong>е</strong>т<br />

1Епшп<strong>е</strong>гаЫ <strong>е</strong>. LINQ ж<strong>е</strong> работа<strong>е</strong>т с<br />

посл<strong>е</strong>доват<strong>е</strong>льностями знач<strong>е</strong>ний или объ<strong>е</strong>ктов,<br />

а н<strong>е</strong> с колл<strong>е</strong>кциями, а значит, вам тр<strong>е</strong>бу<strong>е</strong>тся<br />

объ<strong>е</strong>кт, р<strong>е</strong>ализующий 1 Е ш т<strong>е</strong> га Ы <strong>е</strong> < Т > .<br />

A d R<br />

P ^ m o w<br />

'salami w i t h m a y o " ,<br />

, " c h i c k e n c u t l e t " };<br />

f o r e a c h (var s a n d w i c h in s a n d w i c h e s O n R y e )<br />

C o n s o l e . W r i t e L i n e ( s a n d w i c h ) ;<br />

/Добавив on rye в кон<strong>е</strong>ц Р в З у Л Ь Т Э Т :<br />

каждой строки, мы<br />

положили вс<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нты<br />

^<br />

сэндвич<strong>е</strong>й на ржаной хл<strong>е</strong>б.<br />

Вычисл<strong>е</strong>ния внутри колл<strong>е</strong>кции<br />

П о м н и т<strong>е</strong> , м ы го в о р и л и , ч т о L IN Q о б <strong>е</strong>сп <strong>е</strong>чива<strong>е</strong>т ко л л <strong>е</strong> к ц и и<br />

м <strong>е</strong>тодам и расш и р<strong>е</strong>ния? Н <strong>е</strong> к о т о р ы <strong>е</strong> из н и х в<strong>е</strong>сьма п ол<strong>е</strong>зны .<br />

h a m a n d c h e e s e on r y e<br />

s a l a m i w i t h m a y o o n rye<br />

t u r k e y a n d s w i s s o n rye<br />

c h i c k e n c u t l e t o n r y e<br />

Изм<strong>е</strong>н<strong>е</strong>ния<br />

касаются<br />

р<strong>е</strong>зультатов<br />

запроса... но<br />

никак н<strong>е</strong> затрагивают<br />

эл<strong>е</strong>м<strong>е</strong>нты исходной<br />

колл<strong>е</strong>кции<br />

или базы<br />

данных.<br />

R a n d o m r a n d o m = n e w R a n d o m ();<br />

L i s t < i n t > l i s t O f N u m b e r s = n e w L i s t < i n t > ();<br />

i n t l e n g t h = r a n d o m . N e x t ( 5 0 , 1 5 0 ) ;<br />

f o r (int i = 0; i < l e n g t h ; i++)<br />

l i s t O f N u m b e r s . A d d ( r a n d o m . N e x t (100));<br />

C o n s o l e . W r i t e L i n e ("Есть {0} ч и с <strong>е</strong> л " ,<br />

l i s t O f N u m b e r s .C ou n tо ); < r<br />

C o n s o l e . W r i t e L i n e ( " С а м о <strong>е</strong> м а л <strong>е</strong> н ь к о <strong>е</strong> {0}",<br />

l i s t O f N u m b e r s .Min О ); «6----<br />

C o n s o l e . W r i t e L i n e ( " С а м о <strong>е</strong> б о л ь ш о <strong>е</strong> {0}",<br />

l i s t O f N u m b e r s .Max() ) /<br />

C o n s o l e . W r i t e L i n e ("Их с у м м а р а в н а {0}", g;<br />

l i s t O f N u m b e r s .Suni() ) ;<br />

C o n s o l e . W r i t e L i n e ( " С р <strong>е</strong> д н <strong>е</strong> <strong>е</strong> а р и ф м <strong>е</strong> т и ч <strong>е</strong> с к о <strong>е</strong> {Ог^г}<br />

l i s t O f N u m b e r s .A verage О );<br />

Ни один из этих м <strong>е</strong>т о­<br />

дов н<strong>е</strong> им<strong>е</strong><strong>е</strong>т отнош<strong>е</strong>ния<br />

к NET... вс<strong>е</strong> они опр<strong>е</strong>а<strong>е</strong>л<strong>е</strong><br />

ны в UNQ. ^<br />

Э т о вс<strong>е</strong> м<strong>е</strong>тоды<br />

ния для iBnumerab\e


Посл<strong>е</strong>доват<strong>е</strong>льностью называ<strong>е</strong>тся<br />

упорядоч<strong>е</strong>нный набор объ<strong>е</strong>ктов или<br />

знач<strong>е</strong>ний, которы<strong>е</strong> LINQ возвраща--<br />

<strong>е</strong>т в 1Епит<strong>е</strong>гаЫ<strong>е</strong>.<br />

Сохранит<strong>е</strong> р<strong>е</strong>зультат в вид<strong>е</strong> посл<strong>е</strong>доват<strong>е</strong>льности<br />

И н о гд а н у ж н о , ч т о б ы р<strong>е</strong>зультаты в ы п о л н <strong>е</strong> н и я запроса<br />

L IN Q б ы л и под руко й . В оспользу<strong>е</strong>м ся для э то го<br />

ком андой T o L i s t ( ) :<br />

v a r u n d e r S O s o r t e d =<br />

f r o m n u m b e r in l i s t O f N u m b e r s<br />

w h e r e n u m b e r < 50<br />

o r d e r b y n u m b e r d e s c e n d i n g<br />

s e l e c t n u m b e r ;<br />

f-ia этот<br />

раз числа<br />

сортируюі^ся<br />

no убыванию.<br />

L i s t < i n t > n e w L i s t = u n d e r S O s o r t e d . T o L i s t О ;<br />

Запросы LINQ н<strong>е</strong> выполняются<br />

заран<strong>е</strong><strong>е</strong>!<br />

^удып<strong>е</strong><br />

оСГ11ор*оЖНь11 Это называ<strong>е</strong>тся<br />

«отлож<strong>е</strong>нными вычисл<strong>е</strong>ниями»<br />

— сначала долж<strong>е</strong>н<br />

сработать оп<strong>е</strong>ратор, использующий<br />

р<strong>е</strong>зультаты<br />

запроса. Поэтому так важ<strong>е</strong>н<br />

м<strong>е</strong>тод ToListQ — он заставля<strong>е</strong>т<br />

LINQ н<strong>е</strong>м<strong>е</strong>дл<strong>е</strong>нно выполнить<br />

запрос.<br />

LINQ<br />

С п о м о щ ь ю м <strong>е</strong>тода Т а к <strong>е</strong> () м о ж н о<br />

сф о р м и р овать п о д м н о ж <strong>е</strong> ств о р<strong>е</strong>зультатов:<br />

■.<br />

v a r f i r s t F i v e = u n d e r S O s o r t e d . T a k e ( б ) ;<br />

L i s t < i n t > s h o r t L i s t = f i r s t F i v e . T o L is tO ;<br />

f o r e a c h (int n in s h o r t L i s t )<br />

C o n s o l e . W r i t e L i n e ( n ) ;<br />

Пос<strong>е</strong>тит<strong>е</strong> Официальную страницу 101 L IN Q Samples от Microsoft<br />

Зд<strong>е</strong>сь вы найд <strong>е</strong>т<strong>е</strong> д о п о л н и т<strong>е</strong> л ь н ы <strong>е</strong> м ат<strong>е</strong>риалы п о работ<strong>е</strong> с L IN Q :<br />

h t t p : / / m s d n 2 . m i c r o s o f t . c o m / e n - u s / v c s h a r p / a a 3 3 6 7 4 6 . a s p x<br />

Так много новых слов: from ,<br />

w here, o r d e r b y , s e le c t . . . как<br />

будто сов<strong>е</strong>рш<strong>е</strong>нно другой язык. Поч<strong>е</strong>му<br />

он так отлича<strong>е</strong>тся от С#?<br />

I; Потому что он служит другой ц<strong>е</strong>ли,<br />

ольшая часть синтаксиса <strong>C#</strong> пр<strong>е</strong>дназнач<strong>е</strong>на<br />

для выполн<strong>е</strong>ния одной н<strong>е</strong>большой<br />

оп<strong>е</strong>рации за один раз. Можно начать цикл,<br />

присвоить знач<strong>е</strong>ни<strong>е</strong> п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной, произв<strong>е</strong>сти<br />

мат<strong>е</strong>матич<strong>е</strong>ский расч<strong>е</strong>т или вызвать<br />

м<strong>е</strong>тод... вс<strong>е</strong> это будут <strong>е</strong>диничны<strong>е</strong> оп<strong>е</strong>рации.<br />

Единичный ж<strong>е</strong> запрос LINQ мож<strong>е</strong>т выполнять<br />

ц<strong>е</strong>лый ряд функций. Рассмотрим<br />

прим<strong>е</strong>р:<br />

4acm°<br />

ЧаДаБа<strong>е</strong>Мы<strong>е</strong><br />

B o I I p o C jji<br />

v a r u n d e r lO =<br />

f r o m n u m b e r i n n u m b e r A r r a y<br />

w h e r e n u m b e r < 10<br />

s e l e c t n u m b e r ;<br />

Н<strong>е</strong>смотря на кажущуюся простоту, это<br />

довольно сложный кусок кода. Подумайт<strong>е</strong>,<br />

сколько д<strong>е</strong>йствий должна сов<strong>е</strong>ршить<br />

программа для выбора из массива<br />

n u m b e r A r r a y вс<strong>е</strong>х эл<strong>е</strong>м<strong>е</strong>нтов, н<strong>е</strong><br />

пр<strong>е</strong>вышающих 10. Нужно циклич<strong>е</strong>ски<br />

просмотр<strong>е</strong>ть массив, сравнить каждый<br />

<strong>е</strong>го эл<strong>е</strong>м<strong>е</strong>нт с 10 и выв<strong>е</strong>сти р<strong>е</strong>зультат<br />

в форм<strong>е</strong>, пригодной для дальн<strong>е</strong>йш<strong>е</strong>го<br />

прим<strong>е</strong>н<strong>е</strong>ния.<br />

Им<strong>е</strong>нно поэтому LINQ выглядит так странно<br />

с точки зр<strong>е</strong>ния С#. В<strong>е</strong>дь многочисл<strong>е</strong>нным<br />

оп<strong>е</strong>рациям соотв<strong>е</strong>тству<strong>е</strong>т совс<strong>е</strong>м<br />

короткая запись.<br />

LINQ, позволя<strong>е</strong>т<br />

коротко писать<br />

оч<strong>е</strong>нь сложны<strong>е</strong><br />

запросы.<br />

дальш<strong>е</strong> > 679


н<strong>е</strong>большой обзор<br />

КЛЮЧЕВЫЕ I<br />

МОМЕНТЫ<br />

fr o m указы ва<strong>е</strong>т I E n u m e r a b l e < T > , ч т о м ы<br />

осущ <strong>е</strong>ствля<strong>е</strong>м запрос. За н и м вс<strong>е</strong>гда сл<strong>е</strong>ду<strong>е</strong>т<br />

им я п <strong>е</strong> р <strong>е</strong> м <strong>е</strong> н н о й , п о то м i n и им я в хо д н ы х<br />

д а н н ы х ( f rom v a l u e in values).<br />

w h e re в общ <strong>е</strong>м случа<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т за from. Э то<br />

пр<strong>е</strong>длож <strong>е</strong> н и <strong>е</strong> использу<strong>е</strong>т условны <strong>е</strong> оп<strong>е</strong>рат<br />

о р ы C # для ф и л ь тр а ц и и эл<strong>е</strong>м <strong>е</strong>нтов (where<br />

v a l u e < 10).<br />

o r d e r b y указы ва<strong>е</strong>т п о р я д о к с о р т и ­<br />

р о в к и р<strong>е</strong>зультата. За н и м сл<strong>е</strong>ду<strong>е</strong>т к р и ­<br />

т <strong>е</strong> р и й с о р т и р о в к и и иногд а клю ч<strong>е</strong>во<strong>е</strong><br />

слово d e s c e n d i n g ( o r d e r b y v a l u e<br />

descending).<br />

s e l e c t указыва<strong>е</strong>т, ч т о в х о д и т в к о н <strong>е</strong> ч н ы й<br />

р<strong>е</strong>зультат ( s e l e c t value).<br />

T a k e позволя<strong>е</strong>т п о л у ч и ть п<strong>е</strong>рвы <strong>е</strong> н <strong>е</strong>ско л ько<br />

р<strong>е</strong>зультатов запроса ( r esults. Т а к <strong>е</strong> (10)).<br />

Д ля каж д о й п осл<strong>е</strong>доват<strong>е</strong>льности в L IN Q<br />

сущ <strong>е</strong>ствую т и д р уги <strong>е</strong> м <strong>е</strong>тоды : M i n (), М а х (),<br />

S u m () и A v e r a g e ( ) .<br />

П р <strong>е</strong> д л о ж <strong>е</strong> н и <strong>е</strong> s e l e c t работа<strong>е</strong>т н<strong>е</strong> то л ь ко<br />

с им <strong>е</strong>н<strong>е</strong>м , созданны м в п р <strong>е</strong> д л о ж <strong>е</strong> н и и fro m .<br />

С каж <strong>е</strong>м , <strong>е</strong>сли запрос в ы б и р а <strong>е</strong> т ц <strong>е</strong> н ы из<br />

м ассива зн а ч <strong>е</strong> н и й i n t , ко то р о м у в пр<strong>е</strong>дл<br />

о ж <strong>е</strong> н и и fr o m п р и с в о и л и им я v a lu e ,<br />

стр о к у с ц <strong>е</strong>нам и м о ж н о в<strong>е</strong>рнуть так: s e l e c t<br />

S tr in g .F o r m a t( " { 0 : с } " , v a lu e .<br />

Часгро<br />


UNQ<br />

дальш<strong>е</strong> ► 681


а вы поклонник LINQ?<br />

Посл<strong>е</strong> этого<br />

оп<strong>е</strong>ратора посл<strong>е</strong>доват<strong>е</strong>льность<br />

skunks сод<strong>е</strong>ржит<br />

ч<strong>е</strong>тыр<strong>е</strong><br />

числа: 4 6 , 1 3 /<br />

Ю и 8,<br />

<strong>е</strong>Ш<strong>е</strong>ни<strong>е</strong> Задачи с МаГнищаМи<br />

Вот каким способом нужно расположить<br />

магниты для получ<strong>е</strong>ния указанного<br />

р<strong>е</strong>зультата.<br />

но ^ ^ ^ ^ o z o T a ^ o c /ltN Q w ^ ^<br />

^ks и пом<strong>е</strong>ша<strong>е</strong>м<br />

^оват <strong>е</strong>льност ^ Ь <strong>е</strong> ^гТ<br />

var weasels<br />

from sparrow in bears<br />

; a<br />

select sparrow - 1;<br />

Этот оп<strong>е</strong>ратор вычита<strong>е</strong>т i<br />

из каждого эл<strong>е</strong>м<strong>е</strong>нта посл<strong>е</strong>доват<strong>е</strong>льности<br />

bears и пом<strong>е</strong>ща<strong>е</strong>т<br />

эти эл<strong>е</strong>м<strong>е</strong>нты в посл<strong>е</strong>Ш а-<br />

т<strong>е</strong>льность weasels.<br />

4 S + I Z +


UNQ<br />

Группировка р<strong>е</strong>зультатов запроса<br />

В ы уж <strong>е</strong> зна<strong>е</strong>т<strong>е</strong>, ч т о L IN Q п озволя<strong>е</strong>т разбивать<br />

р<strong>е</strong>зультаты запроса на гр у п п ы , та к как и м <strong>е</strong> н н о<br />

это вы д<strong>е</strong>лали в сим улятор<strong>е</strong> улья. П о с м о тр и м<br />

бол<strong>е</strong><strong>е</strong> п о д р о б н о на то , как это работа<strong>е</strong>т.<br />

va r beeGroups =<br />

Н ачало запроса н и ч <strong>е</strong> м н<strong>е</strong> отл ича<strong>е</strong>тся о т д р у ги х —<br />

вы извл<strong>е</strong>ка<strong>е</strong>т<strong>е</strong> отд <strong>е</strong> л ьны х пч<strong>е</strong>л из ко л л <strong>е</strong> к ц и и<br />

w o r l d .B e e s объ<strong>е</strong>кта L i s t < B e e > .<br />

from be e in world.Bees<br />

< ^ o u p ^ e e b y b e e .Currentstate<br />

into be eGroup<br />

orderby be e G r o u p .Ke y<br />

© Сл<strong>е</strong>дую щ ая стр о ка запроса со д <strong>е</strong> р ж и т н о ­<br />

во<strong>е</strong> клю ч <strong>е</strong> во<strong>е</strong> слово group. О н о п р и к а з ы ­<br />

ва<strong>е</strong>т запросу возвращ ать группы пч<strong>е</strong>л. То<br />

<strong>е</strong>сть вм <strong>е</strong>сто о д н о й посл <strong>е</strong>доват<strong>е</strong>льности<br />

у нас буд<strong>е</strong>т ц <strong>е</strong> л ы й набор. З апись group<br />

b ee by b e e . C u rren tsta te го в о р и т, ч то<br />

пч<strong>е</strong>л н у ж н о р а зб и ть на гр у п п ы в со о тв <strong>е</strong> т­<br />

с т в и и со свойством C u r r e n t s t a t e . Н у и<br />

н а ко н <strong>е</strong> ц , м ы указыва<strong>е</strong>м им я н о в ы х гр уп п :<br />

in to beeGroup.<br />

select beeGroup;<br />

Т <strong>е</strong>п<strong>е</strong>рь н у ж н о п р и п о м о щ и кл ю ч <strong>е</strong> ­<br />

в о го слова s e l e c t указать, ка ко й<br />

р<strong>е</strong>зультат возвращ а<strong>е</strong>т запрос. В данном<br />

случа<strong>е</strong> указы ва<strong>е</strong>тся им я гр у п п ы :<br />

s e l e c t beeGroup;<br />

Т<strong>е</strong>п<strong>е</strong>рь, когда гр у п п ы го т о в ы , и м и м о ж н о<br />

управлять. Н а п р и м <strong>е</strong> р , п р и п о м о щ и пр<strong>е</strong>длож<br />

<strong>е</strong> н и я<br />

o r d e r b y у п о р я д о ч и ть и х п о знач<strong>е</strong>н<br />

и я м п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и я C u r r e n t s t a t e (Idle,<br />

F l y i n g T o F l o w e r и т. п .). С тр о ч к а orderby<br />

beeGroup. Key с о р ти р у <strong>е</strong> т посл<strong>е</strong>доват<strong>е</strong>льности<br />

п о ключу, в кач<strong>е</strong>ств<strong>е</strong> к л ю ч а в д анном случа<strong>е</strong><br />

буд<strong>е</strong>т использоваться сво й ств о C u r r e n t s t a t e .<br />

Т йк как пч<strong>е</strong>лы группировались<br />

по сосплоянию, и м <strong>е</strong> н н о <strong>е</strong>го мы<br />

укаж<strong>е</strong>м в кач<strong>е</strong>ств<strong>е</strong> ключа.<br />

j<br />

currentstate = FlyingToFlower<br />

Обратит<strong>е</strong> внимани<strong>е</strong>, что<br />

запрос возвраща<strong>е</strong>т н<strong>е</strong><br />

отд<strong>е</strong>льных пч<strong>е</strong>л, а их грцппы.<br />

дальш<strong>е</strong> ► 683


Сгруппиру<strong>е</strong>м р<strong>е</strong>зультаты Д}кимАли<br />

Д ж и м м и п окуп а <strong>е</strong> т м н о го д<strong>е</strong>ш <strong>е</strong>вы х ко м и ксо в, чуть м <strong>е</strong>ньш <strong>е</strong> к о м и ксов ср<strong>е</strong>дн<strong>е</strong>й ц <strong>е</strong> н о в о й к а т <strong>е</strong> го р и и и н<strong>е</strong>ско<br />

л ь ко д о р о ги х , и о н х о ч <strong>е</strong> т н а учиться о ц <strong>е</strong> н и в а ть свои ф инансо вы <strong>е</strong> в о з м о ж н о с ти п<strong>е</strong>р<strong>е</strong>д п о к у п к о й .<br />

О н пом <strong>е</strong>щ а<strong>е</strong>т ц <strong>е</strong> н ы из каталога Гр<strong>е</strong>га в п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и <strong>е</strong> D i c t i o n a r y < i n t , i n t > п р и п о м о щ и м <strong>е</strong>тода<br />

G e t P r i c e s О . В оспользу<strong>е</strong>м ся L IN Q , ч т о б ы разб и ть и х на т р и гр у п п ы : ко м и к с ы со сто и м о сть ю до<br />

$100, со с то и м о с ть ю о т $100 до $1,000 и к о м и к с ы , сто я щ и <strong>е</strong> д о р о ж <strong>е</strong> Ь ,0 0 0 . М ы создадим п <strong>е</strong> р <strong>е</strong> числ <strong>е</strong> н и <strong>е</strong><br />

P r i c e R a n g e , к о то р о <strong>е</strong> буд<strong>е</strong>т использоваться в кач<strong>е</strong>ств<strong>е</strong> клю ч а , и м <strong>е</strong>тод E v a l u a t e P r i c e ( ) , опр<strong>е</strong>д<strong>е</strong>ляю ­<br />

щ и й ц <strong>е</strong> н у и во звращ а ю щ и й п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и <strong>е</strong> P r i c e R a n g e .<br />

В кач<strong>е</strong>ств<strong>е</strong> ключа использу<strong>е</strong>м п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

К л ю ч о м гр у п п ы вы ступа<strong>е</strong>т н <strong>е</strong> ко <strong>е</strong> общ <strong>е</strong><strong>е</strong> свойство. Э то м о ж <strong>е</strong> т б ы ть стр о ка , ч и сло и л и<br />

даж<strong>е</strong> ссы лка на объ<strong>е</strong>кт. В наш <strong>е</strong>м случа<strong>е</strong> каждая гр уп п а , к о то р у ю возвращ а<strong>е</strong>т запрос,<br />

буд<strong>е</strong>т посл<strong>е</strong>дова т<strong>е</strong>льностью из н о м <strong>е</strong>ров вы п уско в, кл ю ч о м ж <strong>е</strong> гр у п п ы ста н <strong>е</strong> т п <strong>е</strong> р <strong>е</strong> ч и с­<br />

л<strong>е</strong>ни<strong>е</strong> P r i c e R a n g e . М <strong>е</strong> то д E v a l u a t e P r i c e {) буд<strong>е</strong>т возвращ ать это п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и <strong>е</strong> на<br />

основ<strong>е</strong> та к о го парам <strong>е</strong>тра, как ц<strong>е</strong>на:<br />

e n u m P r i c e R a n g e { C h e a p , M i d r a n g e , E x p e n s i v e }<br />

О<br />

s t a t i c P r ic e R a n g e E v a l u a t e P r i c e ( d e c i m a l p r i c e ) {<br />

}<br />

i f ( p r i c e < lOOM) r e t u r n P r ic e R a n g e . C h e a p ;<br />

e l s e i f ( p r i c e < lOOOM) r e t u r n P r ic e R a n g e . M i d r a n g e ;<br />

e l s e r e t u r n P r ic e R a n g e . E x p e n s iv e ;<br />

Сгруппиру<strong>е</strong>м комиксы по ц<strong>е</strong>новым кат<strong>е</strong>гориям<br />

З апрос в <strong>е</strong> р н <strong>е</strong> т п о с л <strong>е</strong> д о в а т <strong>е</strong> л ь н о с т ь п о с л <strong>е</strong> д о в а т <strong>е</strong> л ь н о с т <strong>е</strong> й . К аж дая из н и х буд<strong>е</strong>т им <strong>е</strong>ть<br />

сво й ств о Key, совпадаю щ <strong>е</strong><strong>е</strong> с эл<strong>е</strong>м <strong>е</strong>нтом п <strong>е</strong> р <strong>е</strong> ч и сл <strong>е</strong> н и я P r i c e R a n g e , возвращ <strong>е</strong>нны м м<strong>е</strong>тодом<br />

E v a l u a t e P r i c e ( ) . О б р а ти т<strong>е</strong> в н и м а н и <strong>е</strong> н а п р <strong>е</strong> д л о ж <strong>е</strong> н и <strong>е</strong> g r o u p b y - м ы вы бира<strong>е</strong>м<br />

из словаря пары и использу<strong>е</strong>м для н и х им я pair: p a i r .K e y - э то н о м <strong>е</strong> р вы пуска, а p a i r .<br />

V a l u e — <strong>е</strong>го ц<strong>е</strong>на. З апись g r o u p p a i r .K e y объ <strong>е</strong> д и н я<strong>е</strong> т в гр у п п ы ном <strong>е</strong> ра вы пуско в, о р и <strong>е</strong> н ­<br />

ти р уясь на и х ц<strong>е</strong>ну:<br />

D i c t i o n a r y < i n t , d e c i m a l> v a l u e s = G e t P r i c e s O ;<br />

v a r p r i c e G r o u p s =<br />

f r o m p a i r i n v a l u e s<br />

g ro u p p a i r . K e y b y E v a l u a t e P r i c e ( p a i r . V a l u e )<br />

in t o p r i c e G r o u p<br />

o r d e r b y p r i c e G r o u p . K e y d e s c e n d in g<br />

s e l e c t p r i c e G r o u p ;<br />

Запрос опр<strong>е</strong>д<strong>е</strong>ля<strong>е</strong>т, к какой<br />

групп<strong>е</strong> относится выбранный<br />

комикс, п<strong>е</strong>р<strong>е</strong>давая <strong>е</strong>го ц<strong>е</strong>ну<br />

м<strong>е</strong>тоду E\ra(uatePrice(). М<strong>е</strong>тод<br />

ж<strong>е</strong> возвраща<strong>е</strong>т п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ни<strong>е</strong><br />

Рпс<strong>е</strong>Капд<strong>е</strong>, использу<strong>е</strong>мо<strong>е</strong><br />

в кач<strong>е</strong>ств<strong>е</strong> ключа группы.<br />

f o r e a c h ( v a r g r o u p i n p r i c e G r o u p s ) {<br />

C o n s o l e . W r i t e ( " I f o u n d { 0 } { 1 } c o m i c s : i s s u e s<br />

f o r e a c h ( v a r p r i c e i n g r o u p )<br />

C o n s o l e . W r i t e ( p r i c e . T o S t r i n g 0 + " " ) ;<br />

C o n s o l e . W r i t e L i n d 0<br />

}<br />

Каждая из групп явля<strong>е</strong>тся посл<strong>е</strong>да<br />

ват<strong>е</strong>лшостьн), поэтому мы добавили<br />

внутр<strong>е</strong>нний цикл foreach для<br />

просмотра ц<strong>е</strong>н внутри группы.<br />

; / К<br />

Р<strong>е</strong>зультат:<br />

" , g r o u p . C o u n t О , g r o u p . K e y ) ;<br />

Н а й д <strong>е</strong> н ы 2 д о р о г и х к о м и к с а : в ы п у с к и 6 57<br />

Н а й д <strong>е</strong> н ы 3 к о м и к с а по с р <strong>е</strong> д н <strong>е</strong> й ц<strong>е</strong>н<strong>е</strong>: в ы п у с к и 19 36 68<br />

Н а й д <strong>е</strong> н ы 3 д <strong>е</strong> ш <strong>е</strong> в ы х к о м и к с а : в ы п у с к и 74 83 97


UNQ<br />

^ e ^ c r Б б а с с <strong>е</strong> й н <strong>е</strong><br />

Пом<strong>е</strong>стит<strong>е</strong> фрагм<strong>е</strong>нты кода из<br />

басс<strong>е</strong>йна на пусты<strong>е</strong> строчки.<br />

Каждый фрагм<strong>е</strong>нт мож<strong>е</strong>т быть<br />

использован н<strong>е</strong>сколько раз.<br />

Есть и лишни<strong>е</strong> фрагм<strong>е</strong>нты.<br />

Вам нужно получить сл<strong>е</strong>дующий<br />

р<strong>е</strong>зультат:<br />

I<br />

Horses enjoy eating carrots, but they love eating apples.<br />

class Line {<br />

public string[] Words;<br />

public int Value;<br />

public Line(string[] Words, int Value) {<br />

this.Words = Words; this.Value = Value;<br />

} ' Подсказка: LINQ сортиру<strong>е</strong>т<br />

строки в алфавитном порядк<strong>е</strong>.<br />

Line[] lines = {<br />

new Line( new string[] { "eating", "carrots,",<br />

"but", "enjoy", "Horses" 1,1),<br />

new Line( new string[] { "zebras?", "hay",<br />

"Cows", "bridge.", "bolted" } , 2) ,<br />

new Line( new string[] { "fork", "dogs!",<br />

"Engine", "and" }, 3 ) ,<br />

new Line( new string!] { "love", "they",<br />

"apples.", "eating" }, 2 ) ,<br />

new Line( new string[) { "whistled.", "Bump" ), 1 )<br />

from<br />

line by line..<br />

into wordGroups<br />

orderby _______<br />

select ________<br />

= words.. .(2) ;<br />

foreach (var group in twoGroups)<br />

{<br />

int i = 0;<br />

foreach (______ inner in ___<br />

i++;<br />

if (i == ..Key) {<br />

var poem<br />

word in<br />

.) {<br />

word descending<br />

word +<br />

foreach (var word in<br />

Console.Write(word) ;<br />

Каж д ы й ф р агм <strong>е</strong>нт<br />

кода м ож <strong>е</strong>т бы ть<br />

использован<br />

from<br />

з!<br />

to<br />

+ select<br />

- inside<br />

+= outside<br />

in<br />

- =<br />

orderby<br />

un<br />

by<br />

into<br />

Key<br />

output<br />

Value<br />

LineO<br />

lines<br />

new<br />

line<br />

group<br />

groups<br />

wordGroups<br />

twoGroups<br />

Value int<br />

Key string<br />

Words var<br />

words D<br />

this [1]<br />

inner [2]<br />

дальш<strong>е</strong> * 685


посл<strong>е</strong>дний р<strong>е</strong>бус в басс<strong>е</strong>йн<strong>е</strong><br />

c l a s s L i n e {<br />

p u b l i c s t r i n g [ ] W o rd s ;<br />

p u b l i c i n t V a l u e ;<br />

p u b l i c L i n e ( s t r i n g [ ] W o rd s , i n t V a lu e ) {<br />

t h i s . W o r d s = W o rd s ; t h i s . V a l u e = V a l u e ;<br />

<strong>е</strong>Ш<strong>е</strong>ни<strong>е</strong> ]=*<strong>е</strong>^са Б басс<strong>е</strong>йн<strong>е</strong><br />

}<br />

L i n e [ ] l i n e s = {<br />

ne w L i n e ( ne w s t r i n g []<br />

ne w L i n e ( ne w s t r i n g []<br />

ne w L i n e ( ne w s t r i n g []<br />

ne w L i n e ( ne w s t r i n g []<br />

ne w L i n e ( new s t r i n g []<br />

};<br />

" e a t i n g " , " c a r r o t s , " , " b u t " , " e n j o y " , " H o r s e s " } , 1 ) ,<br />

" z e b r a s ? " , " h a y " , " C o w s " , " b r i d g e . " , " b o l t e d " } , 2 ) ,<br />

" f o r k " , " d o g s ! " , " E n g i n e " , " a n d " } , 3 ) ,<br />

" l o v e " , " t h e y " , " a p p l e s . " , " e a t i n g " } , 2 ) ,<br />

" w h i s t l e d . " , " B u m p " } , 1 )<br />

v a r words =<br />

f r o m line i n linp.^<br />

gC Q U P l i n e b y l i n e . Value<br />

i n t o w o r d G r o u p s<br />

o r d e r b y wordSroups. Key<br />

s e l e c t wordSroups;<br />

в соот в<strong>е</strong>т ст вии ^<br />

группы<br />

Ш iasKgcfflyps = words.Take(2);<br />

nep6t>fC дв<strong>е</strong> группы - это строчт<br />

^ с о знач<strong>е</strong>ниями Value 3- u-Zf<br />

o r e a c h ( v a r g r o u p i n tw o G r o u p s )<br />

{<br />

i n t i = 0 ;<br />

f o r e a c h<br />

J ^ __ Этот цикл запрашива<strong>е</strong>т ^<br />

№"■ п<strong>е</strong>рвый обь<strong>е</strong>кт Une в п<strong>е</strong>рдои<br />

(var i n n e r i n group) групп<strong>е</strong> и второй обь<strong>е</strong>кт Une<br />

во второй групп<strong>е</strong>.<br />

i + + ;<br />

i f (i == group.Key) {<br />

v a r p o e m =<br />

from w o r d i n I<br />

orderby w o r d d e s c e n d in g<br />

select w o r d + U l;<br />

f o r e a c h<br />

( v a r w o r d i n poem)<br />

C o n s o l e . W r i t e ( w o r d ) ;<br />

Вы поняли, поч<strong>е</strong>му выраж<strong>е</strong>ния<br />

«Horses enjoy eating carrots, but»<br />

(«Лошади получают удовольстви<strong>е</strong><br />

от моркови, но») и «they<br />

love eating apples» («они любят<br />

яблоки») располож<strong>е</strong>ны в алф а-<br />

оитном порядк<strong>е</strong> по убыванию?<br />

Р <strong>е</strong> з у л ь т а т :<br />

Horses enjoy eating carrots, but they love eating apples.<br />

686 глава IS


UNQ<br />

Пр<strong>е</strong>дАО)к<strong>е</strong>ни<strong>е</strong> join<br />

Д ж и м м и собрал ц<strong>е</strong>лую колл <strong>е</strong> кц и ю ко м и ксо в и хот<strong>е</strong>л бы ср а внить ц<strong>е</strong>ны на н и х с ц<strong>е</strong>нам и в каталог<strong>е</strong> Гр<strong>е</strong>га,<br />

ч т о б ы п о н я ть , н<strong>е</strong> п<strong>е</strong>р<strong>е</strong>платил л и он. Д ля записи своих расходов о н создал класс P u r c h a s e с двумя<br />

а втом атич<strong>е</strong>ски м и свойствам и I s s u e и Price. П <strong>е</strong> р <strong>е</strong> ч<strong>е</strong>нь куп л <strong>е</strong> н н ы х им ко м и ксо в находится в колл<strong>е</strong>кц ии<br />

L i s t < P u r c h a s e > , ко торая назы ва<strong>е</strong>тся p u r c h a s e s . К а к ж <strong>е</strong> <strong>е</strong>му т<strong>е</strong> п<strong>е</strong>рь осущ <strong>е</strong>ствить сравн<strong>е</strong>ни<strong>е</strong> с ц<strong>е</strong>нам и<br />

из каталога Гр<strong>е</strong>га?<br />

П р <strong>е</strong> д л о ж <strong>е</strong> н и <strong>е</strong> j o i n п о з в о л и т с к о м б и н и р о в а т ь д а н н ы <strong>е</strong> и з д в у х к о л л <strong>е</strong> к ц и й в <strong>е</strong> д и н ы й запрос. Э то д<strong>е</strong>ла<strong>е</strong>тся<br />

пут<strong>е</strong>м п о и ска в п <strong>е</strong> р в о й к о л л <strong>е</strong> кц и и со в падаю щ и х з н а ч <strong>е</strong> н и й со в то р о й . ( L IN Q д<strong>е</strong>ла<strong>е</strong>т э то эф ф <strong>е</strong> ктивн<br />

о - сравнива<strong>е</strong>т то л ь ко т<strong>е</strong> п а р ы , ко то р ы <strong>е</strong> н у ж н о .) В кач<strong>е</strong>ств<strong>е</strong> р<strong>е</strong>зультата вы водятся совпадаю щ и<strong>е</strong> пары .<br />

П о сл <strong>е</strong> п р <strong>е</strong> д л о ж <strong>е</strong> н и я f r o m вм <strong>е</strong>сто к р и т <strong>е</strong> р и я<br />

о тб о р а р<strong>е</strong>зультатов н а п и ш и т<strong>е</strong> :<br />

j o i n пат<strong>е</strong> i n c o lle c tio n<br />

И м я пат<strong>е</strong> назнача<strong>е</strong>тся чл<strong>е</strong>нам , к о то р ы <strong>е</strong> извл<strong>е</strong>каю<br />

тся из о б ъ <strong>е</strong> д и н <strong>е</strong> н н о й к о л л <strong>е</strong> к ц и и на<br />

каж д о й и т <strong>е</strong> р а ц и и цикла. Зат<strong>е</strong>м вы использу<strong>е</strong>т<strong>е</strong><br />

<strong>е</strong> го в п р <strong>е</strong> д л о ж <strong>е</strong> н и и where.<br />

Ажимми присо<strong>е</strong>диня<strong>е</strong>т<br />

к комиксам из<br />

колл<strong>е</strong>кции purchases<br />

список кцпл<strong>е</strong>ннш им<br />

комиксов.<br />

Аанны<strong>е</strong> Д ж « м м и<br />

fS u d e колл<strong>е</strong>кции объ<strong>е</strong>ктов Purchase,<br />

которая иазыва<strong>е</strong>тсй purchases.<br />

class Purchase {<br />

public int Issue<br />

{ get; set; }<br />

public decimal Price<br />

{ get; set; )<br />

)<br />

О<br />

Зат<strong>е</strong>м<br />

сл<strong>е</strong>дую т п р <strong>е</strong> д л о ж <strong>е</strong> н и я<br />

w h e r e и orderby. Т ак ка к в<br />

р<strong>е</strong>зультат о б ы ч н о тр<strong>е</strong>бу<strong>е</strong>тся<br />

в к л ю ч и ть часть д а н н ы х из<br />

о д н о й ко л л <strong>е</strong> кц и и , а часть из<br />

д р у го й , в ко н ц <strong>е</strong> использу<strong>е</strong>тся<br />

пр<strong>е</strong>длож <strong>е</strong> н и <strong>е</strong> s e l e c t<br />

new,<br />

создаю щ <strong>е</strong><strong>е</strong> п ользо ват<strong>е</strong>льски й<br />

на б о р р<strong>е</strong>зультатов п р и пом о ­<br />

щ и а н о н и м н о го ти п а .<br />

o n c o m i c . I s s u e<br />

e q u a ls p u r c h a s e .I s s u e<br />

Посл<strong>е</strong> пр<strong>е</strong>длож<strong>е</strong>ния<br />

select new в фигурных<br />

скобках п<strong>е</strong>р<strong>е</strong>числ<strong>е</strong>ны<br />

данны<strong>е</strong>,, которы<strong>е</strong> сл<strong>е</strong>ду<strong>е</strong>т<br />

вклночить в р <strong>е</strong> -<br />

зильтат.<br />

Д обавим пр<strong>е</strong>длож <strong>е</strong> н и <strong>е</strong> o n , указы<br />

ваю щ <strong>е</strong><strong>е</strong> сп особ о б ъ <strong>е</strong>дин<strong>е</strong>ния<br />

ко л л <strong>е</strong> кц и й . Зат<strong>е</strong>м укаж <strong>е</strong>м им я п<strong>е</strong>рв<br />

о й к о л л <strong>е</strong> кц и и , клю ч<strong>е</strong>во<strong>е</strong> слово<br />

e q u a ls и им я в т о р о й ко л л <strong>е</strong> кц и и .<br />

s e l e c t new { c o m i c . N a m e ,<br />

c o m i c . I s s u e , p u r c h a s e .P r i c e }<br />

Iqcmo = rI пят<strong>е</strong> = “Johnnv America" I Price = 3600<br />

Issue = 1 ^ lame = “Rock and Roll” Price = 375<br />

1Issue = 57 name = “Hippie Madnless” Price = 13215 L<br />

дальш<strong>е</strong> ► 687


свой пар<strong>е</strong>нь <strong>Дж</strong>имми<br />

Д}кимми изрядно сэкономил<br />

К а ж <strong>е</strong> тся, Д ж и м м и заклю ча<strong>е</strong>т в ы го д н ую сд<strong>е</strong>лку. О н создал с п и с о к классов P urchase, в к о то р о м п<strong>е</strong>р<strong>е</strong>ч<br />

и сл <strong>е</strong> н ы <strong>е</strong>го п о к у п к и и ср а в н и л <strong>е</strong>го с ц<strong>е</strong>нам и из каталога Гр<strong>е</strong>га.<br />

О<br />

О<br />

Сначала Д ж и а л м и создал дополнит<strong>е</strong>льную колл<strong>е</strong>кцию<br />

О н использовал свой с та р ы й м<strong>е</strong>тод B u i l d C a t a l o g (). Д ж и м м и осталось то л ь к о н а п и ­<br />

сать м <strong>е</strong>тод F i n d P u r c h a s e s {) и п о с т р о и т ь к о л л <strong>е</strong> кц и ю классов Purchase.<br />

s t a t i c I E n u m e r a b le < P u r c h a s e > F i n d P u r c h a s e s () {<br />

L i s t < P u r c h a s e > p u r c h a s e s = ne w L i s t < P u r c h a s e > () {<br />

n e w P u r c h a s e 0 { I s s u e = 6 8 , P r i c e = 225M } ,<br />

new P u r c h a s e 0 { I s s u e = 1 9 , P r i c e = 375M } ,<br />

ne w P u r c h a s e 0 { I s s u e = 6, P r i c e = 36 0 0 M } ,<br />

n e w P u r c h a s e 0 { I s s u e = 5 7 , P r i c e = 13 2 1 5 M<br />

n e w P u r c h a s e 0 { I s s u e = 3 6 , P r i c e = 660M } ,<br />

} ;<br />

r e t u r n p u r c h a s e s ;<br />

}<br />

Вс<strong>е</strong> готово для слияния!<br />

3a выпуск * S 7<br />

W ^ z x s .<br />

Ч а сть э т о го запроса вы уж <strong>е</strong> вид<strong>е</strong>ли. О ста лось д обавить к н<strong>е</strong>м у н <strong>е</strong> д о ста ю щ и й<br />

кусок.<br />

J<br />

IE n u m e r a b le < C o m ic > c o m ic s = B u i l d C a t a l o g ( ) ;<br />

D i c t i o n a r y < i n t , d e c i m a l> v a l u e s = G e t P r i c e s O ;<br />

I E n u m e r a b le < P u r c h a s e > p u r c h a s e s = F i n d P u r c h a s e s ()<br />

v a r r e s u l t s =<br />

f r o m c o m ic i n c o m ic s<br />

j o i n p u r c h a s e i n p u r c h a s e s<br />

o n c o m i c . l s s u e e q u a ls p u r c h a s e . I s s u e<br />

o r d e r b y c o m i c . l s s u e a s c e n d in g<br />

s e l e c t ne w { c o m ic .N a m e , c o m i c . l s s u e , p u r c h a s e . P r i c e } ;<br />

d,oimal ,re,sLl,tVal„, = 0;<br />

d e c i m a l t o t a l S p e n t = 0 ;<br />

f o r e a c h ( v a r r e s u l t i n r e s u l t s ) ,<br />

g r e g s L i s t V a l u e += v a l u e s [ r e s u l t . I s s u e ] ;<br />

t o t a l S p e n t + = r e s u l t . P r i c e ;<br />

C o n s o l e . W r i t e L i n e ( " В ы п у с к #{0} ({!}) к у п л <strong>е</strong> н з а {2:с}",<br />

r e s u l t . I s s u e , r e s u l t . N a m e , r e s u l t . P r i c e ) ;<br />

Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> join иницииру<strong>е</strong>т<br />

сравн<strong>е</strong>ни<strong>е</strong> каждого эл<strong>е</strong>м<strong>е</strong>нта из<br />

колл<strong>е</strong>кции comics с э л <strong>е</strong> м <strong>е</strong> н т а м и<br />

колл<strong>е</strong>кции purchases для поиска<br />

т<strong>е</strong>к, у которых comic.lssue<br />

соВпада<strong>е</strong>т с purchase.Issue.<br />

n p eJA O X « » select cosl^ em<br />

C o n s o l e . W r i t e L i n e (" Я п о т р а т и л {0:c} н а к о м и к с ы , с т о я щ и <strong>е</strong> {l:c}<br />

t o t a l S p e n t , g r e g s L i s t V a l u e ) ;<br />

<strong>Дж</strong>имми счастлив,<br />

что он зна<strong>е</strong>т<br />

иЫ 0, так как<br />

это позволило<br />

<strong>е</strong>му подсчитать,<br />

сколько ж<strong>е</strong> он<br />

сэкономил.<br />

688 глава 15<br />

Р<strong>е</strong>зультат:<br />

знач<strong>е</strong>ни<strong>е</strong>м Price от чл<strong>е</strong>на purchase.<br />

В ы п у с к #6 ( J o h n n y A m e r i c a vs. t h e Pinko) к у п л <strong>е</strong> н з а $ 3 , 6 0 0 . 0 0<br />

В ы п у с к #19 (Rock a n d R o l l ( l i m i t e d e d i t i o n ) ) к у п л <strong>е</strong> н з а $ 3 7 5 . 0 0<br />

В ы п у с к #36<br />

В ы п у с к #57<br />

( W o m a n ' s W o rk) к у п л <strong>е</strong> н з а $ 6 6 0 . 0 0<br />

( H i p p i e M a d n e s s ( m i s p r i n t e d ) ) к у п л <strong>е</strong> н з а $ 1 3 , 2 1 5 . 0 0<br />

В ы п у с к #68 ( R e v e n g e o f t h e N e w W a v e F r e a k ( d a m a g e d ) ) к у п л <strong>е</strong> н за<br />

$ 2 2 5 . 0 0<br />

Я п о т р а т и л $18,075.00 на комиксы, стоящи<strong>е</strong> $18,525.00


UNQ<br />

Хорошо. <strong>Дж</strong>иллми использовал L IN Q для<br />

запросов из колл<strong>е</strong>кций... а как быть с промоакци<strong>е</strong>й<br />

коф<strong>е</strong>йного магазина? Я до сих пор н<strong>е</strong><br />

понимаю, как L IN Q работа<strong>е</strong>т с базами данных.<br />

Для работы с базами данных LINQ использу<strong>е</strong>т<br />

тот ж<strong>е</strong> самый синтаксис.<br />

В глав<strong>е</strong> 1 вы уж <strong>е</strong> вид<strong>е</strong>ли, как л <strong>е</strong> гко .N E T п озволя<strong>е</strong>т<br />

р а б ота ть с базами д а н н ы х. В ы м ож <strong>е</strong>т<strong>е</strong> б ы с т р о п р и ­<br />

с о <strong>е</strong> д и н и ть базу, добавить та б л и ц ы и даж <strong>е</strong> п р и в я ­<br />

зать к ф орм <strong>е</strong> д а н н ы <strong>е</strong> из э т и х таблиц.<br />

Н<strong>е</strong>смотря на<br />

значит<strong>е</strong>льную<br />

разницу LlhlQ<br />

и SQL написанный<br />

вами код<br />

буд<strong>е</strong>т похож на<br />

остальны<strong>е</strong> запросы<br />

LINQ.<br />

Сд<strong>е</strong>ла<strong>е</strong>м запрос к э то й , уж <strong>е</strong> связа н н о й с п р о гр а м ­<br />

м о й баз<strong>е</strong> д а н н ы х. L IN Q б<strong>е</strong>з пробл<strong>е</strong>м с к о м б и н и р у<strong>е</strong> т<br />

д анны <strong>е</strong> и з базы с д а н н ы м и , п о л у ч <strong>е</strong> н н ы м и о т объ<strong>е</strong>ктов.<br />

С и н та к с и с запросов н<strong>е</strong> и зм <strong>е</strong> н и тся ... вам потр <strong>е</strong> б у<strong>е</strong> т­<br />

ся вс<strong>е</strong>го л и ш ь п о л у ч и ть д о ступ к баз<strong>е</strong> д а н н ы х.<br />

База данных<br />

ContactDB<br />

Адр<strong>е</strong>с кли<strong>е</strong>нта <strong>е</strong>сть<br />

в объ<strong>е</strong>ктвильской<br />

баз<strong>е</strong> контактной<br />

информации.<br />

l l N t<br />

*?■—<br />

А зд<strong>е</strong>сь находятся<br />

данны<strong>е</strong> о постоянных<br />

пос<strong>е</strong>тит<strong>е</strong>лях<br />

коф<strong>е</strong>йного магазина<br />

Starbuzz.<br />

UNQ позволит нам сравнить<br />

^ и скомбинировать данны<strong>е</strong> из<br />

н<strong>е</strong>скольких источников и создать<br />

р<strong>е</strong>зультирующую посл<strong>е</strong>доват<strong>е</strong>льность.<br />

дальш<strong>е</strong> > 689


соб<strong>е</strong>р<strong>е</strong>м вс<strong>е</strong> вм<strong>е</strong>ст<strong>е</strong><br />

Со<strong>е</strong>дин<strong>е</strong>ни<strong>е</strong> LINQ с базой данных SQL<br />

L IN Q p a 6 o T a e T с объ<strong>е</strong>ктам и, р <strong>е</strong> ализую щ им и и н т <strong>е</strong> р ф <strong>е</strong> й с I E n u m e r a b l e < T > .<br />

З н а чит, для доступа к баз<strong>е</strong> д а н н ы х S Q L нам тр<strong>е</strong>бу<strong>е</strong> тся и м <strong>е</strong> н н о та к о й объ<strong>е</strong>кт.<br />

П о э то м у добавим <strong>е</strong>го к наш <strong>е</strong>м у про<strong>е</strong>кту.<br />

О<br />

Это м о­<br />

ж<strong>е</strong>т быть<br />

и папка<br />

«NETFX<br />

4-.0 Tools»,<<br />

влож<strong>е</strong>нная<br />

в пап1ш<br />

В1п\. В<br />

этом случа<strong>е</strong>-<br />

в конц<strong>е</strong><br />

команды<br />

РАТН=<br />

нужно нап<strong>е</strong>чатать<br />

«NETFX<br />

4.(9 Tools».<br />

Добавим базу данных к новому консольному прилож<strong>е</strong>нию<br />

В глав<strong>е</strong> 1 с пом ощ ью S Q L Sender C om pact вы создали базу с к о н та к т н о й инф орм ац и <strong>е</strong> й и со хранили<br />

<strong>е</strong><strong>е</strong> в ф айл C o n t a c t D B .sdf. Н а ч н и т<strong>е</strong> н о в ы й про<strong>е</strong>кт, щ <strong>е</strong>лкнит<strong>е</strong> п р авой к н о п к о й м ы ш и на <strong>е</strong>го им<strong>е</strong>н<br />

и в о кн<strong>е</strong> S o lu tio n E xplorer, вы б<strong>е</strong>рит<strong>е</strong> команду A d d E xistin g Ite m и добавьт<strong>е</strong> базу В раскры ваю щ <strong>е</strong>м ­<br />

ся списк<strong>е</strong> ти п о в объ<strong>е</strong>ктов н у ж н о буд<strong>е</strong>т вы брать вариант D ata Files. (П о я в и тся маст<strong>е</strong>р D ata Source<br />

C o n fig u ra tio n , н о <strong>е</strong>го м о ж н о п р о с то закры ть.)<br />

Для сопоставл<strong>е</strong>ния L IN Q и S Q L -платформы используйт<strong>е</strong> SqIMetal <strong>е</strong>х<strong>е</strong><br />

Вам остался вс<strong>е</strong>го о д и н ш а г для п р и с о <strong>е</strong> д и н <strong>е</strong> н и я к коду базы д а н н ы х, и сд<strong>е</strong>лать <strong>е</strong> го п о м о ж <strong>е</strong> т<br />

п р о гр ам м а S<br />

q ^ t a l . <strong>е</strong> х <strong>е</strong> . О н а устанавлива<strong>е</strong>тся вм<strong>е</strong>ст<strong>е</strong> с V isu a l S tu d io 2010 и н а хо д и тся в папк<strong>е</strong><br />

M ic ro s o ft SDKs, в л о ж <strong>е</strong> н н о й в п а п ку P ro g ra m Files. В ком андную стр о к у вв<strong>е</strong>дит<strong>е</strong> команду, указы<br />

ваю щ ую м арш рут к папк<strong>е</strong> M ic ro s o ft SDK. Д ля 6 4 -б и тн о й в <strong>е</strong> р сии W in d o w s вв<strong>е</strong>дит<strong>е</strong>:<br />

РАТН=%РАТН%;%PrograinFiles(х86)%\Microsoft SDKs\Windows\v7.OA\Bin\<br />

/Д л я 3 2 -б и тн о й в <strong>е</strong> р с и и ком анда буд<strong>е</strong>т н<strong>е</strong>ско л ь ко отл ичаться:<br />

PATH=%PATH%;%PrograraFiles%\Microsoft SDKs\Windows\v7.OA\Bin\<br />

J e n e p b п <strong>е</strong> р <strong>е</strong> й д и т<strong>е</strong> в папку с п р о <strong>е</strong> к то м ( c d f o ld e r - n a m e ) и вв<strong>е</strong>дит<strong>е</strong> команду:<br />

SqlMetal.exe ContactDB.sdf /dbml:ContactDB.dbml<br />

В о т ч т о д о л ж н о п о л учить ся на вы ход<strong>е</strong>:<br />

Microsoft (R) Database Mapping Generator 2008 version 1.00.30729<br />

for Microsoft (R) .NET Framework version 3.5<br />

Copyright (C) Microsoft Corporation. All rights reserved.<br />

П осл <strong>е</strong> э т о го в ваш <strong>е</strong>й папк<strong>е</strong> ока ж <strong>е</strong>тся ф айл C o n t a c t D B .dbml. И спользуйт<strong>е</strong> ком анду A d d<br />

E x is tin g Ite m , ч т о б ы д об а вить <strong>е</strong>го к сво<strong>е</strong>м у про<strong>е</strong>кту. П р и это м И С Р создаст для вас <strong>е</strong>щ <strong>е</strong> два ф айла:<br />

C o n t a c t D B .d e s i g n e r .cs и C o n t a c t D B .d b m l .layout.<br />

Получить дополнит<strong>е</strong>льную информацию о SqlMetal.exe можно зд<strong>е</strong>сь:<br />

________http://msdn.microsoft.com/ru-m/librartf/hb38ea87 я.


Откройт<strong>е</strong> классы L IN Q и SQL в конструктор<strong>е</strong> O bject Relational<br />

П р о гр а м м о й S q I M e t a l . <strong>е</strong> х <strong>е</strong> б ы л и созданы к л а с с ы L I N Q to S Q L . Э ти классы ум <strong>е</strong>ю т<br />

п о сы л а ть запрос к таблицам ваш <strong>е</strong>й базы д а н н ы х и п р и этом р<strong>е</strong>ализую т и н т<strong>е</strong>рф <strong>е</strong> й с<br />

I E n u m e r a b l e < T > с ф ун кц и <strong>е</strong> й , возвращ аю щ <strong>е</strong>й д анны <strong>е</strong> в таблицу.<br />

И С Р о снащ <strong>е</strong>на та ки м зам <strong>е</strong>чат<strong>е</strong>льны м и н стр ум <strong>е</strong> н то м ка к к о н с т р у к т о р O b je c t R e la tio n a l.<br />

Зд<strong>е</strong>сь вы м ож <strong>е</strong>т<strong>е</strong> увид<strong>е</strong>ть, ка ки<strong>е</strong> классы б ы л и созданы п р о гр а м м о й S q l M e t a l . e x e .<br />

Д в о й н о й щ <strong>е</strong> л ч о к на и м <strong>е</strong> н и д о б а вл<strong>е</strong>нного к п р о <strong>е</strong> к ту ф айла C o n t a c t D B .d b m l о ткр ы в а ­<br />

<strong>е</strong> т <strong>е</strong>го в к о н с тр у к т о р <strong>е</strong> O b je c t R e la tio n a l. В о т ч т о вы п р и этом увид ит<strong>е</strong>:<br />

ontaetDB.dbml<br />

—----- —------------------------------<br />

Peopfe<br />

S Properties<br />

f S * ContactID<br />

Nante<br />

^ Company<br />

Ш Telephone<br />

Ш Email<br />

^ Client<br />

^ LastCall<br />

Create methods by<br />

dragging items from<br />

Database Explorer<br />

onto this design<br />

surface<br />

8 конструктор<strong>е</strong> Object<br />

Relational вы увидит<strong>е</strong><br />

класс PeoplCj созданный<br />

при поАЛош,и программы<br />

SqlMetal.exe. Он присо<strong>е</strong>диня<strong>е</strong>т<br />

к про<strong>е</strong>кту таблицу<br />

People с дазой данных и<br />

возвраща<strong>е</strong>т данны<strong>е</strong> при<br />

помощи инт<strong>е</strong>рф<strong>е</strong>йса<br />

1Епит<strong>е</strong>тЫ<strong>е</strong>, давая<br />

возможность осущ<strong>е</strong>ствлять<br />

запросы UNQ.<br />

Прим<strong>е</strong>чани<strong>е</strong>: В в<strong>е</strong>рсиях Visual Studio, отличных от Express, можно п<strong>е</strong>р<strong>е</strong>тащить источник<br />

данных SQ L н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нно в конструктор Object Relational.<br />

Вс<strong>е</strong> готово для написания запросов к баз<strong>е</strong> данных<br />

Д обавьт<strong>е</strong> э т о т код в м<strong>е</strong>тод M a i n (). О б р а ти т<strong>е</strong> вним а н и <strong>е</strong> , как п р и п о м о щ и кл ю ч <strong>е</strong> ­<br />

в ы х слов s e l e c t new б ы л о указано, ч т о р<strong>е</strong>зультат д о л ж <strong>е</strong> н сод<strong>е</strong>рж ать то л ь к о дан-<br />

^ontactPB иь1<strong>е</strong> из п о л <strong>е</strong> й N a m e и C o m p a n y<br />

Й о Т н о и м я s t r i n g c o n n e c t i o n S t r i n g = " D a t a S o u r c e = I D a t a D i r e c t o r y | W C o n t a c t D B . s d f " ;<br />

context.<br />

Исполь- — .<br />

зуйт<strong>е</strong> <strong>е</strong>го<br />

свойство<br />

People для<br />

получ<strong>е</strong>ния<br />

данных из<br />

таблицы<br />

People.<br />

C o n ta c tD B c o n t e x t = ne w C o n t a c t D B ( c o n n e c t i o n S t r i n g ) ;<br />

Попрактикуйт<strong>е</strong>сь с прим<strong>е</strong>н<strong>е</strong>ни<strong>е</strong>м<br />

ключ<strong>е</strong>вых слов select new. Им<strong>е</strong>нно<br />

они из вс<strong>е</strong>х данных базы выбирают<br />

только информацию об им<strong>е</strong>ни<br />

f r o m p e r s o n i n c o n t e x t . P e o p le<br />

s e l e c t ne w { p e r s o n .N a m e , p e rs o n . C o m p a n y } ; ч<strong>е</strong>лов<strong>е</strong>ка U фирм<strong>е</strong>, в которой OH<br />

работа<strong>е</strong>т.<br />

^<br />

v a r p e o p le D a t a =<br />

f o r e a c h ( v a r p e r s o n i n p e o p le D a t a )<br />

C o n s o l e . W r i t e L i n e ( " { 0 } w o r k s a t { i : p e r s o n .N a m e , p e r s o n . C o m p a n y ) ;<br />

дальш<strong>е</strong> ► 691


ключ<strong>е</strong>во<strong>е</strong> слово var<br />

КЛЮЧЕВЫЕ<br />

МОМЕНТЫ<br />

Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> g r o u p разбива<strong>е</strong>т р<strong>е</strong>зультат на<br />

группы — только созда<strong>е</strong>т посл<strong>е</strong>доват<strong>е</strong>льность<br />

из посл<strong>е</strong>доват<strong>е</strong>льност<strong>е</strong>й.<br />

Каждая группа сод<strong>е</strong>ржит чл<strong>е</strong>н, являющийся<br />

общим для вс<strong>е</strong>х остальных чл<strong>е</strong>нов. Он называ<strong>е</strong>тся<br />

ключом и зада<strong>е</strong>тся ключ<strong>е</strong>вым словом by.<br />

Каждая посл<strong>е</strong>доват<strong>е</strong>льность облада<strong>е</strong>т чл<strong>е</strong>ном<br />

Key, сод<strong>е</strong>ржащим ключ группы.<br />

Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> j o i n объ<strong>е</strong>диня<strong>е</strong>т дв<strong>е</strong> колл<strong>е</strong>кции<br />

в одном запрос<strong>е</strong>. Чл<strong>е</strong>ны об<strong>е</strong>их колл<strong>е</strong>кций<br />

сравниваются друг с другом и из совпадающих<br />

пар формиру<strong>е</strong>тся р<strong>е</strong>зультат.<br />

Ключ<strong>е</strong>вы<strong>е</strong> слова o n ... e q u a l s задают крит<strong>е</strong>рий<br />

сравн<strong>е</strong>ния в пр<strong>е</strong>длож<strong>е</strong>нии j o i n .<br />

В р<strong>е</strong>зультаты запроса j o i n обычно тр<strong>е</strong>бу<strong>е</strong>тся<br />

выборочно включить эл<strong>е</strong>м<strong>е</strong>нты из об<strong>е</strong>их колл<strong>е</strong>кций.<br />

Это р<strong>е</strong>ализу<strong>е</strong>тся при помощи пр<strong>е</strong>длож<strong>е</strong>ния<br />

s e l e c t .<br />

Запрос к баз<strong>е</strong> данных SQL осущ<strong>е</strong>ствля<strong>е</strong>тся при<br />

помощи классов LINQ to SQL.Ohh об<strong>е</strong>сп<strong>е</strong>чивают<br />

программу объ<strong>е</strong>ктами, работающими с LINQ<br />

(то <strong>е</strong>сть дают вам н<strong>е</strong>поср<strong>е</strong>дств<strong>е</strong>нный доступ<br />

к м<strong>е</strong>тодам этих объ<strong>е</strong>ктов).<br />

Конструктор Object Relational позволя<strong>е</strong>т выбирать<br />

таблицы, к которым вы хотит<strong>е</strong> обратиться<br />

ср<strong>е</strong>дствами LINQ. Посл<strong>е</strong> выбора таблиц к про<strong>е</strong>кту<br />

добавля<strong>е</strong>тся класс D a t a C o n t e x t . Чл<strong>е</strong>ны<br />

<strong>е</strong>го экз<strong>е</strong>мпляров добавляются к запросам LINQ<br />

и об<strong>е</strong>сп<strong>е</strong>чивают доступ к таблицам SQL.<br />

Объяснит<strong>е</strong>, пожалуйста, что означа<strong>е</strong>т v a r .<br />

Q ; Ключ<strong>е</strong>во<strong>е</strong> СЛОВО v a r р<strong>е</strong>ша<strong>е</strong>т сложную пробл<strong>е</strong>му, возникающую<br />

в LINQ. Обычно при вызов<strong>е</strong> м<strong>е</strong>тода или выполн<strong>е</strong>нии<br />

оп<strong>е</strong>ратора сразу ясно, с каким типом данных вы работа<strong>е</strong>т<strong>е</strong>.<br />

К прим<strong>е</strong>ру, <strong>е</strong>сли м<strong>е</strong>тод возвраща<strong>е</strong>т знач<strong>е</strong>ния типа s t r i n g ,<br />

р<strong>е</strong>зультат <strong>е</strong>го работы нужно сохранить в п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нную или пол<strong>е</strong><br />

им<strong>е</strong>нно этого типа.<br />

А вот запрос LINQ мож<strong>е</strong>т в<strong>е</strong>рнугь данны<strong>е</strong> анонимного типа, гаторый<br />

нигд<strong>е</strong> н<strong>е</strong> опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>н. Вы зна<strong>е</strong>т<strong>е</strong>, что это какая-то посл<strong>е</strong>доват<strong>е</strong>льность.<br />

Но тип сод<strong>е</strong>ржащихся в н<strong>е</strong>й объ<strong>е</strong>ктов полностью<br />

зависит от сод<strong>е</strong>ржания запроса LINQ. Наприм<strong>е</strong>р, рассмотрим вот<br />

такой запрос:<br />

v a r m o s t E x p e n s i v e =<br />

fro m c o m ic i n c o m ic s<br />

w h e re v a l u e s [ c o m i c . I s s u e ] , > 5 0 0<br />

o r d e r b y v a l u e s [ c o m i c . I s s u e ]<br />

d e s c e n d i n g<br />

s e l e c t c o m ic ;<br />

Часзпо<br />

^ а Д а Б а <strong>е</strong> М ы <strong>е</strong><br />

Б о іп р о с ь і<br />

Если вм<strong>е</strong>сто посл<strong>е</strong>дн<strong>е</strong>й строчки написать:<br />

s e l e c t new<br />

{ Nam e = с о т і с . Nam e,<br />

Is s u e N u m b e r = " # " + c o m i c . l s s u e } ;<br />

запрос в<strong>е</strong>рн<strong>е</strong>т данны<strong>е</strong> анонимного типа с двумя чл<strong>е</strong>нами — строкой<br />

Name и строкой Is s u e N u m b e r . Но опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> класса<br />

для этого типа в наш<strong>е</strong>й программ<strong>е</strong> отсугству<strong>е</strong>т! При том, что<br />

п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нная m o s t E x p e n s i v e должна быть объявл<strong>е</strong>на как<br />

принадл<strong>е</strong>жащая к какому-то типу.<br />

Зд<strong>е</strong>сь на помощь приходит ключ<strong>е</strong>во<strong>е</strong> слово v a r , которо<strong>е</strong> как<br />

бы объясня<strong>е</strong>т компилятору: «Это корр<strong>е</strong>ктный тип, просто мы<br />

пока н<strong>е</strong> зна<strong>е</strong>м, какой им<strong>е</strong>нно. Опр<strong>е</strong>д<strong>е</strong>ли это, пожалуйста, самостоят<strong>е</strong>льно».<br />

692 глава 15


я так и н<strong>е</strong> понял, как работа<strong>е</strong>т прилож<strong>е</strong>ни<strong>е</strong><br />

join.<br />

г ; Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> j o i n работа<strong>е</strong>т с<br />

двумя посл<strong>е</strong>доват<strong>е</strong>льностями. Пр<strong>е</strong>дположим,<br />

у вас <strong>е</strong>сть колл<strong>е</strong>кция футбольных<br />

игроков p layers. Е<strong>е</strong> эл<strong>е</strong>м<strong>е</strong>нтами<br />

являются объ<strong>е</strong>кты со свойствами Name,<br />

P o s i t i o n и Number. Выбрать<br />

игроков, на футболк<strong>е</strong> которых ном<strong>е</strong>р<br />

больш<strong>е</strong> 10, можно запросом:<br />

v a r r e s u l t s =<br />

f r o m p l a y e r in p l a y e r s<br />

w h e r e p l a y e r . N u m b e r > 10<br />

s e l e c t p l a y e r ;<br />

У нас <strong>е</strong>сть и колл<strong>е</strong>кция j erseys,<br />

эл<strong>е</strong>м<strong>е</strong>нты которой обладают свойствами<br />

N u m b e r и Size. Чтобы опр<strong>е</strong>д<strong>е</strong>лить<br />

разм<strong>е</strong>р футболки каждого игрока запиш<strong>е</strong>м:<br />

v a r r e s u l t s =<br />

f r o m p l a y e r in p l a y e r s<br />

w h e r e p l a y e r . N u m b e r > 10<br />

j o i n s h i r t in j e r s e y s<br />

o n p l a y e r . N u m b e r<br />

e q u a l s s h i r t . N u m b e r<br />

s e l e c t shirt;<br />

Этот запрос даст мн<strong>е</strong> множ<strong>е</strong>ство<br />

( )утболок. А как быть, <strong>е</strong>сли м<strong>е</strong>ня н<strong>е</strong><br />

волнуют ном<strong>е</strong>ра игроков, но хот<strong>е</strong>лось<br />

бы узнать разм<strong>е</strong>р футболки каждого<br />

из них?<br />

^ ; Зд<strong>е</strong>сь вам пригодятся анонимны<strong>е</strong><br />

типы — в них можно положить любы<strong>е</strong><br />

нужны<strong>е</strong> вам данны<strong>е</strong>. Они позволяют и выбирать<br />

из объ<strong>е</strong>дин<strong>е</strong>нных колл<strong>е</strong>кций.<br />

Ч а с в д о<br />

ЧаДаБа<strong>е</strong>Мы<strong>е</strong><br />

Б о ї ї р о с ь і<br />

И ничто н<strong>е</strong> м<strong>е</strong>ша<strong>е</strong>т вам выбрать только<br />

им<strong>е</strong>на игроков и разм<strong>е</strong>ры их футболок:<br />

v a r r e s u l t s =<br />

f r o m p l a y e r in p l a y e r s<br />

w h e r e p l a y e r . N u m b e r > 10<br />

j o i n s h i r t in j e r s e y s<br />

o n p l a y e r . N u m b e r<br />

e q u a l s s h i r t . N u m b e r<br />

s e l e c t new {<br />

p l a y e r . N a m e ,<br />

} ;<br />

s h i r t .S i z e<br />

ИСР в состоянии самостоят<strong>е</strong>льно разобраться<br />

с р<strong>е</strong>зультатом, который выда<strong>е</strong>т<br />

запрос. При создании цикла, нум<strong>е</strong>рующ<strong>е</strong>го<br />

р<strong>е</strong>зультаты, сразу посл<strong>е</strong> ввода п<strong>е</strong>р<strong>е</strong>м<strong>е</strong>нной<br />

появится окно IntelliSense со списком.<br />

f o r e a c h (var г in r e s u l t s )<br />

г .<br />

I<br />

Equals<br />

GetType<br />

Ш Size<br />

ToString<br />

GetHashCode<br />

В списк<strong>е</strong> присутствуют свойства N a m e<br />

и Size. Добавл<strong>е</strong>нны<strong>е</strong> к пр<strong>е</strong>длож<strong>е</strong>нию<br />

s e l e c t дополнит<strong>е</strong>льны<strong>е</strong> пункты тож<strong>е</strong><br />

появятся в этом списк<strong>е</strong>. Это связано с т<strong>е</strong>м,<br />

что запрос созда<strong>е</strong>т различны<strong>е</strong> анонимны<strong>е</strong><br />

типы для различных чл<strong>е</strong>нов.<br />

Вс<strong>е</strong>гда ли нужно добавлять файл<br />

. dbm l, создава<strong>е</strong>мый программой<br />

S q I M e t a l . <strong>е</strong> х <strong>е</strong> ? Я так и н<strong>е</strong> понял,<br />

зач<strong>е</strong>м он нуж<strong>е</strong>н.<br />

:Если вы собира<strong>е</strong>т<strong>е</strong>сь писать запросы<br />

коазк Ваз<strong>е</strong> данных SQL, б<strong>е</strong>з этого файла н<strong>е</strong><br />

обойтись.<br />

Помнит<strong>е</strong>, что LINQ тр<strong>е</strong>бу<strong>е</strong>т от объ<strong>е</strong>ктов<br />

р<strong>е</strong>ализации инт<strong>е</strong>рф<strong>е</strong>йса<br />

I E n u m e r a b l e < T > . Базы SQL н<strong>е</strong> р<strong>е</strong>ализуют<br />

вообщ<strong>е</strong> никаких инт<strong>е</strong>рф<strong>е</strong>йсов, так<br />

как н<strong>е</strong> относятся к объ<strong>е</strong>ктам. Поэтому для<br />

запросов LINQ источник данных тр<strong>е</strong>бу<strong>е</strong>тся<br />

пр<strong>е</strong>образовать в объ<strong>е</strong>кт.<br />

В<strong>е</strong>рнит<strong>е</strong>сь к только что написанному<br />

коду, щ<strong>е</strong>лкнит<strong>е</strong> правой кнопкой мыши на<br />

объ<strong>е</strong>кт<strong>е</strong> People и выб<strong>е</strong>рит<strong>е</strong> команду Go<br />

to Definition. Это прив<strong>е</strong>д<strong>е</strong>т вас к м<strong>е</strong>тоду<br />

доступа C o n t a c t D B .d e s i g n e r .<br />

cs, возвращающ<strong>е</strong>му объ<strong>е</strong>кт<br />

Т а Ь 1 <strong>е</strong> < Р <strong>е</strong> о р 1 <strong>е</strong> > . Повторит<strong>е</strong> проц<strong>е</strong>дуру<br />

для объ<strong>е</strong>кта Table. Вы увидит<strong>е</strong>, что класс<br />

T a b l e < T E n t i t y > расширя<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс<br />

I Q u e r y a b l e < T E n t i t y > .<br />

П<strong>е</strong>р<strong>е</strong>йдя к опр<strong>е</strong>д<strong>е</strong>л<strong>е</strong>нию этого инт<strong>е</strong>рф<strong>е</strong>йса,<br />

вы обнаружит<strong>е</strong>, что он р<strong>е</strong>ализу<strong>е</strong>т инт<strong>е</strong>рф<strong>е</strong>йс<br />

I E n u m e r a b l e < T > .<br />

То <strong>е</strong>сть файл . d b m l (и создава<strong>е</strong>мый<br />

им файл кпасса .cs) об<strong>е</strong>сп<strong>е</strong>чива<strong>е</strong>т нас<br />

объ<strong>е</strong>кгом, р<strong>е</strong>ализующим инт<strong>е</strong>рф<strong>е</strong>йс<br />

l E n u m e r a b l e . ИСР точно зна<strong>е</strong>т, как<br />

поступать с файлом . dbml: ст<strong>е</strong>н<strong>е</strong>рировав<br />

<strong>е</strong>го, добавив к про<strong>е</strong>кту и отфыв в конструктор<strong>е</strong><br />

Object Relational, вы увидит<strong>е</strong> чл<strong>е</strong>ны<br />

класса People, совпадающи<strong>е</strong> с таблиц<strong>е</strong>й<br />

P e o p l e в баз<strong>е</strong> данных. Этот класс присо<strong>е</strong>диня<strong>е</strong>тся<br />

к SQL, автоматич<strong>е</strong>ски чита<strong>е</strong>т<br />

данны<strong>е</strong> из таблиц и пр<strong>е</strong>образу<strong>е</strong>т их в форму,<br />

доступную для запросов LINQ.<br />

Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong> select new позволя<strong>е</strong>т конструировать пользоват<strong>е</strong>льский<br />

запрос LINQ,, в р<strong>е</strong>зультаты которого включ<strong>е</strong>ны толь<br />

ко нужны<strong>е</strong> вам эл<strong>е</strong>м<strong>е</strong>нты.<br />

дальш<strong>е</strong> > 693


это всё, р<strong>е</strong>бята<br />

Со<strong>е</strong>диним Starbuzz и Objectville<br />

Т <strong>е</strong>п<strong>е</strong>рь у вас <strong>е</strong>сть всё, ч т о б ы со <strong>е</strong> д и н и ть д анны <strong>е</strong> к о ф <strong>е</strong> й н о го магази<br />

н а S tarbuzz и о б ъ <strong>е</strong> ктв и л ь ско й ф и р м ы п о п р о и звод ству бумаги.<br />

У п р а ж н <strong>е</strong> н и <strong>е</strong><br />

О<br />

Добавим к про<strong>е</strong>кту данны<strong>е</strong> SQL<br />

Если вы это го <strong>е</strong>щ<strong>е</strong> н<strong>е</strong> сд<strong>е</strong>лали, о тк р о й т<strong>е</strong> ново<strong>е</strong> консольно<strong>е</strong> п р и л о ж <strong>е</strong> н и <strong>е</strong> и добавьт<strong>е</strong> к н<strong>е</strong>му базу<br />

C o n ta c tD B . С пом ощ ью п рограм м ы S q I M e t a l. <strong>е</strong> х <strong>е</strong> создайт<strong>е</strong> классы L IN Q to S Q L, добавьт<strong>е</strong> и х<br />

к п р о <strong>е</strong> кту и н а п и ш и т<strong>е</strong> п р о с то й т<strong>е</strong> сто вы й запрос, ч то б ы уб<strong>е</strong>диться, ч то присо <strong>е</strong> д и н <strong>е</strong> н и <strong>е</strong> прош л о<br />

усп<strong>е</strong>ш но и вс<strong>е</strong> работа<strong>е</strong>т.<br />

Построим объ<strong>е</strong>кты starbuzz<br />

В о т с п и с о к с д а н н ы м и к л и <strong>е</strong> н то в м агазина Starbuzz. Д обавьт<strong>е</strong> <strong>е</strong>го к про<strong>е</strong>кту:<br />

М<strong>е</strong>тод<br />

объ<strong>е</strong>ктов<br />

Starbuzx при помои^и<br />

инициализатора<br />

колл<strong>е</strong>кции<br />

НапоАЛина<strong>е</strong>м.,<br />

ч т о для<br />

к о л л <strong>е</strong> к ц и и (А<br />

инициализаторов<br />

можно и<strong>е</strong><br />

использоват<strong>е</strong>’ } .<br />

скобки О- }<br />

c l a s s S t a r b u z z D a t a {<br />

p u b l i c s t r i n g Name { g e t ; s e t ; }<br />

p u b l i c D r i n k F a v o r i t e D r i n k { g e t ; s e t ; } Коф<strong>е</strong>йного Магазина<br />

p u b lic i n t » „ e y s p e n t , get; =et,<br />

p u b l i c i n t V i s i t s { g e t ; s e t ; } CAUUAKOM Много — и большинство<br />

} нужны. Поэтому выб<strong>е</strong>р<strong>е</strong>м<br />

только т<strong>е</strong> из них, которы<strong>е</strong><br />

enum D r i n k { подходят для наш<strong>е</strong>го запроса.<br />

B o r i n g C o f f e e , C h o c o R o c k o L a t t e , T r i p l e E s p r e s s o ,<br />

Z e s ty L e m o n C h a i, D o u b le C a p p u c c in o , H a lf C a f A m e r ic a n o ,<br />

C h o c o M a c c h ia t o , B a n a n a S p lit l n A C u p , PK „ ,<br />

fs;- В коф<strong>е</strong>йном магазин<strong>е</strong> много зам <strong>е</strong>-<br />

(-1схт<strong>е</strong>лк>ных напиткоб, и у каждого<br />

кли<strong>е</strong>нта ecmt> свой любимый.<br />

Вам п о тр<strong>е</strong>бу<strong>е</strong> тся м <strong>е</strong>тод, г<strong>е</strong> н <strong>е</strong> р и р у ю щ и й образц ы д а н н ы х:<br />

s t a t i c I E n u m e r a b le < S t a r b u z z D a t a > G e t S t a r b u z z D a t a () {<br />

r e t u r n ne w L i s t < S t a r b u z z D a t a > {<br />

ne w S t a r b u z z D a t a {<br />

Name = " J a n e t V e n u t i a n " , F a v o r i t e D r i n k = D r i n k . C h o c o M a c c h ia t o ,<br />

M o n e y S p e n t = 2 5 5 , V i s i t s = 50 ) ,<br />

{<br />

Name = " L i z N e l s o n " , F a v o r i t e D r i n k = D r i n k . D o u b le C a p p u c c in o ,<br />

M o n e y S p e n t = 1 5 0 , V i s i t s = 35 } ,<br />

ne w S t a r b u z z D a t a {<br />

Name = " M a t t F r a n k s " , F a v o r i t e D r i n k = D r in k . Z e s t y L e m o n C h a i,<br />

M o n e y S p e n t = 7 5 , V i s i t s = 15 } ,<br />

ne w S t a r b u z z D a t a {<br />

Name = " J o e N g " , F a v o r i t e D r i n k = D r i n k . B a n a n a S p l i t l n A C u p ,<br />

M o n e y S p e n t = 6 0 , V i s i t s = 10 } ,<br />

ne w S t a r b u z z D a t a {<br />

N a m e = " S a r a h K a l t e r " , F a v o r i t e D r i n k = D r i n k . B o r i n g C o f f e e ,<br />

M o n e y S p e n t = 1 1 0 , V i s i t s = 15 }<br />

М<strong>е</strong>тод сод<strong>е</strong>ржит в числ<strong>е</strong> проч<strong>е</strong>го ряд >яд им<strong>е</strong> <strong>е</strong>н из базы<br />

\ контактов бумажной компании. Если вы использу<strong>е</strong>-<br />

^ т<strong>е</strong> свои варианты им<strong>е</strong>н, позаботьт<strong>е</strong>сь о соопаа<strong>е</strong>ни<br />

ях в обоих списках.<br />

694 глава 15


UNQ<br />

О Со<strong>е</strong>дним базу SQL с колл<strong>е</strong>кци<strong>е</strong>й Starbuzz<br />

Э то код запроса. П о м <strong>е</strong> с ти т<strong>е</strong> <strong>е</strong>го в м <strong>е</strong>тод M a in ( ) :<br />

I E n u m e r a b l e < S t a r b u z z D a t a > s t a r b u z z L i s t = G e t S t a r b u z z D a t a ( ) ;<br />

s t r i n g c o n n e c t i o n S t r i n g =<br />

" D a t a S o u r c e = | D a t a D i r e c t o r y 1W C o n t a c t D B . s d f '<br />

C o n t a c t D B c o n t e x t = n e w C o n t a c t D B ( c o n n e c t i o n S t r i n g ) ;<br />

v a r r e s u l t s = ^<br />

f r o m s t a r b u z z C u s t o m e r i n s t a r b u z z L i s t<br />

Пр<strong>е</strong>длож<strong>е</strong>ни<strong>е</strong><br />

Т ира<strong>е</strong>т из w h e r e s t a r b u z z C u s t o m e r . M o n e y S p e n t > 9 0<br />

Starbuzz с данныАМА из т а<br />

SAUUjbt People-<br />

Чл<strong>е</strong>н Pecwle класса<br />

D atadontext -<br />

Sa3t>i данны<strong>е</strong><br />

oS им<strong>е</strong>ни и j o i n p e r s o n i n c o n t e x t . P e o p l e<br />

это колл<strong>е</strong>кция,<br />

ф ирм <strong>е</strong>, a из<br />

об<strong>е</strong>сп<strong>е</strong>чиваюи^ая<br />

колл<strong>е</strong>кции<br />

S t a r b u z z C u s t o m e r .N a m e e q u a l s p e r s o n . N a m e вас дост упом к<br />

Starbuzz оан-<br />

таблиц<strong>е</strong> People<br />

в баз<strong>е</strong> данных.<br />

MoM напит к<strong>е</strong> s e l e c t n e w { p e r s o n . N a m e , p e r s o n . C o m p a n y ,<br />

M объ<strong>е</strong>диня<strong>е</strong>т M<br />

их в р<strong>е</strong>зуль-'^-----------s t a r b u z z C u s t o m e r . F a v o r i t e D r i n k } ;<br />

f \ ^ *f-ZJ<br />

т ирую щ ую Пров<strong>е</strong>рьт<strong>е</strong> р<strong>е</strong>зульт а-<br />

nocAedoda-<br />

к Л Л 1 л .... . ...<br />

meAtiHocmb.<br />

me?/- ySedumecbj что<br />

f o r e a c h ( v a r r o w i n r e s u l t s )<br />

вс<strong>е</strong> работ а<strong>е</strong>т т ак/<br />

как " вы ' ожидали.<br />

C o n s o l e . W r i t e L i n e ( " { 0 } a t { 1 } l i k e s { 2 }<br />

r o w . N a m e , r o w . C o m p a n y , r o w . F a v o r i t e D r i n k ) ;<br />

C o n s o l e . R e a d K e y ( ) ;<br />

Пр<strong>е</strong>красная работа... благодаря<br />

р<strong>е</strong>кламной акции наш бизн<strong>е</strong>с<br />

пойд<strong>е</strong>т в гору. М и обязат<strong>е</strong>льно<br />

позвоним вам снова.<br />

„н сж рам <strong>е</strong>и м зава-<br />

„ р и м <strong>е</strong> и <strong>е</strong> и ч я L IN S _<br />

<strong>е</strong>!«ся UNO P““' “ ^<br />

скачать <strong>е</strong>го зд<strong>е</strong>сьk<br />

t t p y / w w w - I H P “«“' ’ ' * * ' '


Эндрю <strong>Стиллм<strong>е</strong>н</strong>, <strong>Дж</strong><strong>е</strong>нниф<strong>е</strong>р Гоин<br />

<strong>Изуча<strong>е</strong>м</strong> С#<br />

2-<strong>е</strong> издани<strong>е</strong><br />

П<strong>е</strong>р<strong>е</strong>в<strong>е</strong>ла с английского И. Рузмайкина<br />

Зав<strong>е</strong>дующий р<strong>е</strong>дакци<strong>е</strong>й<br />

Руководит<strong>е</strong>ль про<strong>е</strong>кта<br />

В<strong>е</strong>дущий р<strong>е</strong>дактор<br />

Худож<strong>е</strong>ств<strong>е</strong>нный р<strong>е</strong>дактор<br />

Корр<strong>е</strong>ктор<br />

В<strong>е</strong>рстка<br />

А. Кривцов<br />

Л. Юрч<strong>е</strong>нко<br />

Ю. С<strong>е</strong>рги<strong>е</strong>нко<br />

Л. Аду<strong>е</strong>вская<br />

Л. Казарина<br />

Л. Родионова<br />

ООО «Мир книг», 198206, Санкт-П<strong>е</strong>т<strong>е</strong>рбург, П<strong>е</strong>т<strong>е</strong>ргофско<strong>е</strong> шосс<strong>е</strong>, 73, лит. А29.<br />

Налоговая льгота — общ<strong>е</strong>российский классификатор продукции ОК 005-93, том 2;<br />

95 3005 — лит<strong>е</strong>ратура уч<strong>е</strong>бная.<br />

Подписано в п<strong>е</strong>чать 29.08.11. Формат 84x100/16. У<strong>е</strong>л. п. л. 72,24. Тираж 1500. Заказ 26278.<br />

Отп<strong>е</strong>чатано по т<strong>е</strong>хнологии О Р в ОАО «П<strong>е</strong>рвая Образцовая типография»,<br />

обосойл<strong>е</strong>нно<strong>е</strong> подразд<strong>е</strong>л<strong>е</strong>ни<strong>е</strong> «П<strong>е</strong>чатный двор».<br />

197110, Санкт-П<strong>е</strong>т<strong>е</strong>рбург, Чкаловский пр., 15.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!