2012-02-27 20 views
16

私は次のコードを持っている:キャッチ例外、データを追加し、再スローそれ

try 
{ 
    OnInitialize(); 
} 
catch (PageObjectLifecycleException exception) 
{ 
    exception.OldLifecycleState = CurrentLifecycleState; 
    exception.RequestedLifecycleState = LifecycleState.Initialized; 
    throw exception; 
} 

私はそれにいくつかのより多くのデータを追加し、それを再スロー、例外をキャッチします。 ReSharperのは、再スローがおそらく意図されていることを私に(正確に)警告し、それを変更することを提案する:

throw; 

しかし、私は思ったんだけど:これは正しく修正例外または未元のものを再スローだろうか?

:「試してみてください」というコメントに対する回答:私はC++を使いこなしています。 C++では、このようなコーナーケースで未定義の動作が頻繁に発生することが多く、私が望むものが正式に動作するかどうかに関心があります。

+6

はそれを試してみて、何が起こりますか? –

+0

参照が指し示していることは何でも - あなたの場合は変更された "例外"を再スローします。 –

答えて

8

変更された例外への参照がスローされます。

しかし、これが良いプログラミングスタイルかどうかはわかりません。新しい例外を作成し、内部例外としてPageObjectLifecycleExceptionを追加することを検討してください。このようにして、処理コードは正しい追加情報を持っているかどうかを確かめることができます。

+0

私、あまりにも、これは本当のバグヒーダーです。たとえば、より深いものから戻ってきたデータの外側のキャッチブロック・トランプル。 –

+0

コードサンプルは簡略化されています。既存のデータは上書きされず、一部の欠落した追加データのみが供給されます。 –

+0

@TonyHopkinson「Exception.Data」は、この目的のために使われているようです([ここ](https://msdn.microsoft.com/en-us/library/system.exception.data(v = vs.110 ).aspx)) – drzaus

2

あなたのパターンが非常に素晴らしくメンテナンス可能なものかどうかはわかりませんが、現在の例外が再スローされます。

22

答えは既に選択されていますが、ここではもう少し詳しく説明します。

try { 
    // code 
} 
catch(Exception e) { 
    throw e; 
} 

ILにコンパイルされた上記のコードでは、引数として扱わ例外への参照を渡すthrowへの呼び出しを生成します。ご存知のように、コード内のどこからでもthrowに電話をかけて例外を発生させることができます。

try { 
    // code 
} 
catch(Exception e) { 
    throw; 
} 

上記のコードをILにコンパイルすると、rethrowが呼び出されます。これはとは異なります。なぜなら、例外が処理されたブロックが何らかの理由で処理しないと判断したことを通知するために、高位のcatchブロック(次の1つ上)に責任を与える必要があるということです。

rethrowのメソッドは、例外の起点を追跡できるように、現在の呼び出しスタックトレースを保持します()。ただし、throwメソッドは、新しいコールスタックトレースを開始します。 2つの方法が何のために使われるのか理解すればこれは意味をなさないと思います。

何らかの理由で例外をスローしたい場合(例:オブジェクトの検証に失敗した)、ログを実行した後にcatchステートメントでthrow;を使用すると、throw exception;が使用されます。例外処理責任を上位レベルに渡す前に、検証に失敗したオブジェクトの有益な情報へのアクセス)。

あなたの例では、例外にさらに情報を追加する必要がある場合は、全く新しい例外を作成して上げる場合があることをお勧めします。したがって、throw exception;メソッドを使用します。ここで、「例外」は追加の情報と最初にスローされた例外を含む新しい例外です。

希望に役立ちます!

あなたはthrowで例外をデータに情報を追加して再スローすることができジェームズ

9

ので、それは元の形を維持し、コールスタック

try 
{ 
    ... 
} 
catch (PageObjectLifecycleException exception) 
{ 
    exception.Data.Add("additional data", "the additional data"); 
    throw; 
} 
+2

これは本当に受け入れられた答え、それは 'データ'のためのものです。キーコンフリクトを防ぎ、ディクショナリに含まれている情報がどれでも1)コールチェーンに伝播し、2)途中で変更できることを念頭に置いておくと、デバッグを容易にする便利な情報を追加するのに最適です。 –

関連する問題