Практическое руководство. Перехват несовместимого с CLS исключения

Некоторые языки .NET, включая C++/CLI, позволяют объектам вызывать исключения, которые не являются производными от Exception. Такие исключения называются несовместимыми с CLS исключениями или необработанными исключениями. В C# невозможно вызвать несовместимые с CLS исключения, однако можно перехватить их следующими двумя способами.

  • В блоке catch (RuntimeWrappedException e).

    По умолчанию сборка Visual C# перехватывает несовместимые с CLS исключения как заключенные в оболочку. Этот метод следует использовать, если требуется доступ к исходному исключению, который можно получить с помощью свойства RuntimeWrappedException.WrappedException. Далее в этом разделе описывается процедура перехвата исключений таким способом.

  • В общем блоке перехвата (блоке перехвата, для которого не указан тип исключения), который помещается после остальных блоков catch.

    Используйте этот способ, если требуется выполнить какое-либо действие (например, запись в файл журнала) в ответ на несовместимые с CLS исключения, и вам не нужен доступ к сведениям об исключении. По умолчанию среда CLR создает оболочку для всех исключений. Чтобы отключить этот режим, добавьте этот атрибут уровня сборки в код, как правило, в файле AssemblyInfo.cs: [assembly: RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)].

Перехват несовместимого с CLS исключения

В блоке catch(RuntimeWrappedException e) для доступа к исходному исключению используйте свойство RuntimeWrappedException.WrappedException.

Пример

В следующем примере показано, как перехватить несовместимое с CLS исключение, которое было вызвано из библиотеки классов, написанной на C++/CLI. Обратите внимание, что в этом примере клиентскому коду C# заранее известно, что тип вызываемого исключения — System.String. Можно привести свойство RuntimeWrappedException.WrappedException к его исходному типу, если этот тип доступен из кода.

// Class library written in C++/CLI.
var myClass = new ThrowNonCLS.Class1();

try
{
    // throws gcnew System::String(  
    // "I do not derive from System.Exception!");  
    myClass.TestThrow();
}
catch (RuntimeWrappedException e)
{
    String s = e.WrappedException as String;
    if (s != null)
    {
        Console.WriteLine(s);
    }
}

См. также