次の方法で共有


CLS 準拠でない例外をキャッチする方法

C++/CLI をはじめとする一部の .NET 言語では、Exception から派生していない例外をオブジェクトでスローすることができます。 このような例外は "CLS 準拠でない例外" や "非例外" と呼ばれています。 C# では、CLS 準拠でない例外をスローすることはできませんが、それらをキャッチすることはできます。次の 2 とおりの方法があります。

  • catch (RuntimeWrappedException e) ブロック内で。

    Visual C# アセンブリの既定の動作上、CLS 準拠でない例外はラップされた例外としてキャッチされます。 元の例外にアクセスする必要がある場合 (RuntimeWrappedException.WrappedException プロパティからアクセスできます)、このメソッドを利用します。 この方法で例外をキャッチする方法については、このトピックで後述します。

  • 他のすべての catch ブロックの後に置いた汎用的な catch ブロック (例外の型が指定されていない catch ブロック) 内で。

    この方法は、CLS 準拠でない例外への応答として何らかのアクション (ログ ファイルへの書き込みなど) を実行したい場合で、なおかつ例外情報にアクセスする必要がない場合に使用します。 既定では、すべての例外が共通言語ランタイムによってラップされます。 この動作を無効にするには、[assembly: RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)] というアセンブリ レベルの属性を (通常、AssemblyInfo.cs ファイル内の) コードに追加します。

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

関連項目