29

最初は非常に便利に思えたので、新しいSystem.Diagnostics.Contractsクラスで遊んでいます。インバウンド引数や戻り値などをチェックする静的メソッド。これはクリーンなインターフェイスであり、多くのif-thenステートメントや内部で構築されたライブラリツールを置き換えることができました。

ただし、ほとんどの実行時の状況ではあまり役に立たないようです。私の知る限り、エラーは発生しないので、契約が失敗したかどうかを知ることはできません。エラーのあるダイアログボックスが表示されます。人間がほとんど見ないリモートボックスでwcfサービスを実行している場合、契約が失敗したことをどのようにして知ることができますか?エラーが発生したという事実をトラップできない場合、サービスの呼び出し元に、彼らが失敗したことをどのように知らせることができますか?

Throw-Catchはしばらく前から存在していますが、コントラクトがこれをバイパスしたい理由がわかりません。私はこれを間違って使用しようとしていますか?もしそうなら、誰かが私にランタイムコントラクトが理にかなっている現実の状況を教えてくれます。ケン

4

1 に答える 1

38

私が知る限り、エラーはスローされないため、コントラクトが失敗したかどうかを知ることはできません。

コードを呼び出してキャッチするために特定の例外をスローする必要がある場合は、Contract.Requires<TException>メソッドまたは従来の if-then-throws の後にを使用する必要がありますContract.EndContractBlock()。たとえば、他のコードが通常の例外がスローされることを既に期待し、依存している場合に、これを行います。

さまざまな形式の前提条件をいつ使用するかについての完全な説明については、ユーザー マニュアルのセクション 5.1: 引数の検証とコントラクトを参照してください。

エラーが表示されたダイアログ ボックスが表示されます。

プロジェクト設定の [Code Contracts] タブで [Assert on Contract Failure] のチェックを外すと、ダイアログ ボックスではなく、デバッグ中にコード内の問題点で実際の例外がスローされます。ただし、これはキャッチするためのものではありません。

Throw-Catch はしばらく前から存在していましたが、Contracts がこれをバイパスしたい理由がわかりません。私はこのことを間違って使用しようとしていますか? もしそうなら、ランタイム コントラクトが理にかなっている実際の状況を教えてください。

セクション 7.5: Rational for Runtime Behaviorとセクション 7.6:ユーザー マニュアルのContractExceptionで、このように機能する理由が説明されています。

これは、契約違反を処理する特定のロジックを含むプログラムを作成する必要がないようにするためです。それらは正しいプログラムでは決して発生してはならず、修正が必要なコードの重大な障害を示しています。これは、キャッチを回避する方法に似ていますArgumentNullException

ファイルが見つからない場合など、コード自体の障害を示さない例外的な状況では、通常の例外を引き続きスローする必要があります。これにより、呼び出し元のコードがその状況を適切に処理できるようになります。

人間がめったに見ないリモートボックスで wcf サービスを実行している場合...コントラクトが失敗したことをどのように知ることができますか?

できれば、ソフトウェアを使用する前にできる限りテストして、契約に違反していないことを確認する必要があります。

実行時の動作をオーバーライドする必要がある場合は、独自のコントラクト ランタイム クラスを記述して実行できます。詳細については、ユーザー マニュアルのセクション 7.7: カスタム コントラクト ランタイム クラスの提供を参照してください。

編集:以下のコメントに応えて...

コードの障害を見つけるためのものだとおっしゃっていますが、コードの障害のほとんどは、コードの障害ではなく、外部ソースから渡されたデータに起因しています。また、ソフトウェアは、誰かが不正なデータを渡したという事実をログに記録することと、不正なデータを渡したことが修正できるように通知することの両方を行う必要があります。

前提条件は、メソッドの呼び出しがいつ許可されるかを定義するコントラクトであり、メソッドの呼び出し時に呼び出し元によって検証されることを意図しています。ランタイム チェッカーは、メソッド自体ではなく、呼び出し元のコードに適切なチェックを挿入します。静的チェッカーを利用できる場合は、そのメソッドを呼び出す前に前提条件を確認できなかった場合に指摘されます。

あなたの状況では、データを処理する内部メソッドは、許可するデータの種類を示す前提条件を定義する必要があります。制御できない外部ソースからデータが渡された場合は、それを検証し、通常の方法で処理する必要があります。これにはコード コントラクトを使用したくありません。ただし、たとえば、そのデータを完全に検証するのを忘れた場合、前提条件を指定して内部コードを呼び出すと、契約違反が発生します。これは、独自のコードにバグがあることを示しています。

于 2010-08-06T20:31:49.723 に答える