2

私のコード ベースには、#if DEBUG/#endif実稼働環境で実行する勇気がないアサーション タイプのロジックを主に含む多くのステートメントがあります。

[Conditional("DEBUG")]
public void CheckFontSizeMath()
{
  //This check must not block SellSnakeOil() in production, even if it fails.
  if(perferredSize+increment!=increment+preferredSize)
    throw new WeAreInAnUnexpectedParallelUniverseException();
}

これらすべてを新しい方法に変更したことを後悔しますか?

更新: アサーションを行うための 2 つの類似しているが異なる構文スタイルの特性の違いを探しています。アプリケーションの動作を実証する方法は他にもたくさんあることは理解しており、私もそれを行っています。アサーションを完全に放棄する準備はできていません。

また、現実的なデバッグ リリースのみのシナリオに合わせてメソッド名を更新しました。

4

4 に答える 4

3

これで問題ありません。より新しいアプローチは、Code Contractsを使用することです。

于 2010-08-26T18:38:01.267 に答える
2

テストを書いてください!そうすれば、これらの変更を開始するときに、コードが予期しないことを行っていることを恐れる必要はありません。

テスト対象のコードを取得したら、心ゆくまでリファクタリングできます。

テストのないコードは、たとえ昨日書かれたとしても、レガシー コードです... Working Effectively with Legacy Codeのコピーを入手してください。5 つ星の 32 件のレビュー。

于 2010-08-26T18:39:08.117 に答える
1

あなたが持っている他のオプションは、ハンスによって提案されたようにコードコントラクトを使用するか、System.Diagnostics.Debug名前空間でアサーションメソッドを使用することです。

Debug.Assert(1 + 1 == 2, "Math went wrong!");

このチェックは、リリース バージョンのビルド時に自動的に削除されます。

于 2010-08-26T18:47:26.557 に答える
1

欠点:

  1. ビルド構成とは無関係に機能するハード チェックや例外ほど堅牢ではありません。ほとんどのコードはリリース モードでエラーを処理する必要があるという事実を考慮することをお勧めします。

  2. 動作は構成によって異なる可能性があります。不注意であると、条件付きメソッドに非デバッグ ロジックを配置したり、副作用を追加したりして、製品コードが正しく機能しない可能性があります (基本的には、C++ の ASSERT() マクロ内で誤ってメソッドを呼び出すのと同じことです。効果は最悪です!) ここでの最大のことは例外です。条件付きメソッドでは、何らかの理由で値を返すことができないため、潜在的なエラーが 1 つ排除されます。ただし、例外をスローして、エラー状態が発生したときにたどるパスを劇的に変更することができます。これにより、物事の理解と維持が難しくなります。

  3. 呼び出しサイトでは、条件付きメソッドが呼び出されていることは明らかではありません。「DoSomething();」と表示されるだけです。私は、それが条件付きであることがわかっている規則に従って、条件付きメソッドに名前を付けることを好みます。例: DEBUG_SanityCheckBufferContents()。

  4. メソッド本体を #if アウトしない場合、デバッグ コードは引き続き存在し、特にリフレクションを介して検査/呼び出すことができます。メソッドの IL は引き続き発行されますが、呼び出しサイトは発行されません。

  5. 構成によって動作が異なるため、単体テストが非常に困難になります。これはポイント 2 と同じですが、テストの観点からは非常に厄介なので、別のポイントとして追加しました。ほとんどの開発者は、チェックインする前にデバッグまたはリリースでテストを実行しますが、両方ではありません。私たちの CI は両方のテスト セットを実行するため、すべてのテストに合格した後に何かをチェックインして、デバッグ構成が壊れていて、リリース ビルドを実行したためにテストに合格した (またはその逆) ことを見つけるのは面倒です。

要するに、私の経験則は次のとおりです。

  • 単体テストでハード チェックと例外を優先します。これが不可能な場合は条件付きメソッドを使用します (パフォーマンス クリティカル チェックなど)。
  • 条件付きメソッドに明確な名前を付ける
  • メソッド本体のプラグマ #if out コード
  • 条件付きメソッドでプログラム制御フローを変更することには十分に注意してください (条件付きメソッドを使用する場合、個人的には例外ではなく Debug.Assert を好みますが、他の多くのプログラマーが例外を使用しているのを見たことがあるので、これはおそらく議論の余地があります)。
于 2010-08-26T18:50:47.810 に答える