はじめに
C#では、throw e
で、例外を再スローすると、スタックトレースが上書きされるので、throw e
は使わないほうが良いです。
サンプルで説明
using System;
namespace csharp
{
class Program
{
static void Main(string[] args)
{
try
{
Method2();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void Method2()
{
try
{
Method1();
}
catch (Exception e)
{
throw e;
}
}
private static void Method1()
{
throw new Exception("エラー発生");
}
}
}
上記を実行すると、コンソールには以下のように出力されます。
System.Exception: エラー発生
at csharp.Program.Method2() in D:\dev\qiita\csharp\Program.cs:line 27
at csharp.Program.Main(String[] args) in D:\dev\qiita\csharp\Program.cs:line 11
発生元(スタックトレースの一番上)が、Method2になっていますね。
実際には、Method1で発生しているのですが、throw e
のせいで、スタックトレースが上書きされています。
C#で、スタックトレースを上書きされないように再スローするには、以下のようにMethod2を変更すればOKです。
private static void Method2()
{
try
{
Method1();
}
catch
{
throw;
}
}
このように、throw
だけであれば、以下のようにスタックトレースが上書きされなくなります。
System.Exception: エラー発生
at csharp.Program.Method1() in D:\dev\qiita\csharp\Program.cs:line 33
at csharp.Program.Method2() in D:\dev\qiita\csharp\Program.cs:line 27
at csharp.Program.Main(String[] args) in D:\dev\qiita\csharp\Program.cs:line 11
おわりに
私が今まで経験したプロジェクトにおいて、スタックトレースの上書きが必要であったことは、一度もありません。
JavaやJavaScriptでは、同様の記述をしてもスタックトレースは上書きされないので、C#でなぜこのような仕様になっているのか、調査をしても私には分かりませんでした。
もし、C#がthrow e
でスタックトレースを上書きする理由をご存知の方がいらっしゃいましたら、ぜひ、コメントで教えてください!