3

次のように open 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 を提供しない (または提供すべきではない) BaseClass から継承します。

TheString を提供し、BaseClass から継承する中間クラスを作成し、そこから継承できることに気付きました。ただし、動的ソリューションは非常に迅速に導入でき、うまく機能します。私の特定のシナリオに対してより良い解決策が提示されない限り、中間クラスを追加し、関連するクラスのみがそこから継承されるようにしてから、次のようにテストする予定です。

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

しかし、何らかの理由で中間クラスを使用するためにリファクタリングしたくないという前提の下で、ここで何をすべきでしょうか? catch ブロックで安全に無視する必要がある可能性のある例外を見つけるにはどうすればよいですか? どのような例外がスローされる可能性があるかを単に「検索」する実際の方法がない、他の同様の状況はどうですか?

4

1 に答える 1

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
于 2016-08-15T15:55:07.070 に答える