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

Страница 188 из 502

Обработка исключительных ситуаций - “изящный” способ устранения программных ошибок

Одно из главных преимуществ обработки исключительных ситуаций заключается в том, что она позволяет вовремя отреагировать на ошибку в программе и затем продолжить ее выполнение. В качестве примера рассмотрим еще одну программу, в которой элементы одного массива делятся на элементы другого. Если при этом происходит деление на нуль, то генерируется исключение DivideByZeroException. Обработка подобной исключительной ситуации заключается в том, что программа уведомляет об ошибке и затем продолжает свое выполнение. Таким образом, попытка деления на нуль не приведет к аварийному завершению программы из-за ошибки при ее выполнении. Вместо этого ошибка обрабатывается "изящно", не прерывая выполнение программы.

<b>// Изящно обработать исключительную ситуацию и продолжить выполнение программы.</b>

<b>using System;</b>

<b>class ExcDemo3 {</b>

<b>  static void Main() {</b>

<b>    int[] numer = { 4, 8, 16, 32, 64, 128 };</b>

<b>    int[] denom = { 2, 0, 4, 4, 0, 8 };</b>

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

<b>      try {</b>

<b>        Console.WriteLine(numer[i] + &quot; / <sup>&quot;</sup> +</b>

<b>        denom[i] + <sup>&quot;</sup> равно <sup>&quot;</sup> +</b>

<b>        numer[i]/denom[i]);</b>

<b>      }</b>

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

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

<b>        Console.WriteLine(&quot;Делить на нуль нельзя!&quot;);</b>

<b>      }</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

Ниже приведен результат выполнения этой программы.

<b>4/2 равно 2</b>

<b>Делить на нуль нельзя!</b>

<b>16/4 равно 4 </b>

<b>32/4 равно 8 </b>

<b>Делить на нуль-нельзя!</b>

<b>128 / 8 равно 16</b>

Из данного примера следует еще один важный вывод: как только исключение обработано, оно удаляется из системы. Поэтому в приведенной выше программе проверка ошибок в блоке try начинается снова на каждом шаге цикла for, при условии, что все предыдущие исключительные ситуации были обработаны. Это позволяет обрабатывать в программе повторяющиеся ошибки.

Применение нескольких операторов catch

С одним оператором try можно связать несколько операторов catch. И на практике это делается довольно часто. Но все операторы catch должны перехватывать исключения разного типа. В качестве примера ниже приведена программа, в которой перехватываются ошибки выхода за границы массива и деления на нуль.

<b>// Использовать несколько операторов catch.</b>

<b>using System;</b>

<b>class ExcDemo4 {</b>

<b>  static void Main() {</b>

<b>    // Здесь массив numer длиннее массива denom.</b>

<b>    int[] numer = { 4, 8, 16, 32, 64, 128, 256, 512 };</b>

<b>    int[] denom = { 2, 0, 4, 4, 0, 8 };</b>

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

<b>      try {</b>

<b>        Console.WriteLine(numer[i] + &quot; / &quot; +</b>

<b>        denom[i] + &quot; равно &quot; + numer[i]/denom[i ]) ;</b>

<b>      }</b>

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

<b>        Console.WriteLine(&quot;Делить на нуль нельзя!&quot;);</b>

<b>      }</b>

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

<b>        Console.WriteLine(&quot;Подходящий элемент не найден.&quot;);</b>

<b>      }</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

Вот к какому результату приводит выполнение этой программы.

<b>4/2 равно 2</b>

<b>Делить на нуль нельзя!</b>

<b>16/4 равно 4 </b>

<b>32/4 равно 8 </b>

<b>Делить на нуль нельзя!</b>

<b>128 / 8 равно 16 </b>

<b>Подходящий элемент не найден.</b>

<b>Подходящий элемент не найден.</b>

Как следует из приведенного выше результата, каждый оператор catch реагирует только на свой тип исключения.

Вообще говоря, операторы catch выполняются по порядку их следования в программе. Но при этом выполняется только один блок catch, в котором тип исключения совпадает с типом генерируемого исключения. А все остальные блоки catch пропускаются.

Перехват всех исключений

Время от времени возникает потребность в перехвате всех исключений независимо от их типа. Для этой цели служит оператор catch, в котором тип и переменная исключения не указываются. Ниже приведена общая форма такого оператора.