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# の構文と使用法に関する信頼性のある情報源です。
参照
処理手順
参照
try, catch, and throw Statements (C++)
概念
その他の技術情報
履歴の変更
日付 |
履歴 |
理由 |
---|---|---|
2010 年 7 月 |
throw の例を更新。 |
カスタマー フィードバック |