Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 79
Текст из файла (страница 79)
В частности, попробуйте закоммеитировать переопределение метода товтггпд () и понаблюдайте за результатами. Кроме того, попытайтесь создать исключение, используя конструктор, вызываемый по умолчанию, и посмотрите, какое сообщение при этом формируется стандартными средствами С(т. Перехват исключений производных классов При попытке перехватить типы исключений, относящихся как к базовым, так и к производиым классам, следует особенно внимательно соблюдать порядок следования операторов сассь, поскольку перехват исключения базового класса будет совпадать с перехватом исключений любых его производных классов. Например, класс Ехсерсгоп является базовым для всех исключений, и поэтому вместе с исключением типа ехсерсгоп могут быть перехвачены и все остальные исключения производных от него классов.
Конечно, для более четкого перехвата всех исключений можно воспользоваться упоминавшейся ранее формой оператора сассь без указания конкретного типа исключения. Но вопрос перехвата исключений производных классов становится весьма актуальным и в других ситуациях, особенно при создании собственных исключений. Если требуется перехватывать исключения базового и производного классов, то первым по порядку должен следовать оператор сагой, перехватывающий исключение производного класса.
Это правило необходимо соблюдать потому, что при перехвате исключеиия базового класса будут также перехвачены исключения всех производных от него классов. Правда, это правило соблюдается автоматически: если первым расположить в коде оператор сассь, перехватывающий исключение базового класса, то во время компиляции этого кода будет выдано сообщение об ошибке.
В приведенном ниже примере программы создаются два класса исключений: Ехсергд и Ехсерсв. Класс ЕхсертА является производным от класса Ехсергвоп, а класс ЕхсерС — производным от класса Ехсерсд. Затем в программе генерируются исключеиия каждого типа.
Ради краткости в классах специальных исключений предоставляется только один конструктор, принимающий символьную строку, описывающую исключение. Однако при разработке программ коммерческого назначения в классах специальных исключеиий обычно требуется предоставлять все четыре коиструктора, определяемых в классе Ехсерггоп. О Исключения производных классов должны появляться до О исключений базового класса. пзкпп Яузкеки // Создать класс исключения.
с1авз Ехсерсл: Ехсерккоп ( рпЬ1кс ЕхсерСА(вкгтпд зкг) : Ьазе(зкг) ( ) рпв11с очеггтбе зкгтпп тоякггпп() ( гекпгп Иевзадет Глава (Э. Обработка исключительных ситуаций 413 // Создать класс исключения, производный от класса Ехсерка. с1азв ЕхсерСВ : Ехсерса ( рив11с ЕхсерСВ(зкгапр зкг) : Ьазе(зкг) ( ) риЬ11с очегг1пе зкгапд тоЯСгапд()'( геспгп Меззадет ) ) с1азв Огоегнаксегз ( зкакгс чово Ма1п() ( Гог(апк х = От х < Зт х++) ( Сгу ( 1г(к==о) Спгон пен БхсерСА("Перехват исключения типа Ехсерза")т е1зе аг(х==1) сигов пен ехсергВ("перехват исключения типа БхсерсВ") е1зе Гнгон пен Бхсерк1оп()к ) саксь (Ехсеркв ехс) ( Сопзо1е.нгьсеЬапе(ехс)т саксп (Ехсеркл ехс) ( Сопзо1е.нг1ке11пе(ехс)т ) сакси (Ехсерзгоп ехс) ( Сопзо1е.нг1кешпе(ехс)т ) ) ) Вот к какому результату приводит выполнение этой программы: Перехват исключения типа ЕхсерСА.
Перехват исключения типа ЕхсерГВ. яузсею.ехсергьоп: Выдано исключение типа "яузсею.кхсерс1оп". в Огпегиаскегв.иахп() Обратите внимание на порядок следования операторов сасс)ь Именно в таком порядке они и должны выполняться. Класс ЕхсерСВ является производным от класса ЕхсерСА, поэтому исключение типа ЕхсерСВ должно перехватываться до исключения типа Ехсерсй. Аналогично, исключение типа ехсерс гоп (т.е. базового класса для всех исключений) должно перехватываться последним. Для того чтобы убедиться в этом, измените порядок следования операторов сасс)ь В итоге зто приведет к ошибке во время компиляции.
Полезным примером применения оператора саССЬ, перехватывающего исключения базового класса, служит перехват всей категории исключений. Допустим, что создается ряд исключений для управления некоторым устройством. Если сделать их классы производными от общего базового класса, то в тех приложениях, где необязательно выяснять конкретную причину возникшей ошибки, достаточно перехватывать исключение базового класса и тем самым исключить ненужное дублирование кода. 414 часть !. язык сз Применение ключевых слов спесЕей и ипспесЕей В языке С№ имеется специальное средство, связанное с генерированием исключений, возникающих при переполнении в арифметических вычислениях. Как вам должно быть уже известно, результаты некоторых видов арифметических вычислений могут превышать диапазон представления чисел для типа данных, используемого в вычислении.
В этом случае происходит так называемое переполнение. Рассмотрим в качестве примера следующий фрагмент кода: Ьусе а, Ь, гевп1»; а = 1277 Ь = 1277 гевн1Г = (Ьуке)(а * Ь) В этом коде произведение значений переменных а и Ь превышает диапазон представления чисел для типа Ьусе. Следовательно, результат вычисления данного выражения приводит к переполнению для типа данных, сохраняемого в переменной гезо1с. В языке С№ допускается указывать, будет ли в коде сгенерировано исключение при переполнении, с помощью ключевых слов сьес)сес( и ппсьесхей.
Так, если требуется указать, что выражение будет проверяться на переполнение, следует использовать ключевое слово спес)сес(, а если требуется проигнорировать переполнение — ключевое слово ппспес)сес(. В последнем случае результат усекается, чтобы не выйти за пределы диапазона представления чисел для целевого типа выражения. У ключевого слова спес)сес( имеются две общие формы. В одной форме проверяется конкретное выражение, и поэтому она называется операторной. А в другой форме проверяется блок операторов, и поэтому она называется блочной.
Ниже приведены обе формы. сьескес) (ехрг) спесхес( ( уу проверяемые операторы ) где ехрг обозначает проверяемое выражение. Если вычисление проверяемого выражения приводит к ((ереполнению, то генерируется исключение Оуе»11оыкхсер»1оп. У ключевого слова ппспес)сес( также имеются две общие формы. В первой, операторной форме переполнение игнорируется при вычислении конкретного выражения.
А во второй, блочной форме оно игнорируется при выполнении блока операторов. нпснескес( (екрг) ппсьесхес( ( // операторы, для которых переполнение игнорируется ) где ехр» обозначает выражение, при вычислении которого переполнение игнорируется. Если же в непроверяемом выражении происходит переполнение, то результат его вычисления усекается. Ниже приведен пример программы, в котором демонстрируется применение ключевых слов снес)сес( и опспесхесд Глава (3. Обработка исключительных ситуаций 415 // Продемонстрировать применение ключевых слов слепнет(и цпсиесхеб.
цеков Яузгепп с1аяз Спескепоеюо ( зсак1с чойс) Ма1п() ( путе а, Ьт Ьусе гезц1кт а = 127( Ь = 1277 ггу ( гезц1Г = цпспескеб( (Ьусе) (а * Ь) ) т сопзо1е.нгггеь1пе("непроверенный на переполнение результат: гезц1Г)т гезц1Г = спескет(((Ьусе)(а * Ь))т // эта операция // приводит к исключительной ситуации Сопяо1е.игхсевйпе("Проверенный на переполнение результат: гезц1Г)т // не подлежит выполнению ) сассп (Очегг1онЕхсерс1оп ехс) ( Сопзо1е.игасецйпе(ехс)т ) ) При выполнении этой программы получается следующий результат: Непроверенный на переполнение результат: 1 Яузсею.очегг1онЕхсерк1опх Переполнение в результате выполнения арифметической операции. в Спесхет(оеюо.Махи() Как видите, результат вычисления непроверяемого выражения был усечен.
А вычисление проверяемого выражения привело к исключительной ситуации. В представленном выше примере программы было продемонстрировано применение ключевых слов спесхет( и цпспесхес( в одном выражении. А в следующем примере программы показывается, каким образом проверяется и не проверяется на переполнение целый блок операторов: // Продемонстрировать применение ключевых слов спесхеб // и цпспесКеб в блоке операторов. ця1пс Яузгелц с1азя Спескет(В1осня ( ягаг1с чоюб ма|о() ( Ьусе а, Ь! Ьусе геяц1гт а = 1277 Ь = 127) ггу ( цпспескеб ( 416 Часть ).
Язык С() а = 127; Ь = 1277 геяи1С = ипспесьео((Ьуге)(а * Ь))7 Сопяо1е.игьгеьапе("Непроверенный на переполнение результат: " + геяи1с) т а = 1257 Ь=57 геяи1с = ипсьесхет(((ьусе) (а * ь) ) т Сопяо1е.нг1ге11пе("Непроверенный на переполнение результат". " + геяи1г) ) ) спескей ( а=2; Ь=7) геяи1С = сьескек(( (Ьусе) (а * Ь) ) т // верно Сопзо1е.ИгксеЬьпе("Провервнный на переполнение результат: геви1С) ) а = 127) Ь = 1277 геяи1Г = спескец((Ьуге)(а * Ь))т // зта операция // приводит к исключительной ситуации Сопзо1е.игусеЬ1пе("Проверенный на переполнение результат: геяи1Г)т // не подлежит выполнению ) ) сассЬ (Очегс1онЕхсерсаоп ехс) ( Сопяо1е.игкгеьапе(ехс)) ) Результат выполнения втой программы приведен ниже. Непроверенный на переполнение результат: 1 Непроверенный на переполнение результат: 113 Проверенньпт на переполнение результат: 14 зуясею.оиегт1онЕхсерсьоп: Переполнение в результате выполнения арифметической операции.
в Спескек)веюо.иа1п() Как видите, результаты выполнения непроверяемого на переполнение блока операторов были усечены. Когда же в проверяемом блоке операторов произошло переполнение, то возникла исключительная ситуация. Потребность в применении ключевого слова снес)кет) или ипспес)тес( может возникнуть, в частности, потому, что по умолчанию проверяемое или непроверяемое состояние переполнения определяется путем установки соответствующего параметра компилятора и настройки самой среды выполнения.