try-catch (C# リファレンス)

更新 : 2010 年 7 月

try-catch ステートメントは、try ブロックと、それに続く catch 句で構成されます。この句にはさまざまな例外のハンドラーを指定します。 例外がスローされると、共通言語ランタイム (CLR: Common Language Runtime) は、この例外を処理する catch ステートメントを検索します。 現在実行されているメソッドに catch ブロックが含まれていない場合、CLR は現在のメソッドを呼び出したメソッドを検索します (この方法で、呼び出しスタックの上位を検索していきます)。 catch ブロックが見つからない場合、CLR は未処理例外のメッセージをユーザーに表示し、プログラムの実行を停止します。

try ブロックには、例外を発生させる可能性がある保護されたコードが含まれます。 ブロックは、例外がスローされるか、ブロックが正常に終了するまで実行されます。 たとえば、次の例では null オブジェクトをキャストしようとすると、NullReferenceException 例外が発生します。

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

catch 句は、引数なしで使用してすべての種類の例外をキャッチできますが、この使用方法は推奨しません。 通常は、回復方法が判明している例外のみキャッチするのが適切です。 したがって、System.Exception から派生したオブジェクト引数を必ず指定します。以下に例を示します。

catch (InvalidCastException e) 
{
}

特定の catch 句は、同一の try-catch ステートメントで複数使用できます。 この場合、catch 句は順序どおりにチェックされるため、catch 句の順序が重要になります。 例外は、特定性の高い順にキャッチしてください。 後のブロックに到達しないように catch ブロックを並べた場合、コンパイラはエラーを発生させます。

catch ステートメントでキャッチされた例外を再びスローするために、catch ブロックでは throw ステートメントを使用できます。 次の例では、IOException 例外からソース情報を抽出してから、親メソッドにこの例外をスローします。

catch (FileNotFoundException e)
{
    // FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
    // Extract some information from this exception, and then 
    // throw it to the parent method.
    if (e.Source != null)
        Console.WriteLine("IOException source: {0}", e.Source);
    throw;
}

キャッチした例外とは異なる例外をスローできます。 これを行うには、次の例に示すように、キャッチする例外を内部例外として指定します。

catch (InvalidCastException e) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", e);
}

次の例に示すように、指定した条件が true の場合に例外を再スローすることもできます。

catch (InvalidCastException e)
{
    if (e.Data == null)
    {
        throw;
    }
    else
    {
        // Take some action.
    }
 }

try ブロック内では、そのブロックで宣言されている変数のみを初期化します。 そうしないと、ブロックの実行が完了する前に例外が発生する可能性があります。 たとえば、以下のコード例では、変数 n が try ブロック内で初期化されます。 この変数を try ブロックの外側にある Write(n) ステートメントで使おうとすると、コンパイラ エラーが発生します。

static void Main() 
{
    int n;
    try 
    {
        // Do not initialize this variable here.
        n = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'n'.
    Console.Write(n);
}

catch の詳細については、「try-catch-finally」を参照してください。

使用例

例外を発生させる可能性がある ProcessString メソッドへの呼び出しを含む try ブロックの例を次に示します。 catch 句には、メッセージを画面に表示するだけの例外ハンドラーがあります。 throw ステートメントが MyMethod の内側から呼び出されると、システムは catch ステートメントを検索し、メッセージ "Exception caught" を表示します。

    class TryFinallyTest
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        string s = null; // For demonstration purposes.

        try
        {            
            ProcessString(s);
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */

2 つの catch ステートメントを使用する例を次に示します。 最初にある、特定性の最も高い例外がキャッチされます。

class ThrowTest3
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        try
        {
            string s = null;
            ProcessString(s);
        }
        // Most specific:
        catch (ArgumentNullException e)
        {
            Console.WriteLine("{0} First exception caught.", e);
        }
        // Least specific:
        catch (Exception e)
        {
            Console.WriteLine("{0} Second exception caught.", e);
        }
    }
}
/*
 Output:
 System.ArgumentNullException: Value cannot be null.
 at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/

前の例で、特定性の最も低い catch 句から始めると、次のエラー メッセージが表示されます。

A previous catch clause already catches all exceptions of this or a super type ('System.Exception')

ただし、特定性の最も低い例外をキャッチするには、throw ステートメントを次のものと置き換えます。

throw new Exception();

C# 言語仕様

詳細については、「C# 言語仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

参照

処理手順

方法 : 例外を明示的にスローする

参照

C# のキーワード

try, catch, and throw Statements (C++)

例外処理ステートメント (C# リファレンス)

throw (C# リファレンス)

try-finally (C# リファレンス)

概念

C# プログラミング ガイド

その他の技術情報

C# リファレンス

履歴の変更

日付

履歴

理由

2010 年 7 月

throw の例を更新。

カスタマー フィードバック