Рейтинговые книги
Читем онлайн C# 4.0: полное руководство - Герберт Шилдт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 106 107 108 109 110 111 112 113 114 ... 294

catch (ЕхсерТуре2 ехОb) {

  // Обработчик исключения типа ЕхсерТуре2. }

finally {

  // Код завершения обработки исключений.

}

Блок finally будет выполняться всякий раз, когда происходит выход из блока try/catch, независимо от причин, которые к этому привели. Это означает, что если блок try завершается нормально или по причине исключения, то последним выполняется код, определяемый в блоке finally. Блок finally выполняется и в том случае, если любой код в блоке try или в связанных с ним блоках catch приводит к возврату из метода.

Ниже приведен пример применения блока finally.

// Использовать блок finally.

using System;

class UseFinally {

  public static void GenException(int what) {

    int t;

    int[] nums = new int [2];

    Console.WriteLine("Получить " + what);

    try {

      switch(what) {

      case 0:

        t = 10 / what; // сгенерировать ошибку из-за деления на нуль

        break;

      case 1:

        nums[4] =4; // сгенерировать ошибку индексирования массива

        break;

      case 2:

        return; // возврат из блока try

      }

    }

    catch (DivideByZeroException) {

      Console.WriteLine("Делить на нуль нельзя!");

      return; // возврат из блока catch

    }

    catch (IndexOutOfRangeException) {

      Console.WriteLine("Совпадающий элемент не найден.");

    }

    finally {

      Console.WriteLine("После выхода из блока try.");

    }

  }

}

class FinallyDemo {

  static void Main() {

    for(int i=0; i < 3; i++) {

      UseFinally.GenException(i);

      Console.WriteLine() ;

    }

  }

}

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

Получить 0

Делить на нуль нельзя

После выхода из блока try.

Получить 1

Совпадающий элемент не найден.

После выхода из блока try.

Получить 2

После выхода из блока try.

Как следует из приведенного выше результата, блок finally выполняется независимо от причины выхода из блока try.

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

Подробное рассмотрение класса Exception

В приведенных выше примерах исключения только перехватывались, но никакой существенной обработке они не подвергались. Как пояснялось выше, в операторе catch допускается указывать тип и переменную исключения. Переменная получает ссылку на объект исключения. Во всех исключениях поддерживаются члены, определенные в классе Exception, поскольку все исключения являются производными от этого класса. В этом разделе будет рассмотрен ряд наиболее полезных членов и конструкторов класса Exception и приведены конкретные примеры использования переменной исключения.

В классе Exception определяется ряд свойств. К числу самых интересных относятся три свойства: Message, StackTrace и Targetsite. Все эти свойства доступны только для чтения. Свойство Message содержит символьную строку, описывающую характер ошибки; свойство StackTrace — строку с вызовами стека, приведшими к исключительной ситуации, а свойство ТагgetSite получает объект, обозначающий метод, сгенерировавший исключение.

Кроме того, в классе Exception определяется ряд методов. Чаще всего приходится пользоваться методом ToString(), возвращающим символьную строку с описанием исключения. Этот метод автоматически вызывается, например, при отображении исключения с помощью метода WriteLine().

Применение всех трех упомянутых выше свойств и метода из класса Exception демонстрируется в приведенном ниже примере программы.

// Использовать члены класса Exception.

using System;

class ExcTest {

  public static void GenException() {

    int[] nums = new int [4];

    Console.WriteLine("До генерирования исключения.");

    // Сгенерировать исключение в связи

    //с выходом за границы массива,

    for(int i=0; i < 10; i++) {

      nums[i] = i;

      Console.WriteLine("nums[{0}]: {1}", i, nums[i]);

    }

    Console.WriteLine("He подлежит выводу");

  }

}

class UseExcept {

  static void Main() {

    try {

      ExcTest.GenException();

    }

    catch (IndexOutOfRangeException exc) {

      Console.WriteLine("Стандартное сообщение таково: ");

      Console.WriteLine(exc); // вызвать метод ToString()

      Console.WriteLine("Свойство StackTrace: " + exc.StackTrace);

      Console.WriteLine("Свойство Message: " + exc.Message);

      Console.WriteLine("Свойство TargetSite: " + exc.TargetSite);

    }

  Console.WriteLine("После блока перехвата исключения.");

  }

}

При выполнении этой программы получается следующий результат.

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

nums[0]: 0

nums[1]: 1

nums[2]: 2

nums[3]: 3

Стандартное сообщение таково: System.IndexOutOfRangeException: Индекс находился

вне границ массива.

    в ExcTest.genException() в <имя_файла>:строка 15

    в UseExcept.Main()в <имя_файла>:строка 29

Свойство StackTrace:  в ExcTest.genException()в <имя_файла>:строка 15

    в UseExcept.Main()в <имя_файла>:строка 29

Свойство Message:    Индекс    находился    вне    границ    массива.

Свойство TargetSite:    Void genException()

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

В классе Exception определяются четыре следующих конструктора:

public Exception()

public Exception(string сообщение)

public Exception(string сообщение, Exception внутреннее_исключение)

protected Exception(System.Runtime.Serialization.Serializationlnfo информация, System.Runtime.Serialization.StreamingContext контекст)

Первый конструктор используется по умолчанию. Во втором конструкторе указывается строка сообщение, связанная со свойством Message, которое имеет отношение к генерируемому исключению. В третьем конструкторе указывается так называемое внутреннее исключение. Этот конструктор используется в том случае, когда одно исключение порождает другое, причем внутреннее_исключение обозначает первое исключение, которое будет пустым, если внутреннее исключение отсутствует. (Если внутреннее исключение присутствует, то оно может быть получено из свойства InnerException, определяемого в классе Exception.) И последний конструктор обрабатывает исключения, происходящие дистанционно, и поэтому требует десериализации.

Следует также заметить, что в четвертом конструкторе класса Exception типы Serializationlnfo и StreamingContext относятся к пространству имен System. Runtime.Serialization.

Наиболее часто используемые исключения

В пространстве имен System определено несколько стандартных, встроенных исключений. Все эти исключения являются производными от класса SystemException, поскольку они генерируются системой CLR при появлении ошибки во время выполнения. В табл. 13.1 перечислены некоторые наиболее часто используемые стандартные исключения.

1 ... 106 107 108 109 110 111 112 113 114 ... 294
На этой странице вы можете бесплатно читать книгу C# 4.0: полное руководство - Герберт Шилдт бесплатно.
Похожие на C# 4.0: полное руководство - Герберт Шилдт книги

Оставить комментарий