次のステートメントがあるとします。
try
{
... some code ...
}
catch
{
... some cleanup code ...
throw;
}
と
try
{
... some code ...
}
catch (Exception ex)
{
... some cleanup code ...
throw ex;
}
これらは同じように動作しますか、それとも最初のもので新しい例外がスローされますか?
それらは同じではありません。2 番目のバージョンでは、スタック情報が失われます。
詳細な説明はこちら: http://winterdom.com/2002/09/rethrowingexceptionsinc
そのサイトから:
[2 番目のコード] コード [..] では、ex を再スローしているのではなく、同じ例外オブジェクト インスタンスを使用して新しい例外フローを開始しているだけです。
前者は元の例外をスローします。後者は新しい例外をスローします。前者は元のスタック トレースを保持するのに対し、後者は例外が再スローされた場所から始まるスタック トレースのみを保持することを除いて、通常は同じように動作します。
2つの違いがあります
最初に正しいのは、2 番目のものによって、新しいスタック トレースで新しい例外がスローされることです。これにより、貴重なデバッグ情報が失われるため、決して実行しないでください。2番目の例を行う正しい方法は次のようになります
try
{
... some code ...
}
catch (Exception) //You can include the "ex" if you need it in your cleanup code
{
... some cleanup code ...
throw; //Don't use the "ex" here
}
2 番目の違いは、最初の例ではキャッチされ、2 番目の例ではキャッチされない非常に少数の例外があることです。主に、これらの例外は、CLR に準拠していないコードからスローされるものです。ExceptionC# コードから非派生例外をスローする方法はありません。
バブルアップする前に例外に追加情報を追加したい場合は、新しい例外をスローし、古い例外をInnerException
try
{
... some code ...
}
catch (Exception ex)
{
... some cleanup code ...
throw new MyCustomException("Some useful information", ex);
}