Добавить в цитаты Настройки чтения

Страница 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(&quot;До генерирования исключения.&quot;);</b>

<b>      // Сгенерировать исключение в связи с выходом</b>

<b>      // индекса за границы массива.</b>

<b>      for(int i=0; i &lt; 10; i++) {</b>

<b>        nums[i] = i;</b>

<b>        Console.WriteLine(&quot;nums[{0}]: {1}&quot;, i, nums[i]);</b>

<b>      }</b>

<b>      Console.WriteLine(&quot;He подлежит выводу&quot;);</b>

<b>    }</b>

<b>    catch (IndexOutOfRangeException) {</b>

<b>      // Перехватить исключение.</b>

<b>      Console.WriteLine(&quot;Индекс вышел за границы массива!&quot;);</b>

<b>    }</b>

<b>    Console.WriteLine(&quot;После блока перехвата исключения.&quot;);</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.