. Стиллмен, Дж. Грин - Изучаем 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.