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

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

Несмотря на всю свою краткость, приведенный выше пример наглядно демонстрирует ряд основных моментов процесса обработки исключительных ситуаций. Во-первых, код, который требуется контролировать на наличие ошибок, содержится в блоке try. Во-вторых, когда возникает исключительная ситуация (в данном случае — при попытке проиндексировать массив nums за его границами в цикле for), в блоке try генерируется исключение, которое затем перехватывается в блоке catch. В этот момент выполнение кода в блоке try завершается и управление передается блоку catch. Это означает, что оператор catch не вызывается специально, а выполнение кода переходит к нему автоматически. Следовательно, оператор, содержащий метод WriteLine() и следующий непосредственно за циклом for, где происходит выход индекса за границы массива, вообще не выполняется. А в задачу обработчика исключений входит исправление ошибки, приведшей к исключительной ситуации, чтобы продолжить выполнение программы в нормальном режиме.

Обратите внимание на то, что в операторе catch указан только тип исключения (в данном случае — IndexOutOfRangeException), а переменная исключения отсутствует. Как упоминалось ранее, переменную исключения требуется указывать лишь в том случае, если требуется доступ к объекту исключения. В ряде случаев значение объекта исключения может быть использовано обработчиком исключений для получения дополнительной информации о самой ошибке, но зачастую для обработки исключительной ситуации достаточно просто знать, что она произошла. Поэтому переменная исключения нередко отсутствует в обработчиках исключений, как в рассматриваемом здесь примере.

Как пояснялось ранее, если исключение не генерируется в блоке try, то блок catch не выполняется, а управление программой передается оператору, следующему после блока catch. Для того чтобы убедиться в этом, замените в предыдущем примере программы строку кода

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

на строку

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

Теперь индексирование массива не выходит за его границы в цикле for. Следовательно, никакого исключения не генерируется и блок catch не выполняется.

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

В качестве еще одного примера рассмотрим следующую программу, где блок try помещается в методе Main(). Из этого блока вызывается метод GenException(), в котором и генерируется исключение IndexOutOfRangeException. Это исключение не перехватывается методом GenException(). Но поскольку метод GenException() вызывается из блока try в методе Main(), то исключение перехватывается в блоке catch, связанном непосредственно с этим блоком try.

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

<b>using System;</b>

<b>class ExcTest {</b>

<b>  // Сгенерировать исключение,</b>

<b>  public static void GenException()    {</b>

<b>    int[] nums = new int [4];</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>}</b>

<b>class ExcDemo2 {</b>

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

<b>    try {</b>

<b>      ExcTest.GenException() ;</b>

<b>    }</b>

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

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

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

<b>    }</b>

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

<b>  }</b>

<b>}</b>

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

<b>До генерирования исключения.</b>

<b>nums[0]: О</b>

<b>nums[1]: 1</b>

<b>nums[2]: 2</b>

<b>nums[3]: 3</b>

<b>Индекс вышел за границы массива!</b>

<b>После блока перехвата исключения.</b>