Como capturar uma exceção não compatível com CLS

Algumas linguagens .NET, incluindo o C++/CLI, permite que os objetos lancem exceções que não derivam de Exception. Essas exceções são chamadas de exceções não CLS ou não exceções. Em C#, não é possível gerar exceções que não sejam do CLS, mas você pode capturá-las de duas maneiras:

  • Em um bloco catch (RuntimeWrappedException e).

    Por padrão, um assembly do Visual C# captura exceções não CLS como exceções encapsuladas. Use este método se você precisar de acesso à exceção original, que pode ser acessada por meio da propriedade RuntimeWrappedException.WrappedException. O procedimento, mais adiante neste tópico, explica como capturar exceções dessa maneira.

  • Em um bloco de captura geral (um bloco de captura sem um tipo de exceção especificado), que é colocado após todos os outros blocos catch.

    Use esse método quando desejar realizar alguma ação (como gravar em um arquivo de log) em resposta a exceções não CLS e você não precisa de acesso às informações de exceção. Por padrão, o Common Language Runtime encapsula todas as exceções. Para desabilitar esse comportamento, adicione esse atributo de nível de assembly em seu código, geralmente no arquivo AssemblyInfo.cs: [assembly: RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)].

Para capturar uma exceção não CLS

Em um bloco catch(RuntimeWrappedException e), acesse a exceção original por meio da propriedade RuntimeWrappedException.WrappedException.

Exemplo

O exemplo a seguir mostra como capturar uma exceção que não é do CLS, que foi gerada por uma biblioteca de classes escrita em C++/CLI. Observe que, neste exemplo, o código cliente C# sabe com antecedência que o tipo da exceção que está sendo gerada é um System.String. Você pode converter a propriedade RuntimeWrappedException.WrappedException de volta a seu tipo original, desde que o tipo seja acessível por meio do código.

// 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);
    }
}

Confira também