- PR -

[VB.NET] Throw だけで例外を再スロー

1
投稿者投稿内容
Ten.
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 67
投稿日時: 2004-08-26 19:35
VS.NET2003でVB.NETを使用しています。

MSDN で VB.NET の Throw ステートメントの説明を見ると、スローする例外を必ず指定しなければならないと書かれています。

しかし、Catchブロック内では以下のように Throw だけで発生している例外を再スローすることができます。(C#では例外を指定しないで再スローすることについて記述があります)
コード:
Try
    ' ・・・
Catch ex As Exception
    ' ・・・
    Throw
End Try


このことについて疑問が2つあります。

1.MSDN の Throw ステートメント関する記述は、単なる間違いなのか?

2.以下のように変数を指定して再スローした場合と比べるとスタックトレースの内容が違うのはなぜか?
コード:
Try
    ' ・・・
Catch ex As Exception
    ' ・・・
    Throw ex
End Try


スタックトレースの違いは ToString で出力した文字列を比較しました。
変数を指定した場合、最初に例外を発生させたメソッドと例外を再スローしたメソッドの間の呼び出し履歴が出力されません。(分かりにくいかもしれませんが、以下のようなイメージです)

 at ・・・
 at ・・・
 at 最初に例外を発生させたメソッド
 --- 内部例外スタック トレースの終わり ---
 at ・・・   ←この部分が抜けている
 at 例外を再スローしたメソッド
 at ・・・
 at ・・・
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-08-26 19:55
引用:

Ten.さんの書き込み (2004-08-26 19:35) より:
1.MSDN の Throw ステートメント関する記述は、単なる間違いなのか?


単に説明不足というか、抜けているって感じですね。
しいて言えば、Catch内の単なるTnrowと、通常の例外を指定するThrow 〜は、別物であるという感覚で書かれているように見えます。

「Visual Basic 言語の仕様」の方では、ちゃんとCatch内での記述についても言及されていますね。
引用:

2.以下のように変数を指定して再スローした場合と比べるとスタックトレースの内容が違うのはなぜか?


これも、例外を発生させる際の動作が関わってきますね。
例外のスタックトレースは、例外をThrowした時に取得が開始されます(感覚的には)。
※ここでのThrowは、Catch内ではない、必ず例外を指定する方のThrowです。

Catch内でも例外を明示してThrowした場合には、そこから例外が発生するのですから、スタックトレースの取得もそこから始まります。

一方、Catch内で使える単なるThrowは、既に取得したスタックトレースに影響を与えずに、そのまま上位にスローする、というよりもむしろ、スローの続きを実行する、という感じです。
はっきり言って、Throwにおける再スローの意味と、Throw 〜 における再スローの意味は別物と思った方が良いですね。
Ten.
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 67
投稿日時: 2004-08-27 11:48
なちゃさん、ご返答ありがとうございます。

引用:

「Visual Basic 言語の仕様」の方では、ちゃんとCatch内での記述についても言及されていますね。


確かに「8.11.1 構造化例外処理ステートメント」に書いてありますね。
ここも読んでいたはずなんですが、読解力がないせいかよく読まないと気付きませんでした。。。

引用:

Catch内でも例外を明示してThrowした場合には、そこから例外が発生するのですから、スタックトレースの取得もそこから始まります。
一方、Catch内で使える単なるThrowは、既に取得したスタックトレースに影響を与えずに、そのまま上位にスローする、というよりもむしろ、スローの続きを実行する、という感じです。
はっきり言って、Throwにおける再スローの意味と、Throw 〜 における再スローの意味は別物と思った方が良いですね。


同じ「再スロー」という言葉を使うから混乱するんですね。

とても分かりやすい説明をありがとうございました。
もやもやが晴れて、すっきりしました。
1

スキルアップ/キャリアアップ(JOB@IT)