Практическое руководство. Перехват несовместимого с 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);
}
}