Блок обработки исключений представляет собой либо последовательность операторов, разделенных точкой с запятой, либо последовательность обработчиков исключений вида
on имя : тип do оператор
Обработчики разделяются символом ';', после последнего обработчика также может следовать символ ';'. Здесь тип - тип исключения (должен быть производным от стандартного типа Exception), имя - имя переменной исключения (имя с последующим двоеточием может быть опущено). В первом случае при обработке исключения выполняются все операторы из блока except. Во втором случае среди обработчиков осуществляется поиск типа текущего исключения (обработчики перебираются последовательно от первого до последнего), и если обработчик найден, то выполняется соответствующий оператор обработки исключения, в противном случае исключение считается необработанным и передается объемлющему блоку try. В последнем случае после всех обработчиков onможет идти ветвь else, которая обязательно обработает исключение, если ни один из обработчиков не выполнился.
Следует обратить внимание, что имя переменной исключения в разных обработчиках может быть одинаковым, т.е. оно локально по отношению к обработчику.
Поиск типа исключения в обработчиках производится с учетом наследования: исключение будет обработано, если оно принадлежит к указанному в обработчике типу или производному от него. Поэтому принято записывать вначале обработчики производных классов, а затем - обработчики базовых (в противном случае обработчик исключения производного класса никогда не сработает). Обработчик исключения Exception обрабатывает все возможные исключения и поэтому должен быть записан последним.
Пример.
vara: array[1..10] ofinteger;
try
vari: integer;
readln(i);
writeln(a[i] divi);
...
except
onSystem.DivideByZeroException do
writeln('Деление на 0');
one: System.IndexOutOfRangeException do
writeln(e.Message);
onSystem.FormatException do
writeln('Неверный формат ввода');
elsewriteln('Какое-то другое исключение');
end;
Оператор try... finallyимеет вид:
try
операторы
finally
операторы
end;
Операторы в блоке finallyвыполняются безотносительно к тому, возникло или нет исключение в блоке try. При этом само исключение не обрабатывается.
Блок finallyиспользуется для возвращения ранее выделенных ресурсов.
Пример 1.Закрытие открытого файла.
reset(f);
try
...
finally
close(f);
end;
Файл будет закрыт независимо от того, произошло ли ислючение в блоке try.
Пример 2.Возвращение выделенной динамической памяти.
New(p);
try
...
finally
Dispose(p);
end;
Динамическая память, контролируемая указателем p, будет возвращена независимо от того, произошло ли ислючение в блоке try.
Оператор raiseпредназначен для возбуждения исключения и имеет вид:
raise объект
Здесь объект - объект класса, производного от Exception. Например:
raisenew Exception('Ошибка');
При возбуждении специфического исключения желательно определить свой тип исключения.
Для повторной генерации исключения внутри секции exceptиспользуется также вызов raiseбез параметров:
raise;
Операторы += и -= для процедурных переменных
Оператор присваивания += предназначен для присоединения к процедурной переменной процедуры, оператор присваивания -= - для отсоединения. Подпрограммы вызываются в порядке присоединения. Например:
proceduremult2( varr: real);
begin
r := 2 * r;
end;
procedureadd3( varr: real);
begin
r := r + 3;
end;
var
p: procedure( varx: real);
r: real;
begin
r := 1;
p := mult2;
p += add3;
p(r); // r := 2 * r; r := r + 3;
p -= mult2;
p(r); // r := r + 3;
end.
Отсоединение не присоединенных подпрограмм не выполняет никаких действий.
Кроме того, к процедурной переменной можно прикреплять/откреплять статические и экземплярные методы классов. Пример см. в теме процедурные переменные.
Операторы += и -= используются также для добавления/удаления обработчиков для событий .NET. Например:
Читать дальше