如何捕捉非 CLS 异常

包括 C++/CLI 在内的某些 .NET 语言允许对象引发并非派生自 Exception 的异常。 这类异常被称为非 CLS 异常或非异常。 无法在 C# 中引发非 CLS 异常,但有两种方式可以捕获它们:

  • catch (RuntimeWrappedException e) 块内捕获。

    默认情况下,Visual C# 程序集将非 CLS 异常作为包装的异常捕获。 如需访问原始异常(可通过 RuntimeWrappedException.WrappedException 属性访问),请使用此方法。 本主题的后续过程将解释如何通过此方式捕获异常。

  • 在位于所有其他 catch 块之后的常规 catch 块(未指定异常类型的 catch 块)之中。

    如果为了响应非 CLS 异常需要执行某些操作(如写入日志文件),且无需访问异常信息时,请使用此方法。 默认情况下,公共语言运行时包装所有异常。 要禁用此行为,请将此程序集级别属性添加到代码中,通常位于 AssemblyInfo.cs 文件:[assembly: RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)]

要捕捉非 CLS 异常

catch(RuntimeWrappedException e) 块中通过 RuntimeWrappedException.WrappedException 属性访问原始异常。

示例

下面示例显示如何捕捉以 C++/CLI 编写的类库所引发的非 CLS 异常。 请注意,在此示例中,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);
    }
}

请参阅