Обратите внимание, что вызов метода Pattern
находится внутри охраняемого блока. Поэтому, когда Pattern не справится с обработкой исключительной ситуации, ее обработку возьмет на себя универсальный обработчик, стоящий за try-блоком. На рис. 23.6 показаны три варианта запуска метода TestPattern. в одном из них исключительной ситуации при вызове метода Pattern вообще не возникало, в другом — ситуация возникала, но коррекция обработчика исключения помогла и при повторе выполнения охраняемого блока в Pattern все прошло нормально. В третьем варианте метод Pattern не смог справиться с исключительной ситуацией, и она обрабатывалась в catch-блоке метода TestPattern.
Рис. 23.6.
Обработка исключительных ситуаций. Три случая
Класс Exception
Рассмотрим устройство базового класса Exception
, чтобы понять, какую информацию может получить обработчик исключения, когда ему передается объект, задающий текущее исключение. Основными свойствами класса являются:• Message
— строка, задающая причину возникновения исключения. Значение этого свойства устанавливается при вызове конструктора класса, когда создается объект, задающий исключение;• HeipLink
— ссылка (URL) на файл, содержащий подробную справку о возможной причине возникновения исключительной ситуации и способах ее устранения;• InnerException
— ссылка на внутреннее исключение. Когда обработчик выбрасывает новое исключение для передачи обработки на следующий уровень, то текущее исключение становится внутренним для вновь создаваемого исключения;• Source
— имя приложения, ставшего причиной исключения;• StackTrace
— цепочка вызовов — методы, хранящиеся в стеке вызовов в момент возникновения исключения;• Targetsite
— метод, выбросивший исключение.Из методов класса отметим метод GetBaseException
. При подъеме по цепочке вызовов он позволяет получить исходное исключение — первопричину возникновения последовательности выбрасываемых исключений.Класс имеет четыре конструктора, из которых три уже упоминались. Один из них — конструктор без аргументов, второй — принимает строку, становящуюся свойством Message, третий — имеет еще один аргумент: исключение, передаваемое свойству InnerException
.В предыдущий пример я внес некоторые изменения. В частности, добавил еще один аргумент при вызове конструктора исключения в catch-блоке метода Pattern;
throw(new MyException("Все попытки Pattern безуспешны", me));
В этом случае у создаваемого исключения заполняется свойство InnerExceptions
. Для слежения за свойствами исключений я добавил метод печати всех свойств, вызываемый во всех обработчиках исключений:static public void PrintProperties (Exception e)
{
Console.WriteLine("Свойства исключения: ");
Console.WriteLine("Targetsite = {0}", e.Targetsite);
Console.WriteLine("Source = {0}", e.Source);
Console.WriteLine("Message = {0}",e.Message);
if (e.InnerException == null)
Console.WriteLine("InnerException = null");
else Console.WriteLine("InnerException = {0}",
e. InnerException.Message);
Console.WriteLine("StackTrace = {0}", e.StackTrace);
Console.WriteLine("GetBaseException = {0}",
e. GetBaseException ());
}
Из-за громоздкости не привожу результаты, но отмечу, что они соответствуют описанию, приведенному в тексте лекции.
В заключение темы исключений хочу еще раз подчеркнуть, что корректное применение механизма исключений должно поддерживаться целенаправленными усилиями программиста. Следует помнить о двух важных правилах:
• обработка исключений должна быть направлена не столько на уведомление о возникновении ошибки, сколько на корректировку возникшей ситуации;
• если исправить ситуацию не удается, то программа должна быть прервана так, чтобы не были получены некорректные результаты, не удовлетворяющие спецификациям программы.
24. Организация интерфейса и рисование в формах