Шаг 221.
Язык программирования C#. Начала.
Обработка исключений. Использование конструкции try-catch (окончание)

    На этом шаге мы рассмотрим пример использования указанных конструкций.

    Небольшой пример, в котором при обработке исключительной ситуации используется объект ошибки, представлен в примере ниже.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace pr221_1
{
    // Класс с главным методом: 
    class Program
    {
        // Главный метод: 
        static void Main()
        {
            // Отображение сообщения:
            Console.WriteLine("Haчинается выполнение программы");
            // Объявление переменных: 
            int A = 10, B = 0;
            // Отображение значений переменных:
            Console.WriteLine("Переменная A = " + A);
            Console.WriteLine("Переменная B = " + B);
            // Контролируемый код: 
            try {
                // Отображение сообщения:
                Console.WriteLine("Вычисляется выражение A/B");
                // Вычисление выражения (попытка деления на ноль): 
                Console.WriteLine("Peзультат: " + A / B);
                // Отображение выражения (команда не выполняется):
                Console.WriteLine("Вычисления закончены");
            }
            // Блок обработки исключения: 
            catch(Exception e) {
                // Отображение сообщения:
                Console.WriteLine("Boзникла ошибка!");
                // Тип ошибки:
                Console.WriteLine("Тип ошибки: " + e.GetType().Name);
                // Описание ошибки:
                Console.WriteLine("Описание: " + e.Message);
                // Источник ошибки (программа):
                Console.WriteLine("Программа: " + e.Source);
                // Метод, в котором произошла ошибка:
                Console.WriteLine("Метод: " + e.TargetSite.Name);
                // Место (строка) с ошибкой:
                Console.WriteLine("Mecто ошибки: " + e.StackTrace);
            }
            // Отображение сообщения:
            Console.WriteLine("Программа завершила выполнение");
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Результат выполнения программы представлен ниже:


Рис.1. Результат выполнения программы

    Программа достаточно простая. Вся интрига закручивается в главном методе. В начале выполнения программы в консольном окне появляется сообщение соответствующего содержания. Также объявляются две целочисленные переменные: переменная A со значением 10 и переменная B со значением 0. Значения переменных отображаются в консольном окне. После этого начинает выполняться try-блок с контролируемым кодом.

    Сначала командой

  Console.WriteLine("Вычисляется выражение A/B"); 
выводится сообщение о вычислении частного двух целочисленных значений. При выполнении команды
  Console.WriteLine("Peзультат: " + A / B);
предпринимается попытка вычислить значение выражения A/B. Но при нулевом значении переменной B возникает ошибка, связанная с делением на ноль. Поэтому дальше команды в try-блоке не выполняются (то есть до выполнения команды
  Console.WriteLine("Вычисления закончены");
в try-блоке дело не доходит). Вместо этого создается объект исключения, и этот объект передается для обработки в catch-блок.


Выполнение команды
  Console.WriteLine("Peзультат: " + A / B);
начинается с вычисления значения аргумента, переданного методу WriteLine(). При вычислении значения аргумента вычисляется значение выражения A/B. Как отмечалось выше, в этом месте возникает ошибка. Поэтому выполнение команды
  Console.WriteLine("Peзультат: " + A / B);
прекращается, и никакого сообщения в консольном окне не будет.

    В catch-блоке объект (точнее, ссылка на объект) исключения обозначен как e. Именно через переменную e в теле catch-блока мы обращаемся к объекту исключения. Там командой

  Console.WriteLine("Boзникла ошибка!");
отображается сообщение о возникновении ошибки, а далее с использованием объекта исключения e в консольном окне отображаются некоторые дополнительные сведения о том, что произошло.

    У объекта исключения e есть метод GetType(). Метод результатом возвращает объект класса Type, содержащий информацию о типе объекта e. Этот объект класса Type имеет текстовое свойство Name, значение которого - название класса, к которому относится объект исключения e. Поэтому значение выражения e.GetType().Name - это название класса ошибки, которая произошла. Как следует из результата выполнения программы, произошла ошибка класса DivideByZeroException (из пространства имен System).

    Текстовое свойство Message объекта e содержит описание ошибки. В данном случае значением свойства является текст "Попытка деления на нуль.". Далее, значением свойства Source является текст с названием приложения или объекта, вызвавшего исключение. Значением свойства TargetSite является объект класса MethodBase. Объект содержит информацию о методе, вызвавшем исключение. Название метода можно получить с помощью свойства Name. Таким образом, значением выражения e.TargetSite.Name является текст "Main" с названием главного метода, в котором произошла ошибка. Значением свойства StackTrace является текст с указанием места (вплоть до номера строки кода), в котором возникла ошибка.

    На этом выполнение catch-блока завершается. Работа программы завершается выполнением команды

  Console.WriteLine("Программа завершила выполнение");     .


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

    Стоит также заметить, что если мы в программном коде изменим значение переменной B с 0 на 2 (вместо инструкции B=0; следует использовать инструкцию B=2;), то результат выполнения программы будет таким, как показано ниже:


Рис.2. Результат выполнения программы

    В этом случае при выполнении try-блока ошибок не возникает. Поэтому выполняются все команды в try-блоке, а команды в catch-блоке игнорируются.

    На следующем шаге мы рассмотрим основные классы исключений.




Предыдущий шаг Содержание Следующий шаг