Защитные конструкции языка Object Pascal. Блок try..except.
Для работы с объектами исключительных ситуаций существуют специальные конструкции языка Object Pascal– блоки try, except и try..finally. Они контролируют выполнение операторов, помещенных внутри блока до ключевого слова except или finally. В случае возникновения исключительной ситуации штатное выполнение вашей программы немедленно прекращается, и управление передается операторам, идущим за указанными ключевыми словами. Если в вашей процедуре эти блоки отсутствуют, управление все равно будет передано ближайшему блоку, внутри которого возникла ситуация. А уж внутри VCL их предостаточно.
Хотя синтаксис двух видов блоков похож, но они принципиально отличаются назначением и решаемыми задачами. Поэтому вопрос, какой из них выбрать, не стоит: чтение нижеследующего материала, надеемся, убедит вас в пользе обоих.
Блок try..except
Для реакции на конкретный тип ситуации применяется блок try..except. Синтаксис его следующий:
try <Оператор> <Оператор> … except on EExceptionl do < Оператор обработки ИС типа EExceptionl >; on EException2 do < Оператор >; … else { } <Оператор> {обработчик прочих ИС} end;
Выполнение блока начинается с секции try. При отсутствии исключительных ситуаций только она и выполняется. Секция except получает управление в случае возникновения ИС. После обработки происходит выход из защищенного блока, и управление обратно в секцию try не передается; выполняются операторы, стоящие после end.
Если вы хотите обработать любую ИС одинаково, независимо от ее класса, вы можете писать код прямо между операторами except и end. Но если обработка отличается, здесь можно применять набор директив on..do, определяющих реакцию приложения на определенную ситуацию. Каждая директива связывает ситуацию (on…), заданную своим именем класса, с группой операторов (do…).
U: = 220.0; R: = 0; try I: = U / R; except on EZeroDivide do MessageBox('Короткое замыкание!'); end;
В этом примере замена if..then на try..except, может быть, не дала очевидной экономии кода. Однако если при решении, допустим, вычислительной задачи проверять на возможное деление на ноль приходится не один, а множество раз, то выигрыш от нового подхода неоспорим – достаточно одного блока try..except на все вычисления.
При возникновении ИС директивы просматриваются последовательно, в порядке их описания. Каждый тип исключительной ситуации, описанный после ключевого слова on, обрабатывается именно этим блоком: только то, что предусмотрено в нем, и будет являться реакцией на данную ситуацию.
Если при этом обработчик родительского класса стоит перед дочерним, последний никогда не получит управления.
try i: = l;j: = 0; k: = i div j; … except on EIntError do ShowMessage('IntError'); on EDivByZero do ShowMessage('DivByZero'); end;
В этом примере, хотя в действительности будет иметь место деление на ноль (EDivByZero), вы увидите сообщение, соответствующее родительскому классу EintError. Но стоит поменять две конструкции on..do местами, и все придет в норму.