throw exだけど、throwに出来るの知ってる
前職の同僚に言われたことです。
private static void test() { try { child1(); } catch(Exception ex) { Console.WriteLine("例外発生:test"); throw; } }
例外を捕捉して、throwするとき、throw;
とだけ書いても捕捉した例外をthrow出来るのです。
これは知っていたのですが、
private static void test1() { try { child1(); } catch(Exception ex) { Console.WriteLine("例外発生:test1"); throw ex; } }
というようにthrow ex;
とthrow;
と書くのは別物です。
StackTraceが追えるかの違いがあるのです。
using System; public class Program { public static void Main() { try { test(); } catch(Exception ex) { Console.WriteLine(ex); } try { test1(); } catch(Exception ex) { Console.WriteLine(ex); } } private static void test() { try { child1(); } catch(Exception) { Console.WriteLine("例外発生:test"); throw; } } private static void test1() { try { child1(); } catch(Exception ex) { Console.WriteLine("例外発生:test1"); throw ex; } } private static void child1() { child2(); } private static void child2() { child3(); } private static void child3() { int a = 10; int b = 0; Console.WriteLine(a/b); } }
上記のようなコードにした場合、結果は以下のようになります
例外発生:test
System.DivideByZeroException: Attempted to divide by zero.
at Program.child3() in d:\Windows\Temp\po0y23rl.0.cs:line 46
at Program.child2() in d:\Windows\Temp\po0y23rl.0.cs:line 41
at Program.child1() in d:\Windows\Temp\po0y23rl.0.cs:line 38
at Program.test() in d:\Windows\Temp\po0y23rl.0.cs:line 25
at Program.Main() in d:\Windows\Temp\po0y23rl.0.cs:line 9
例外発生:test1
System.DivideByZeroException: Attempted to divide by zero.
at Program.test1() in d:\Windows\Temp\po0y23rl.0.cs:line 33
at Program.Main() in d:\Windows\Temp\po0y23rl.0.cs:line 14
test関数の時、throw;
しており、10/0の計算が発生した箇所までStackTraceが追えます。
しかし、test1関数の時、throw ex;
している場合は、10/0の計算した箇所まで追えません。test1関数までです。
というわけで、全然別物です。
使いこなせないと痛手になります。
理由がない限り、throw;
を使うことになるかと。
C#歴は長いのですが、知りませんでした。
動くだけのコードを書くための初歩的な情報はいくらでも転がってますが、こうした例外処理は自分で勉強していかないといけませんね。