Страница 185 из 502
Основы обработки исключительных ситуаций
Обработка исключительных ситуаций в C# организуется с помощью четырех ключевых слов: try, catch, throw и finally. Они образуют взаимосвязанную подсистему, в которой применение одного из ключевых слов подразумевает применение другого. На протяжении всей этой главы назначение и применение каждого из упомянутых выше ключевых слов будет рассмотрено во всех подробностях. Но прежде необходимо дать общее представление о роли каждого из них в обработке исключительных ситуаций. Поэтому ниже кратко описан принцип их действия.
Операторы программы, которые требуется контролировать на появление исключений, заключаются в блок try. Если внутри блока try возникает исключительная ситуация, генерируется исключение. Это исключение может быть перехвачено и обработано каким-нибудь рациональным способом в коде программы с помощью оператора, обозначаемого ключевым словом catch. Исключения, возникающие на уровне системы, генерируются исполняющей системой автоматически. А для генерирования исключений вручную служит ключевое слово throw. Любой код, который должен быть непременно выполнен после выхода из блока try, помещается в блок finally.
Основу обработки исключительных ситуаций в C# составляет пара ключевых слов try и catch. Эти ключевые слова действуют совместно и не могут быть использованы порознь. Ниже приведена общая форма определения блоков try/catch для обработки исключительных ситуаций:
<b>try {</b>
<b>// Блок кода, проверяемый на наличие ошибок.</b>
<b>} catch <i>(ExcepTypel exOb) {</i></b>
<b>// Обработчик исключения типа <i>ExcepTypel. }</i></b>
<b>catch (<i>ЕхсерТуре2 exOb)</i> {</b>
<b>// Обработчик исключения типа <i>ЕхсерТуре2.</i> }</b>
где ЕхсерТуре — это тип возникающей исключительной ситуации. Когда исключение генерируется оператором try, оно перехватывается составляющим ему пару оператором catch, который затем обрабатывает это исключение. В зависимости от типа исключения выполняется и соответствующий оператор catch. Так, если типы генерируемого исключения и того, что указывается в операторе catch, совпадают, то выполняется именно этот оператор, а все остальные пропускаются. Когда исключение перехватывается, переменная исключения exOb получает свое значение.
На самом деле указывать переменную exOb необязательно. Так, ее необязательно указывать, если обработчику исключений не требуется доступ к объекту исключения, что бывает довольно часто. Для обработки исключения достаточно и его типа. Именно поэтому во многих примерах программ, приведенных в этой главе, переменная exOb опускается.
Следует, однако, иметь в виду, что если исключение не генерируется, то блок оператора try завершается как обычно, и все его операторы catch пропускаются. Выполнение программы возобновляется с первого оператора, следующего после завершающего оператора catch. Таким образом, оператор catch выполняется лишь в том случае, если генерируется исключение.
Рассмотрим простой пример, демонстрирующий отслеживание и перехватывание исключения. Как вам должно быть уже известно, попытка индексировать массив за его границами приводит к ошибке. Когда возникает подобная ошибка, система CLR генерирует исключение IndexOutOfRangeException, которое определено как стандартное для среды .NET Framework. В приведенной ниже программе такое исключение генерируется намеренно и затем перехватывается.
<b>// Продемонстрировать обработку исключительной ситуации.</b>
<b>using System;</b>
<b>class ExcDemol {</b>
<b> static void Main() {</b>
<b> int[] nums = new int [4];</b>
<b> try {</b>
<b> Console.WriteLine("До генерирования исключения.");</b>
<b> // Сгенерировать исключение в связи с выходом</b>
<b> // индекса за границы массива.</b>
<b> for(int i=0; i < 10; i++) {</b>
<b> nums[i] = i;</b>
<b> Console.WriteLine("nums[{0}]: {1}", i, nums[i]);</b>
<b> }</b>
<b> Console.WriteLine("He подлежит выводу");</b>
<b> }</b>
<b> catch (IndexOutOfRangeException) {</b>
<b> // Перехватить исключение.</b>
<b> Console.WriteLine("Индекс вышел за границы массива!");</b>
<b> }</b>
<b> Console.WriteLine("После блока перехвата исключения.");</b>
<b> }</b>
<b>}</b>
При выполнении этой программы получается следующий результат.
<b>До генерирования исключения.</b>
<b>nums[0]: 0</b>
<b>nums[1]: 1</b>
<b>nums[2]: 2</b>
<b>nums[3]: 3</b>
<b>Индекс вышел за границы массива!</b>
<b>После блока перехвата исключения.</b>
В данном примере массив nums типа int состоит из четырех элементов. Но в цикле for предпринимается попытка проиндексировать этот массив от 0 до 9, что и приводит к появлению исключения IndexOutOfRangeException, когда происходит обращение к элементу массива по индексу 4.