Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 74
Текст из файла (страница 74)
В качестве примера ниже задается тип Ьуее для перечисления Арр1е. еппи Лрр1е: Ьуке ! Юопакпап, Со1беппе1, Кебпе1, Напезар, Сокк1апб, МС1пкозЬ 1," Теперь константа лрр1е. И1пезар, например, имеет значение типа ьусе. Цвет сорта Цвет сорта Цвет сорта цвет сорта Цвет сорта Цвет сорта допашап 60!беппе! Пебое! ттг!п евер Сот!!апб МскйоеЬ Глава 12. Интерфейсы, структуры и перечисления 386 допакпап — красный Со1беппе1 — желтый Кебпе1 — красный иапзар — красный Сокк1апб — красный Мстпкозп — красновато-зеленый 366 часть (. язык са Применение перечислений На первый взгляд перечисления могут показаться любопытным, но не очень важным элементом С№, но на самом деле зто не так. Перечисления очень полезны, когда в программе требуется одна или несколько специальных символически обозначаемых констант.
Допустим, что требуется написать программу для управления лентой конвейера на фабрике. Для этой цели можно создать метод сопчеуог (), принимающий в качестве параметров следующие команды: "старт", "стоп", "вперед" и "назад". Вместо того чтобы передавать методу сопчеуог () целые значения, например, 1 — в качестве команды "старт", 2 — в качестве команды "стоп" и так далее, что чревато ошибками, можно создать перечисление, чтобы присвоить этим значениям содержательные символические обозначения. Ниже приведен пример применения такого подхода. // Сымитировать управление лентой конвейера.
ив1пд Яувгетт с1авв Сопчеуогсопгго1 ( // Перечислить команды конвейера. роЬ11с епии Ассаоп ( Ясагс, 5сор, Гогнаго, аечегве )) роЬ11с чо1к( Сопчеуог(ассаоп сов) ( внагсп(сои) ( саве Ассаоп.5гагс: сопво1е.хгагепвпе("запустить конвейер.")," Ьгеак; саве Ассаоп.зсор: Сопво1е.игагеввпе("Остановить конвейер."); Ьгеа)тт саяе Ассаоп.Гогнаго: Сопво1е.ыгасеЬтпе("Переместить конвейер вперед."); Ьгеах) саве Ассаоп.аечегве: Сопво1е.игагеввпе("Переместить конвейер назад.")~ Ьгеа)тт с1авв Сопчеуогпеио ( вгас1с чотп Мазо() ( СопчеуогСопсго1 с = лен СопчеуогСопсго1(); с.Сопчеуог(СопчеуогСопгго1.Ассаоп.эгагк)т с.Сопчеуог(СопчеуогСопкго1.Ассаоп.Гогнагп) с.сопчеуог(сопчеуогсопгго1.Асс1оп.аечегве) с.Сопчеуог(СопчеуогСопгго1.Ассаоп.эсор)т Вот к какому результату приводит выполнение этого кода; Запустить конвейер. Переместить конвейер вперед.
Глава 12. Интерфейсы, структуры и перечислении 387 Переместить конвейер назад. Остановить конвейер. Метод сопчеуог () принимает аргумент типа йссйоп, и поэтому ему могут быть переданы только значения, определяемые в перечислении йст1оп. Например, ниже приведена попытка передать методу сопчеуог () значение 22. с.Сопчеуог(22)," // Ошибка! Эта строка кода ие будет скомпилироваиа, поскольку отсутствует предварительно заданное преобразование типа 1пг в перечислимый тип )ГОС1оп.
Именно это и препятствует передаче неправильных команд методу сопчеуог () . Конечно, такое преобразование можно организовать принудительно с помощью приведения типов, ио это было бы преднамеренным, а ие случайным или неумышленным действием. Кроме того, вероятность неумышленной передачи пользователем неправильных команд методу Сопчеуот () сводится с минимуму благодаря тому, что эти команды обозначены символическими именами в перечислении. В приведенном выше примере обращает иа себя внимание еще одно интересное обстоятельство: перечислимый тип используется для управления оператором зи1СО)т.
Как упоминалось выше, перечисления относятся к целочисленным типам данных, и поэтому их вполне допустимо использовать в операторе эи1сс)к ГЛАВА Обработка исключительных ситуаций сключительяая ситуация, или просто исключение, происходит во время выполне- О ния. Используя подсистему обработки исключительных ситуаций в С№, можно обрабатывать структурированным и контролируемым образом ошибки, возникающие при выполнении программы.
Главное преимущество обработки исключительных ситуаций заключается в том, что она позволяет автоматизировать получение большей части кода, который раньше приходилось вводить в любую крупную программу вручную для обработки ошибок. Так, если программа написана на языке программирования без обработки исключительных ситуаций, то при неудачном выполнении методов приходится возвращать коды ошибок, которые необходимо проверять вручную при каждом вызове метода. Это не только трудоемкий, но и чреватый ошибками процесс.
Обработка исключительных ситуаций рационализирует процесс обработки ошибок, позволяя определить в программе блок кода, называемый обработчиком исключений и выполняющийся автоматически, когда возникает ошибка. Это избавляет от необходимости проверять вручную, насколько удачно или неудачно завершилась конкретная операция либо вызов метода. Если возникнег ошибка, она будет обработана соответствующим образом обработчиком ошибок.
Обработка исключительных ситуаций важна еще и потому, что в С№ определены стандартные исключения для типичных программных ошибок, например деление на нуль или выход индекса за границы массива. Для реагирования на подобные ошибки в программе должно быть организовано отслеживание и обработка соответствующих исключительных ситуаций. Ведь в конечном счете для успешного программирования на С№ необходимо научиться умело пользоваться подсистемой обработки исключительных ситуаций.
КЛЭСС Зу81ет. Ехсер~хоп В языке С№ исключения представлены в виде классов. Все классы исключений должны быть производными от встроенного в С№ класса ехсерсГоп, являющегося частью пространства имен яузсев. Следовательно, все исключения являются подклассами класса Ехсерггоп. 390 Часть!. Язык С№ К числу самых важных подклассов ехсерс1оп относится класс Бузсешехсерс1оп. Именно от этого класса являются производными все исключения, генерируемые исполняющей системой С№ (т.е. системой Ск.кк).-класс БузсешЕхсерс1оп ничего ие добавляет к классу Ехсереуоп, а просто определяет вершину иерархии стандартных исключений. В среде .НЕТ г гашетчог)к определено несколько встроенных исключений, являющихся производными от класса Б узсешехсерсуоп.
Например, при попытке выполнить деление иа нуль геиерируегся исключение ()1ч1к(евуеегоехсерс1оп. как будет показано далее в этой главе, в С№ можно создавать собственные классы исключений, производные от класса Ехсергуоп. Основы обработки исключительных ситуаций Обработка исключительных ситуаций в С№ организуется с помощью четырех ключевых слов: сгу, сассп, спгон и 11па11у. Оии образуют взаимосвязанную подсистему, в которой применение одного из ключевых слов подразумевает применение другого.
На протяжении всей этой главы назначение и применение каждого из упомянутых выше ключевых слов будет рассмотрено во всех подробностях. Но прежде необходимо дать общее представление о роли каждого из иих в обработке исключительных ситуаций. Поэтому ниже кратко описан принцип их действия. Применение пары ключевых слов ~ху и са~сЬ Основу обработки исключительных ситуаций в С№ составляет пара ключевых слов сгу и пасс)т.
Эти ключевые слова действуют совместно и ие могут быть использованы порознь. Ниже приведена общая форма определения блоков сгу/пасс)т для обработки исключительных ситуаций. ску ( // Блок кода, проверявший на наличие ошибок. ) свесь (Бхсертуре1 ехОЬ) ( // Обработчик исключения типа Ехсертуре1. ) сапов (ЕхсерТуре2 ехОЬ) ( // Обработчик исключения типа ЕхсерТуре2. ) где Ехсертуре — это тип возникающей исключительной ситуации. Когда исключение генерируется оператором с ту, оио перехватывается составляющим ему пару оператором сасс)т, который затем обрабатывает это исключение. В зависимости от типа исключения выполняется и соответствующий оператор сасс)т.
Так, если типы генерируемого исключеиия и того, что указывается в операторе саго)т, совпадают, то выполняется именно этот оператор, а все остальные пропускаются. Когда исключение перехватывается, переменная исключения ехОЬ получает свое значение. Глава (3. Обработка исключительных ситуаций 391 На самом деле указывать переменную ехОЬ необязательно. Так, ее иеобязательио указывать, если обработчику исключений требуется доступ к объекту исключения.
Для обработки исключения достаточно и его типа. Именно поэтому во многих примерах программ, приведенных в этой главе, переменная ехОЬ опускается. Следует, однако, иметь в виду, что если исключение ие генерируется, то блок оператора сгу завершается как обычно и все его операторы сасс]т пропускаются. Выполнение программы возобновляется с первого оператора, следующего после завершающего оператора сакс(ь Таким образом, оператор сасс]т выполняется лишь в том случае, если геиерируется исключение.
Простой пример обработки исключительной ситуации Рассмотрим простой пример, демоистрирующий отслеживание и перехватывание исключеиия. Как вам должно быть уже известно, попытка индексирования массива за его границами приводит к ошибке. Когда возникает подобная 'ошибка, система С].В геиерирует исключение 1пбехбцСОгкапцеЕхсертхоп, которое определено как стандартное для среды .]ч[ЕТ Ргашетчог](. В приведенной ниже программе такое исключение генерируется намеренно и затем перехватывается.
// Продемонстрировать обработку исключительной ситуации. цайпд зузкевт с1азз Ехсбево1 ( зкак1с чотб паап() ( 1пс [] пцвз = пен Епк [4] агу ( Сопзо1е.икакетвпе("До генерирования исключения.") // Сгенерировать исключение в связи с выходом // индекса за границм массива. ток(апс 1=01 1 < 10; 1++) ( пцвз(1] = 1) Сопзо1е.иг1се11пе("пцвз[(0)]: (1]", 1, пцва(1]) Сопзо1е.иг1кевапе("Не подлежит выводу"); сакс)т (1пбехбцкоткапдеЕхсерс1оп) ( // Перехватить исключение. Сопзо1е.игаке11пе("Индекс вышел за границы массива)")т Сопзо1е.Ик1кеьапе("После блока перехвата исключения."); ) При выполнении этой программы получается следующий результат: до генерирования исключения. повн[0]: 0 пцвз[1]: 1 392 Часть 3.
Язык О№ (г): г пцшв(3): 3 индекс вышел эа границы массива! После блока перехвата исключения. В данном примере массив типа ъпт. состоит из четырех элементов. Но в цикле гог предпринимается попытка проиндексировать этот массив от О до 9, что и приводит к появлению исключения 1пг(ех00001капдепхсерсъоп, когда происходит обращение к элементу массива по индексу 4.
Несмотря на всю свою краткость, приведенный выше пример наглядно демонстрирует ряд основных моментов процесса обработки исключительных ситуаций. Во-первых, код, который требуется контролировать на. наличие ошибок, содержится в блоке сгу. Во-вторых, когда возникает исключительная ситуация (в данном случае — при попытке проиндексировать массив пцшв за его границами в цикле гол), в блоке с ту генерируется исключение, которое затем перехватывается в блоке сассп. В этот момент выполнение кода в блоке сгу завершается и управление передается блоку сассп.
Это означает, что оператор сассП не вызывается специально, а выполнение кода переходит к нему автоматически. Следовательно, оператор, содержащий метод игьгеь1пе [) и следующий непосредственно за циклом гог, где происходит выход индекса за границы массива, вообще не выполняется. А в задачу обработчика исключений входит исправление ошибки, приведшей к исключительной ситуации, чтобы продолжить выполнение программы в нормальном режиме. Обратите внимание на то, что в операторе сассп указан только тип исключения (в данном случае — 1п<(ехОцСОгпапдепхсерг1оп), а переменная исключения отсутствует.