Страница 186 из 502
Несмотря на всю свою краткость, приведенный выше пример наглядно демонстрирует ряд основных моментов процесса обработки исключительных ситуаций. Во-первых, код, который требуется контролировать на наличие ошибок, содержится в блоке try. Во-вторых, когда возникает исключительная ситуация (в данном случае — при попытке проиндексировать массив nums за его границами в цикле for), в блоке try генерируется исключение, которое затем перехватывается в блоке catch. В этот момент выполнение кода в блоке try завершается и управление передается блоку catch. Это означает, что оператор catch не вызывается специально, а выполнение кода переходит к нему автоматически. Следовательно, оператор, содержащий метод WriteLine() и следующий непосредственно за циклом for, где происходит выход индекса за границы массива, вообще не выполняется. А в задачу обработчика исключений входит исправление ошибки, приведшей к исключительной ситуации, чтобы продолжить выполнение программы в нормальном режиме.
Обратите внимание на то, что в операторе catch указан только тип исключения (в данном случае — IndexOutOfRangeException), а переменная исключения отсутствует. Как упоминалось ранее, переменную исключения требуется указывать лишь в том случае, если требуется доступ к объекту исключения. В ряде случаев значение объекта исключения может быть использовано обработчиком исключений для получения дополнительной информации о самой ошибке, но зачастую для обработки исключительной ситуации достаточно просто знать, что она произошла. Поэтому переменная исключения нередко отсутствует в обработчиках исключений, как в рассматриваемом здесь примере.
Как пояснялось ранее, если исключение не генерируется в блоке try, то блок catch не выполняется, а управление программой передается оператору, следующему после блока catch. Для того чтобы убедиться в этом, замените в предыдущем примере программы строку кода
<b>for(int i=0; i < 10; i++) {</b>
на строку
<b>for(int i=0; i < 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("До генерирования исключения.");</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>}</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("Индекс вышел за границы массива!");</b>
<b> }</b>
<b> Console.WriteLine("После блока перехвата исключения.");</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>