C#例外処理でのthrowとthrow exの違い
C#の例外処理におけるThrowの扱い方の違いのメモ。
C#/VB.NETでは、「throw;」を使うほうが推奨されることが多いです。「throw ex;」を使うとそれまでの情報(スタックトレースやInnerException)がクリアされます。
以下は、その確認コードです。
//ゼロ除算エラーを発生させる関数 private void ZeroDivide() { int zero = 0; int err = 1 / zero; } //exを付けてThrowする関数 private void ThrowEx() { try { ZeroDivide(); } catch (Exception ex) { //exを付けて投げる throw ex; } } //ex無しでThrowする関数 private void ThrowOnly() { try { ZeroDivide(); } catch (Exception ex) { //exを付けないで投げる throw; } } //ThrowExをテスト private void button1_Click(object sender, EventArgs e) { try { ThrowEx(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); // //→「throw ex;」時のメッセージ // //System.DivideByZeroException: 0 で除算しようとしました。 // 場所 Form1.ThrowEx() 場所 C:\Sample\Form1.cs:行 38 // 場所 Form1.button1_Click(Object sender, EventArgs e) 場所 C:\Sample\Form1.cs:行 60 // //※本当はZeroDivide関数でエラーが発生したがThrow前の情報が消えている。 // ThrowEx関数でエラーが発生したかのように見える。 } } //ThrowOnlyをテスト private void button2_Click(object sender, EventArgs e) { try { ThrowOnly(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); // //→「throw;」時のメッセージ // //System.DivideByZeroException: 0 で除算しようとしました。 // 場所 Form1.ZeroDivide() 場所 C:\Sample\Form1.cs:行 26 // 場所 Form1.ThrowOnly() 場所 C:\Sample\Form1.cs:行 50 // 場所 Form1.button2_Click(Object sender, EventArgs e) 場所 C:\Sample\Form1.cs:行 72 // //※エラー発生元であるZeroDivideのスタックトレースが消えずに残っている。 } }