Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 77
Текст из файла (страница 77)
Использование блока й~па11у Иногда требуется определить кодовый блок, который будет выполняться после выхода из блока сху/сасс)т. В частности, исключительная ситуация может возникнуть в связи с ошибкой, приводя)цей к преждевременному возврату из текущего метода.
Но в этом методе мог быть открыт файл, который нужно закрыть, или же установлено сетевое соединение, требующее разрывания. Подобные ситуации нередки в программировании, и поэтому для их разрешения в СЯ предусмотрен удобный способ; воспользоваться блоком Тупа11у. Для того чтобы указать кодовый блок, который будет выполняться после блока сву/сапой, достаточно вставить блок Тупа11у в конце последовательности операторов сгу/сасс)ь Ниже приведена общая форма совместного использования блоков Сгу/сабсп и Т1па11у. сгу ( // Блок кода, предназначенный для обработки ошибок.
пасть (ЕксерТуре1 ехОЫ ( // Обработчик исключения типа ЕхсерТуре1. сапов (ЕксерТуре2 ехОЫ ( // Обработчик исключения типа ЕксерТуре2. ) Гтпа11у ( // Код завершения обработки исключений. ) Блок ТТпа11у будет выполняться всякий раз, когда происходит выход из блока Сгу/ саесп, независимо от причин, которые к этому привели. Это означает, что если блок сгу завершается нормально или по причине исключения, то последним выполняется код, Глава (3. Обработка исключительных ситуаций 403 определяемый в блоке 11па11у.
Блок 11па11у выполняется и в том случае, если любой код в блоке сгу или в связанных с ним блоках саьсь приводит к возврату из метода. Ниже приведен пример применения блока Еапа11у. // использовать блок Гапа11у. пятпч Зуякеш; с1аяя Пяеуапа11у ( роЬ11с ясак1с чотт) ЯепЕхсерк1оп(апк ипат) ( апк С; кис[) поше = пеи лиг[2[; Сопяо1е.нгакепапе("Получить " + ипат)т ггу ( янт.сон (ипас) ( саяе О: Г = 10 / иЬаст // сгенерировать ошибку из-за деления на нуль Ьгеант саяе 1т пошл[4[ = 4т // сгенерировать ошибку индексирования массива Ьгеа)тт саяе 2".
гегогпт // возврат иэ блока Сгу ) саксп (Пач1бевузегоЕхсеркаоп) ( сопяо1е.игггетапе("делить на нуль нельзя!"); гегогпт // возврат из блока сассь ) саксп (1пбехопкогкапчеЕхсеркгоп) ( Сопяо1е.игтке11пе("Подходящий элемент не найден.")т ) Еапа11у ( Сопяо1е.нг1кепапе("После выхода иэ блока Ггу.")т ) с1аяя угпа11уоешо [ ясасас чолн иаап() ( Гог(хпо 1=0; 1 < Зт 1чч) ( Пяер1па11у.пепкхсерк1оп(г)т Сопяо1е.Иг1се11пе(); ) ) ) Вот к какому результату приводит выполнение этой программы: Получить О Делить на нуль нельзя После выхода из блока Сгу. 404 часть (, Язык С№ Получить 1 Подходящий элемент не найден. После выхода из блока Сгу. Получить 2 после выхода из блока ггу. Как следует из приведенного выше результата, блок Т1па11у выполняется независимо от причины выхода из блока ггу.
И еше одно замечание: с точки зрения синтаксиса блок т1па11у следует после блока ггу, и формально блоки сагсп для этого не требуются. Следовательно, блок г1па11у можно ввести непосредственно после блока сгу, опустив блоки сассп. В этом случае блок 11па11у начнет выполняться сразу же после выхода из блока ггу, но исключения обрабатываться не будут.
Подробное рассмотрение класса жхсерйхоп В приведенных выше примерах исключения только перехватывались, но никакой сушественной обработке они не подвергались. Как пояснялось выше, в операторе сагой допускается указывать тип и переменную исключения. Переменная получает ссылку на объект исключения. Во всех исключениях поддерживаются члены, определенные в классе Ехсер11оп, поскольку все исключения являются производными от этого класса. В этом разделе будет рассмотрен ряд наиболее полезных членов и конструкторов класса ехсерг1оп и приведены конкретные примеры применения переменной исключения.
В классе Ехсерстоп определяется ряд свойств. К числу самых интересных относятся три свойства; незвале, Ягасхтгасе и ТагдеСЯ1се. Все эти свойства доступны только для чтения. Свойство незваное содержит символьную строку, описываюШую характер ошибки; свойство Ягас)ктгасе — строку с вызовами стека, приведшими к исключительной ситуации, а свойство тагдегЯ1ге получает объект, обозначающий метод, сгенерировавший исключение.
Кроме того, в классе Ехсерг1оп определяется ряд методов. Чаще всего приходится пользоваться методбм тозсг1пд (), возвращающим символьную строку с описанием исключения. Этот метод автоматически вызывается, например, при отображении исключения с помощью метода Нгтсеттпе () . Применение всех трех упомянутых выше свойств и метода из класса ЕхсерС1оп демонстрируется в приведенном ниже примере программы. // использовать члены класса Ехсерс1оп. цятпч Яуясещ; с1аяя ЕхсТеяс ( рцп11с ясастс чогй Пепкхсерс1оп() ( гпс[) пцщя = лен 1пс[ч); Сопво1е.иг1седтпе("До генерирования исключения.") // Сгенерировать исключение в связи с выходом // на границы массива.
Глава )3. Обработка исключительнмк ситуаций 405 Ток(1пк 1=от 1 < 10т 1++) ( пощя (г] = 1; Сопяо1е.Иг1ке),1пе("пшля((0)]т (1)", )., пцюя().]); ) сопяо1е.игтсеьгпе("не подлежит выволу")," ] ) с1аяя ОяеЕхсерк ( якак1с чогб Ма1п() ( лгу ( Бхстеяс.пепехсерггоп()т ) саков (тпбехбцсблнапдекхсерс1оп ехс) ( Сопяо1е.иг1кепйпе("Стандартное сообщение таково: "); Сопяо1е.нг1кетйпе(ехс)т // вызвать метод ТоЯСггпд() Сопяо1е.Игввет ьпе("Свойство ЯсасхТгасе: ехс.ягасктгасе)) Сопяо1е.нг1кенйпе("Свойство Меяяаде: ехс.Меяяаде)т Сопяо1е.иг1кетйпе("Свойство Тагдекзгкет " + ехс.тагдек51ке)т ) Сопяо1е.иг1кетйпе("После блока перехвата исключения."); ) При выполнении этой программы получается следующий результат; До генерирования исключения.
тизля (0]: 0 плюя (1]: 1 пчщ~ (2]: 2 ппюя (3): 3 Стандартное сообщение таково: Яуясею.тпт)ехбпкблнапдеЕхсерк1оп: Индекс находился вне границ массива. в Ехстеяк.депкхсерс1оп() в ПяеЕхсерс.на).п() Свойство ЯкасКТгасет в Ехстеяк.депЕхсерп1оп О в ПяеЕхсерг.магп() Свойство Меяваде: Индекс находился вне границ массива. Свойство Тагдек51кет Чотб депнхсерк1оп() После блока перехвата исключения. В классе Ехсерк1оп определяются четыре следующих конструктора: рцЫгс Ехсерк1оп() рцЫгс Ехсервгоп(явг1пд ясг) роЫ1с Ехсерк1оп(ягг1пд ялг, Ехсерк1оп гппег) ргопескеб Ехсерс1оп( Яуякею.нопкмле.зегга1глак1оп.5егга11гакгоптпто я1, яуякею.аопк1ще.Яег1а11гак1оп.япгеаю1пдсопсехк яс) 406 часть е Язык Сз Первый конструктор используется по умолчанию. Во втором конструкторе указывается строка зСг, связанная со свойством меззаде, которое имеет отношение к геиерируемому исключению.
В третьем конструкторе указывается так называемое внутреннее исключение. Этот конструктор используется в том случае, когда одно исключение порождает другое, причем Елпег обозначает первое исключение, которое будет пустым, если внутреннее исключение отсутствует. (Если внутреннее исключение присутствует, то оио может быть получено из свойства 1ппегкхсергъоп, определяемого в классе Ехсерк1опа И последний коиструктор обрабатывает исключения, происходящие дистанционно, и позтому требует десериализации. Следует также заметить, что в четвертом конструкторе класса Ехсеркьоп типы Яегуа11кагъоп1пго и ЯкгеатъпдСопкехк относятся к пространству имен Яузкем.
Ецпгыпе.зег1а11хак1оп, Наиболее употребительные исключения В пространстве имен Яузсет определено несколько стандартных, встроенных исключеиий. Все эти исключения являются производными от класса Яузсепкхсерсъоп, поскольку оии генерируются системой СЕВ при появлении ошибки во время выполнения. В табл. 13.1 перечислены некоторые наиболее употребительные стандартные исключения. Таблица 13.1.
Наиболее употребительные исключения, определенные а простран- стве имен ауееею Исключение Зиачеиие лггаутуреиьввюсспехсерсьол тип сохраняемого значения несовместим с типом массива О1у1беаузегокхсерс1оп тлбехоикогпалчеехсеркъоп 1луа11боавСЕхсеркьоп ОокотиеиогуЕхсеркъоп Попытка деления иа нуль Индекс оказался за границами массива Неверно выполнено динамическое приведение типов Обращение к оператору леи оказалось неудачным из-за недо- статочиого объема свободной памяти Произошло арифметическое переполнение Оуегт1оиЕхсеркьол Мо11ветегепсеЕхсеркьоп Попытка использовать пустую ссылку, т.е. ссылку, которая ие указывает ии иа один из объектов Якасхоуегт1оикхсерк1ол Переполнение стека // Продемонстрировать обработку исключения Ко11аетегелсеЕхсеркъол.
ивзпд Яувкекп Большинство исключений, приведенных в табл. 13.1, ие требуют особых пояснений, кроме исключеиия Ец11пе ГегепсеЕхсергъоп. Это исключение генерируется при попытке использовать пустую ссылку иа несуществующий объект, например, при вызове метода по пустой ссылке.
Пустой называется такая ссылка, которая ие указывает ии иа один из объектов. Для того чтобы создать такую ссылку, достаточно, например, присвоить явным образом пустое значение переменной ссьпочиого типа, используя ключевое слово пп11.
Пустые ссылки могут также появляться и другими, менее очевидными путями. Ниже приведен пример программы, демонстрирующий обработку исключения Ец11пегегепсеЕхсерсъоп. Глава 13. Обработка исключительных ситуаций 407 с1аяя Х ( 1пк хт рцх11с Х(гпс а) ( х = ат ) рцптгс гпг Лоб(Х о) ( гесцгп х + о.хт ) // Продемонстрировать генерирование и обработку // исключения Иц11негегелсеЕхсерктол. с1аяя ИКЕПешо ( якак1с чо1б Иа1п() ( Х р = лен Х(10); Х ч = пц11т // присвоить явным образом пустое/ значение переменной ч 1пк ча1т сгу ( ча1 = р.абб(Ч); // зта операция приведет к // исключительной ситуации ) салоп (Иц11негегепсекхсерк1оп) [ Сопяо1е.нггкетапе( "Исключение Иц11нетегелсеЕхсерк1оп(") Соляо1е.Игтгеьхле ("ошибки...
1п") т // й теперь исправить ошибку. Ч = пен Х(9)т ча1 = р.лсЫ (Ч)' Сопяо1е.нгасеьгпе("Значение ча1 равна (О)", ча1)т 1 ) Вот к какому результату приводит выполнение этой программы: Исключение Иц11кегегепсекхсерс1оп( Исправление ошибки... Значение ча1 равно 19 В приведенном выше примере программы создается класс Х, в котором определяются член х и метод аЫ (), складываюший значение члена х в вызываюшем объекте со значением члена х в объекте, передаваемом этому методу в качестве параметра.
Оба объекта класса Х создаются в методе Иайп () . Первый из них (переменная р) инициализируется, а второй (переменная с() — нет. Вместо этого переменной с( присваивается пустое значение. Затем вызывается метод р. йсЫ () с переменной с( в качестве аргумента. Но поскольку переменная с( не ссылается ни на один из объектов, то при попытке получить значение члена с(. х генерируется исключейие Иц11неГегепсенхсерс1оп. Особый интерес представляет исключение зсасхочегГ1оиехсерс1оп,генерируемое при переполнении стека.