Г. Шилдт - Полный справочник по C# (1160789), страница 64
Текст из файла (страница 64)
Крометого, поскольку команды задаются словами, а не числами, маловероятно, что пользователь метода conveyor () по небрежности передаст неверное значение.В этом примере хотелось бы еще обратить ваше внимание вот на что. Тип перечисления используется здесь для управления switch-инструкцией. Как уже упоминалось, поскольку перечисления считаются целочисленными типами, их можно использовать в инструкции switch.348Часть I. Язык С#Полныйсправочник поОбработка исключительныхситуацийИсключительная ситуация (или исключение) — это ошибка, которая возникает вовремя выполнения программы. Используя С#-подсистему обработки исключительных ситуаций, с такими ошибками можно справляться.
Эта подсистема в С#включает в себя усовершенствованные методы, используемые в языках C++ и Java.Поэтому эта тема будет знакомой для C++- и Java-программистов. Однако обработкаисключений в С# отличается ясностью и полнотой реализации.Преимущество подсистемы обработки исключений состоит в автоматизации создания большей части кода, который ранее необходимо было вводить в программы"вручную". Например, в любом компьютерном языке при отсутствии такой подсистемы практически каждый метод возвращал коды ошибок, и эти значения проверялисьвручную при каждом вызове метода.
Такой подход довольно утомителен, кроме того,при этом возможно возникновение ошибок. Обработка исключений упрощает "работунад ошибками", позволяя в программах определять блок кода, именуемый обработчиком исключении, который будет автоматически выполняться при возникновении определенной ошибки.
В этом случае не обязательно проверять результат выполнения каждой конкретной операции или метода вручную. Если ошибка возникнет, ее должным образом обработает обработчик исключений.Еще одним преимуществом обработки исключительных ситуаций в С# являетсяопределение стандартных исключений для таких распространенных программныхошибок, как деление на нуль или попадание вне диапазона определения индекса.Чтобы отреагировать на возникновение таких ошибок, программа должна отслеживатьи обрабатывать эти исключения.Без знания возможностей С#-подсистемы обработки исключений успешное программирование на С# попросту невозможно.Класс System.ExceptionВ С# исключения представляются классами.
Все классы исключений должны бытьвыведены из встроенного класса исключений Exception, который является частьюпространства имен System. Таким образом, все исключения — подклассы классаException.Из класса Exception выведены классы SystemException и ApplicationException.Они поддерживают две общие категории исключений, определенные в С#: те, которыегенерируются С#-системой динамического управления, или общеязыковым средствомуправления (Common Language Runtime — CLR), и те, которые генерируются прикладными программами.
Но ни класс SystemException, ни класс ApplicationExceptionне привносят ничего нового в дополнение к членам класса Exception. Они простоопределяют вершины двух различных иерархий классов исключений.С#определяет встроенные исключения, которые выводятся из классаSystemException. Например, при попытке выполнить деление на нуль генерируетсяисключение класса DivideByZeroException. Как будет показано ниже в этой главе,вы сможете создавать собственные классы исключений, выводя их из классаApplicationException.Основы обработки исключенийУправление С#-механизмом обработки исключений зиждется на четырех ключевых словах: t r y , catch, throw и f i n a l l y .
Они образуют всзимосвязанную подсисте-350Часть I. Язык С#му, в которой использование одного из них предполагает использование другого. Вэтой главе каждое слово рассматривается подробно. Однако для начала будет полезнополучить общее представление о роли, которую они играют в обработке исключительных ситуаций. Если кратко, то их работа состоит в следующем.Программные инструкции, которые нужно проконтролировать на предмет исключений, помещаются в try-блок. Если исключение таки возникает в этом блоке, онодает знать о себе выбросом определенного рода информации.
Это выброшенное исключение может быть перехвачено программным путем с помощью catch-блока и обработано соответствующим образом. Системные исключения автоматически генерируютсяС#-системой динамического управления. Чтобы сгенерировать исключение вручную,используется ключевое слово throw. Любой код, который должен быть обязательновыполнен при выходе из try-блока, помещается в блок f i n a l l y .Использование t r y - и catch-блоковЯдром обработки исключений являются блоки t r y и catch. Эти ключевые словаработают "в одной связке"; нельзя использовать слово t r y без catch или catch безt r y .
Вот каков формат записи try/catch-блоков обработки исключений:try {// Блок кода, подлежащий проверке на наличие ошибок.}catch {ExcepTypel exOb) {// Обработчик для исключения типа ExcepTypel.}catch (ExcepType2 exOb) {// Обработчик для исключения типа ЕхсерТуре2.Здесь ЕхсерТуре — это тип сгенерированного исключения. После "выброса" исключение перехватывается соответствующей инструкцией catch, которая его обрабатывает.
Как видно и^ формата записи try/catch-блоков, с try-блоком может бытьсвязана не одна, а несколько catch-инструкций. Какая именно из них будет выполнена, определит тип исключения. Другими словами, будет выполнена та catchинструкция, тип исключения которой совпадает с типом сгенерированного исключения (а все остальные будут проигнорированы). После перехвата исключения параметрехОЬ примет его значение.Задавать параметр ехОЬ необязательно. Если обработчику исключения не нужендоступ к объекту исключения (как это часто бывает), в задании параметра ехОЪ нетнеобходимости.
Поэтому во многих примерах этой главы параметр ехОЪ не задан.Важно понимать следующее. Если исключение не генерируется, try-блок завершается нормально, и все его catch-инструкции игнорируются. Выполнение программы продолжается с первой инструкции, которая стоит после последней инструкцииcatch. Таким образом, catch-инструкция (из предложенных после try-блока) выполняется только в случае, если сгенерировано соответствующее исключение.Пример обработки исключенияНиже приведен простой пример, демонстрирующий, как отследить и перехватитьисключение. Известно, что попытка индексировать массив за пределами его границвызывает ошибку нарушения диапазона. В этом случае С#-система динамическогоуправления генерирует исключение типа indexOutOfRangeException, которое представляет собой стандартное исключение, определенное языком С#.
В следующейпрограмме такое исключение намеренно генерируется, а затем перехватывается.Глава 13. Обработка исключительных ситуаций351// Демонстрация обработки исключений,using System;c l a s s ExcDemol {p u b l i c s t a t i c void Main() {i n t [ ] nums = new i n t [ 4 ] ;try {Console.WriteLine("Перед генерированием исключения.");// Генерируем исключение, связанное с попаданием// индекса вне диапазона,for(int i=0; i < 10; i++) {nums[i] = i;Console.WriteLine("nums[{0}]: {1}", i, nums[i]);}Console.WriteLine("Этот текст не отображается.");}catch (IndexOutOfRangeException) {// Перехватываем исключение.Console.WriteLine("Индекс вне диапазона!");}Console.WriteLine("После catch-инструкции.");При выполнении этой программы получаем такие результаты:Перед генерированием исключения.nums[0]: 0nums[1]: 1nums[2]: 2nums[3]: 3Индекс вне диапазона!После catch-инструкции.Обратите внимание на то, что nums — это int-массив для хранения четырех элементов.
Однако в цикле for делается попытка индексировать этот массив от 0 до 9, икак только значение индекса устанавливается равным четырем, генерируется исключение типа IndexOutOfRangeException.Несмотря на небольшой размер, предыдущая программа иллюстрирует ряд ключевых аспектов обработки исключений. Во-первых, проверяемый код содержится внутри try-блока. Во-вторых, при возникновении исключения (в данном случае из-за попытки внутри for-цикла индексировать массив nums за границами его диапазона)выполнение try-блока прекращается, а само исключение перехватывается catch-инструкцией. Другими словами, управление программой передается catch-инструкции,независимо от того, все ли инструкции try-блока выполнились.
При этом важно то,что инструкция c a t c h не вызывается, а ей передается управление программой. Поэтому инструкция1 Console.WriteLine("После c a t c h - и н с т р у к ц и и . " ) ;никогда не выполнится. После выполнения catch-инструкции программа продолжится со следующей инструкции. Следовательно, чтобы ваша программа могла нормально продолжить свое выполнение, обработчик должен устранить проблему, которая стала причиной возникновения исключительной ситуации.352Часть I. Язык С#Обратите внимание на то, что в инструкции c a t c h параметр отсутствует.
Как упоминалось выше, параметр необходим только в тех случаях, когда требуется доступ кобъекту исключения. В некоторых случаях значение объекта исключения используетсяобработчиком для получения дополнительной информации об ошибке, но чаще всегодостаточно просто знать о том, что исключение имело место. Следовательно, в отсутствии catch-параметра в обработчике исключения нет ничего необычного, как в случае, проиллюстрированном предыдущей программой.Как уже упоминалось, если try-блоком исключение не сгенерировано, ни одна изcatch-инструкций не выполняется, и управление программой будет передано инструкции, следующей за catch-инструкцией.
Чтобы убедиться в этом, замените в предыдущей программе эту инструкцию f ог-цикла1 f o r ( i n t i = 0 ; i < 10; i++) {такой:I f o r ( i n t i = 0 ; i < nums.Length; i++) {Теперь цикл for не нарушает границы индексирования массива nums. Поэтомуисключение не генерируется, и catch-блок не выполняется.Второй пример исключенияВесь код, выполняемый внутри try-блока, проверяется на предмет возникновенияисключительной ситуации. Сюда также относятся исключения, которые могут сгенерировать методы, вызываемые из блока t r y .