1

次のようなコードのセクションがあります。

try
{
  classVar = functionCall(input, sEnum.First);

  classVar = functionCall(input, sEnum.Second);

  classVar = functionCall(input, sEnum.Third);
}
catch (Exception ex)
{
  Debug.Assert(false, ex.ToString());
}

しかし、私の例外は、それがどの特定の呼び出しから来たのかを示しています。スタックトレースには、関数呼び出し内から呼び出された別のクラスの詳細のみが表示されます。

これをラップする別の方法は次のとおりです。

try
{
  classVar = functionCall(input, sEnum.First);
}
catch (Exception ex)
{
  Debug.Assert(false, ex.ToString());
}
try
{
  classVar = functionCall(input, sEnum.Second);
}
catch (Exception ex)
{
  Debug.Assert(false, ex.ToString());
}
try
{
  classVar = functionCall(input, sEnum.Thrid);
}
catch (Exception ex)
{
  Debug.Assert(false, ex.ToString());
}

以前のバージョンよりもはるかに読みにくいと思いますが。

コードを読みやすくしながら、後でどこから来たのかを確認できるように、関数呼び出しをラップしたり、例外を渡すパターンはありますか?

4

7 に答える 7

4

おそらくやりたいことは、例外の文字列値だけでなく、例外スタック トレースをキャプチャして表示することです。

これを行うには、例外で StackTrace プロパティを使用します。これにより、例外が発生した場所を確認できます。

catch (Exception e) { 
    Console.WriteLine(e.StackTrace);
}

印刷する方法のサンプル。それをデバッグシステムに統合する方法を理解できると確信しています。

于 2009-11-12T16:13:59.310 に答える
2

functioncall()メソッド内にtry / catchを追加し、そこでdebug.assertも追加します。どうしても必要な場合は、例外を再スローして、このコードのビットにチェーンを渡すことができます。

于 2009-11-12T16:12:15.163 に答える
2

スタック トレースの行番号は、3 つのうちのどれが呼び出されたかを示します。

于 2009-11-12T16:12:55.710 に答える
1

ペイロードの一部として列挙値を運ぶ独自の例外クラスを作成するのはどうですか? スタック トレースを唯一の情報源に頼る必要がないように、ログ メッセージをよりわかりやすいものにすることもできます。

于 2009-11-12T16:12:58.890 に答える
1

オプション 1functionCall()コンテキスト情報を使用してカスタム例外を再スローするように 変更します。Debug.Assertロギング、呼び出しなどのために、より高いレベルで例外をキャッチします。

オプション 2 このパターンでは、読みやすさが若干損なわれますが、例外処理ロジックを再利用できます。注意: 分かりやすさを犠牲にしてデリゲート手法を使いすぎると、コード臭くなる可能性があります。

static void InvokeActionWithContext(Action action, string description) {
   try 
   {
     action();
   }
   catch(Exception ex)
   {
     throw new AnExceptionWithContext(description, ex);
   }
}

// call like this
InvokeActionWithContext( 
   () => classVar = functionCall(input, sEnum.Third),
   "Initializing value three"
);
于 2009-11-12T19:37:10.413 に答える
0

これは最も洗練されたソリューションではないかもしれませんが、別の変数を追加して、現在のステップを追跡できます。

    int step = 0;
    try
    {
       classVar = functionCall(input, sEnum.First);
       step++;

      classVar = functionCall(input, sEnum.Second);
      step++;

      classVar = functionCall(input, sEnum.Third);
   }
   catch (Exception ex)
   {
      //examine the step variable here

      Debug.Assert(false, ex.ToString());
   }
于 2009-11-12T16:16:03.487 に答える
-1

これは少し素朴ですが...

ExceptHandler<sEnum> h = new ExceptHandler<sEnum>();
try
{
  h.Step = sEnum.First;
  classVar = functionCall(input, sEnum.First);
  h.Step = sEnum.Second;
  classVar = functionCall(input, sEnum.Second);
  h.Step = sEnum.Third;
  classVar = functionCall(input, sEnum.Third);
}
catch (Exception ex)
{
  h.AssertException(ex.ToString());
}

ExceptHandler は基本的に、実行中の実際の状態を保持するステート マシンです。特定の場合にそれを継承する基本クラスとして定義できます...

より.NETのように編集しました:)

于 2009-11-12T16:15:10.370 に答える