いつコードコントラクトに対してdebug.assertをデバッグする必要がありますか?メソッドの前提条件を確認したいのですが、どちらを選択するか混乱しています。失敗シナリオをテストし、例外を予期する単体テストがあります。
同じメソッドでDebug.Assertとコードコントラクトを使用することは良い方法ですか?もしそうなら、コードが書かれるべき順序は何ですか?
Debug.Assert(parameter!= null);
Contract.Requires<ArgumentNullException>(parameter != null, "parameter");
または
Contract.Requires<ArgumentNullException>(parameter != null, "parameter");
Debug.Assert(parameter!= null);
その背後に根拠はありますか?
これらは異なるものです。デバッグアサートは、コードがデバッグとしてコンパイルされたときにのみ実行されるため、デバッグ時にのみチェック/アサートします。これは、開発中のコードの「健全性チェック」にこれを使用するという考え方です。コードコントラクトは、デバッグまたはリリースで使用できます。彼らは、メソッドの事前条件と事後条件がメソッドの期待に準拠している(契約を満たす)ことを保証します。テストのコンプライアンスをチェックするために設計された、同様の機能を提供するテストフレームワークもあります。
コードの開発時(およびその後のメンテナンス開発時)に特定のものが期待どおりであることを確認したい場合は、Debug.Assertを使用します。
デバッグとリリースの両方で条件が満たされていることを確認する場合は、コードコントラクトを使用します。コントラクトでは、プログラムが「正しい」ことを確認するのに役立つ特定の形式の静的分析も許可されます。
単体テストを作成するときは、テストフレームワークアサーションを使用します。
個人的に、私は_Debug.Assert
_とコードコントラクトの両方を使用して、新しく記述されたコードの前提条件を適用しません-IMOコードコントラクトは_Debug.Assert
_に優先します。コードが実行時になる前に実行できる静的チェックから取得できます。 _Debug.Assert
_とContracts
の両方で前提条件チェックの重複を維持するのは面倒です。
根拠:
Debug.Assert
_またはthrow
コードでコーディングしたレガシーの前提条件を再コーディングする必要はありません。既存の前提条件チェックコードを保持し、 Contract.EndContractBlock()
System.Diagnostics.Debug
_なしで_/d:DEBUG
_をビルドする場合、コントラクトランタイムチェックをNone
に設定してビルドすると、同じ未チェックの「リリースモード」の動作が得られます。 ドキュメントの6.2.1を参照Contract.Requires
_)が直接原因でした。それ以外の場合、_Contract.Assert
_または_Contract.Assume
_は一般的な状態をチェックでき、メソッドを終了するときの状態の「保証された正確さ」は_Contract.Ensures
_を使用して表現できます。そして、Invariants
は、常に状態を保持しなければならないことを表しています。注意点の1つ:意図的に契約に違反する単体テストを作成する場合は、ContractException
に対処する必要があるかもしれません-Jon Skeetがこれをうまく説明しています here 。例えばテストセットアップの _Contract.ContractFailed
_ハンドラー をSetHandled
を呼び出すハンドラーに接続し、UTでキャッチしてアサートできるパブリック例外をスローします。