• Иллюстрированный самоучитель по Architecture .NET

    Обработка исключений

    Без сомнения, вы уже хорошо знакомы с механизмом исключений в стандартном C++, так что хорошо понимаете, как работают управляемые исключения. Напомним, что платформа .NET (точнее, общеязыковая среда выполнения CLR) поддерживает расширения, совместимые с расширением управляемости C++, и управляемые исключения, возникшие при выполнении кода, созданного на одном из языков .NET, могут быть перехвачены и обработаны кодом, написанным на любом другом языке .NET.

    Кроме обработки предопределенных исключений, таких, как Invalid-CastException или OverflowException, вы можете определить ваши собственные производные от Exception (Исключение) классы, инкапсулирующие некоторую специфичную для приложения информацию. Рассмотрим следующий пример:

    //Exceptions.cpp
    #using <mscorlib.dll>
    using namespace System;
    // использовать пространство имен Система;
    _gc class MyException: public Exception
    // класс сборщика мусора MyException: общедоступное Исключение
    {
    };
    void TemperamentalFunction(int i) // ненавидит нечетные числа
    {
    Console::WriteLine(
    "TemperamentalFunction called with {0}",
    i.ToString());
    if (i%2!= 0) // если (i%2!= 0), т.е. нечетное
    throw new MyException;
    Console::WriteLine("No exception thrown"); // Нет исключения
    }
    void main()
    {
    try
    {
    TemperamentalFunction(2); // вызов с четным числом
    TemperamentalFunction(3); // вызов с нечетным числом
    }
    catch (MyException *pe)
    {
    Console::WriteLine("Exception thrown!"); // Исключение!
    Console::WriteLine(pe › get_StackTrace());
    }
    }
    

    Приведем результат работы программы:

    TemperamentalFunction called with 2
    No exception thrown
    TemperamentalFunction called with 3
    Exception thrown!
    at TemperamentalFunction(Int32 i) in с:\netcppcode\
    chap03\exceptions\exceptions.cpp:line 16
    at main() in c:\netcppcode\chap03\exceptions
    \exceptions.cpp:line 25
    

    Вот более русифицированная версия этой выдачи.

    TemperamentalFunction вызвана с 2
    Нет исключения
    TemperamentalFunction вызвана с 3
    Исключение!
    в TemperamentalFunction (Int32 i) в с:\netcppcode\
    chap03\exceptions\exceptions.cpp:line 16
    в главном () в c:\netcppcode\chap03\exceptions
    \exceptions.cpp:line 25
    

    Обратите внимание на метод StackTrace, позволяющий получить текстовую строку, представляющую состояние стека в момент возникновения исключения. Хотя в этом примере ключевое слово _finally (наконец) и не используется, но следует помнить, что такое расширение стандарта ANSI C++ поддерживается в Visual C++. Ключевое слово _finally (наконец) позволяет вставлять в программу код, который выполняется вне зависимости от того, возникло или нет исключение в блоке try. Следует также упомянуть, что ключевое слово _finally (наконец) полностью совместимо с механизмом исключений, поддерживаемым другими языками .NET.

    При желании предыдущий пример можно разбить на две части. Первая часть могла быть реализована на С# (в виде динамически подключаемой библиотеки (DLL)) и содержала бы код, при выполнении которого возникало бы исключение. Вторая часть была бы приложением на C++, вызывающим метод TemperamentalFunction. Этим способом можно было бы наглядно продемонстрировать, что исключения действительно являются мостом, соединяющим разные языки .NET.

    Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.