2016-08-15 1 views
3

私はそうのようなオープンcatchブロックを使用してはならない理由を私は知っている:Try/Catch - 奇妙な/複雑なケースで何を捕まえるべきかを私はどのように知っていますか?

int x = 0; 
try 
{ 
    x = GetXFromSomeplaceThatCanFail(); 
} 
catch //Possibly (Exception) or (Exception e) 
{ 
    //Ignore The Failure Because We Don't Care If It Fails 
} 
if (x != 0) //Yes I know I can use finally blocks to do something similar, but this is just an example case 
{ 
    //Do Things With x 
} 

私はこれは悪い習慣であると検出されない障害/微妙なエラーが発生する可能性があり、OutOfMemoryException例外のようなものを「飲み込む」になることを十分に承知していますひどいものです。

だから、私は自分のコードを調べて、このようなものがないことを確認しています。通常は、tryブロックで使用しているもののドキュメンテーションに行き、予期される例外をキャッチするか、特定の操作がインデックスなどの配列にアクセスするときにIndexOutOfRangeExceptionのような特定の例外を生成することを知ります。

しかし、奇妙な状況でどのような例外がスローされるかを確認するためのドキュメントはありません(または見つけるのが難しい)。私自身のプロジェクト(変数名は一般的なものと単純化された変数名)は、文字列フィールドが存在する場合にのみ動的タイプを使用して、かそれ以外の場合は "N/A"を結果として提供できません。繰り返しますが、私はこれは悪いコードであることを知っていることを思い出させる:

string theString = "Some Old Value From Previous Run/etc."; 
try 
{ 
    theString = (placeWhereValuesComeFrom as dynamic).TheString; 
} 
catch 
{ 
    theString = "N/A"; 
} 

をこの文脈では、placeWhereValuesComeFromは(またそれがなければならない)TheStringを提供するdoensn't BaseClassのを継承しています。

TheStringを提供し、BaseClassから継承する中間クラスを作成してから継承することができます。しかし、ダイナミックなソリューションは、設置が非常に速く、うまく機能しました。

theString = placeWhereValuesComeFrom is Subclass ? ((Subclass)placeWhereValuesComeFrom).TheString : "N/A"; 

しかし、私がいないという仮定の下で:よりよい解決策は、私は、中間クラスを追加し、唯一の関連するクラスはそれから継承させる、そのようにようにテストする予定の私の特定のシナリオのために出すされていない限り中間のクラスを使う理由が何であれ、リファクタリングしたいのですが、ここで何をすればいいのですか?キャッチブロックで無視しなければならない可能性のある例外を知るにはどうすればよいですか?例外をスローすることができるだけの "ルックアップ"の方法がない他の同様の状況はどうですか?

+1

あなたはそれから回復する方法を知っているので、あなたが例外を処理することができた場合通常、あなたはそれをキャッチ(と、それをログアウト)することができます。例外からの復旧方法がわからない場合は、アプリケーションをクラッシュさせ、そのクラッシュのすべての詳細をログに記録するだけです。 –

+2

無視する必要のある例外を「発見」しません。代わりに、実際に処理するコードを記述している例外をキャッチするだけです。例外が何であるかわからない場合、定義上、あなたはそれらを処理することができず、それらを捕まえるべきではありません。 –

+0

キャストされたダイナミックに関連するフィールドがない場合、例外がスローされることは知っています。私はその例外を処理したい。私は例外タイプが何であるかは分かりませんが、ダイナミックタイプのドキュメントは***とは言いません。これが適用される他の状況があります - その中で何をしますか? – Yushatak

答えて

2

ここで扱う例外は、実行時バインドの失敗です。動的オブジェクトがTheStringを実装していないときスローされる例外のタイプはMicrosoft.System.CSharp.RuntimeBinder.RuntimeBinderExceptionです。

だからあなたのコードは、次のようになります。

try 
{ 
    str = myDynamicObject.TheString; 
} 
catch (Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException) 
{ 
    //Binding failure 
    str = "N/A" 
} 
catch (... //exceptions you know TheString can throw, if any...) 
{ 
    //Handle 
} 
// any other exception you don't know how To handle...don't handle it 
+0

これは上の特定のケースを解決するための有効なコードですが、マニュアルで何も伝えておらず、手動で障害をチェックしたくない場合の一般的な状況には対処しません。 – Yushatak

+3

@ユマタクそれでは、私はあなたの質問の前提が間違っていると思っています。処理する方法を知っている例外をキャッチする必要があります。何が例外になっているのかわからない場合は、どうやって処理するのかが分かりません。悲観的に文書化されたライブラリを使用しているか(別のライブラリを使用しているか)、完全に理解していないライブラリを使用しています(調査し、コードを単体テストでテストします)。 – InBetween

+0

これは私が答えに最も近いところだと思います。もしドキュメントがあなたに言わなければ、あなた自身のために調査しなければならないか、別のものに移動する必要があります。コードを強調表示して、コードを実行する "可能な例外のリスト"レイヤーごとにスローされる可能性のある例外を列挙します(クリックした場合は、それが見つかった場所が表示されます)。その時点で、それぞれ独自の方法で適切に処理できるシナリオでは、選択された、またはすべての例外に対するハンドラを追加するためのボタンをいくつか配置することもできます。 – Yushatak

関連する問題