C ++、Java、.Netのいずれも、これまで、スタックの巻き戻しクリーンアップコードで発生する例外を処理するための優れた方法を提供していませんでした。多くの場合、クリーンアップコードで発生する例外は、メインラインコードで発生する例外よりもプログラムの動作にとって重要ですが、診断目的にはあまり役立ちません(特に、クリーンアップ例外が発生する可能性があるため)。メインラインの例外の結果として)。
VB.netでは、問題の例外をキャッチまたは処理することを主張せずにfinally
、コードがどの例外がブロックを離れたのかをコードが認識できるように、try/finallyブロックを作成することができます。try
残念ながら、C#ではそれは不可能ですが、C#のコードは、vb.netで記述されたラッパーを呼び出すことでそのような効果を実現できます。適切なセマンティクスを実現するために必要なコードは少し厄介なので、このようなラッパーの使用はvb.netでも役立つ場合があります。例外のためにスタックの巻き戻し中にが実行された場合に呼び出されるusing
ようなインターフェイスを使用できれば、両方の言語のブロックを改善できます。これにより、IDisposableDuringException { void Dispose(Exception ex);}
Dispose
Dispose
スローされる可能性のある例外に提供された例外を含める方法。また、例外がスローされたかどうかによって、破棄動作が異なる可能性があります(たとえば、トランザクションスコープは、例外を介して終了する場合、ロールバックを明確に実行する必要があります。これは、結局のところ、それらのポイントですが、通常の手段で終了するときに暗黙的にロールバックを実行するように要求するのは厄介です)。
クリーンアップ中に例外がスローされた場合にfinally
どうなるかについては、例外が保留中であるかどうかに関係なく、適切な動作はカスタムのようなものをスローすることCleanupFailureException
です。呼び出し元のコードが、たとえばメインラインからスローされたものをキャッチするように準備されていたとしてもInvalidOperationException
、メインラインが正常に完了した後InvalidOperationException
にクリーンアップが行われると、コードが処理する準備ができていた状況とは異なる状況を表す可能性があります。したがって、別の例外タイプを使用します。
ちなみに、予期しない例外が致命的であるか非致命的であるとコードが想定すべきかについては、しばしば議論があります。多くの場合、適切なアプローチは、予期しない例外からスタックを巻き戻し、処理されていたオブジェクトを明示的に無効にして、それらのオブジェクトを使用した今後のすべての操作で例外が発生するようにすることだと思います。これは、予期しない例外が非常に重要なオブジェクトを破損する可能性がある場合、プログラムが損傷を与える前に停止する可能性があるという効果がありますが、同時に、例外がとにかく必要とされないオブジェクトを破損する可能性を考慮に入れます(たとえば、破損したファイルからドキュメントをロードしているときに予期しない問題が発生し、ドキュメントをロードしようとしたときに、それに関連するデータ構造が絶望的に破損した場合、