3

ccrewrite を使用しない場合(たとえば、CC がインストールされていない別の開発者によってプロジェクトがビルドされた場合)、

Contract.Requires<T>(cond)静かに削除されますか、それとも と同等の動作になりif (!cond) { throw new T() }ますか? (別のメソッド呼び出しか 2 つかは気にしませんが、「常にチェックする」必要があります。)

Contract.Requires<T>とは動​​作が異なるように見えるので質問しますがContract.Requires、「どのように」または「いつ」かわかりません。

目標は、公共契約の構造を置き換えることです

if (x != null) throw new ArgumentNullException();

ビルドステップ中にCC書き換えを実行しない場合でも例外をスローするCC互換バージョン。

上記はEndContractBlock「カスタムパラメーター検証」(つまり、レガシーコントラクトモード) で機能しますが、プロジェクトで「標準コントラクトが必要」を使用したいと思います。

「カスタムパラメーター検証」モードでは使用できないため、同等があると思いますRequires<T>。常に必要なチェックに相当するものがない場合は、その理由についての洞察があればよいでしょう。

私は、静的分析のためにそれらを評価するので、CC の書き換えが行われないときにRequires、 、Ensures、および不変の不変コントラクト メソッドとインターフェイス コントラクトを失うことは問題ありませんが、CC を維持することを主張するには、常に存在する境界チェックが必要です。

4

1 に答える 1

4

Code Contracts マニュアルを参照してください。さまざまな形式の Code Contract チェックがどのように機能するか、および各形式を使用するときにどのオプションを設定する必要があるかについて、知っておく必要があるすべてのことを明確に示しています。

Contract.Requires(bool cond)との違いは何Contract.Requires<TException>(bool cond)ですか?

最初の質問に答えるには、マニュアルのセクション2.1 前提条件を参照してください。簡単に言えば、違いは次のとおりです。

Contract.Requires(bool cond)

条件が と評価された場合、プライベートContract.ContractException例外がスローされfalseます。この例外をキャッチすることはできません (あなたの観点からはプライベートであるため)。

Contract.Requires<TException>(bool cond)

条件が と評価された場合false、指定されたTExceptionがスローされます。すべてのビルドでコントラクト ツールを実行しないと、このフォームを使用できません。

ccrewrite

具体的には、20 ページのセクション5. 使用ガイドラインで、Code Contracts が使用できるさまざまな形式のコントラクト、それらがどのように機能するか、およびそれぞれのビルド要件について説明しています。

簡単にまとめますが、マニュアルをダウンロードして読んでください。コード コントラクトを効果的に使用する方法を学ぶには、多くの実験を行う必要があります。また、PluralSight にアクセスできる場合は、John Sonmez がCode Contractsという優れた入門コースを提供しています。Michael Perry にはProvable Codeという素晴らしいコースがあります。

リリースされたコードにはコントラクトのチェックは必要ありません

リリースされたコードでコントラクト チェックが必要ない場合は、次のようにします。

  • Contract.Requiresどこでも使用
  • デバッグ ビルドのみでランタイム チェックを有効にします。

リリースされたコードにはコード コントラクト チェックが必要です

リリースされたコードのコントラクト チェックが必要な場合は、次の 2 つのオプションがあります。

  1. Code Contracts の「ネイティブ」前提条件を使用します。
    • Contract.Requires<TException>特定の例外をスローするパブリックAPI メソッド (ライブラリのユーザーによって呼び出されるメソッドなど) で使用しますArgumentException
    • Contract.RequiresパブリックAPI メソッドまたは 特定の例外をスローしたくないパブリックAPI メソッドに使用します。
    • すべてのビルドでランタイム チェック有効にします。
    • 前提条件のみを発行し、アセンブリのパブリック サーフェス エリア(ライブラリ コンシューマーによって呼び出し可能なメソッドのみなど) のみを発行するオプションを有効にしていることを確認してください。
  2. 「レガシー」コントラクト チェックを使用します。
    • これは、パブリックAPI メソッドの古い学校スタイルのif (cond) { throw new Exception(...) }ガード ブロックです。
    • 手動継承を使用して、派生型にコントラクトを適用します。(オプション 1 を使用する場合、コード コントラクトは基本クラスからコントラクトの自動継承を実行できるため、Liskov Substitution Principle 違反を回避できます。)
    • Code Contracts がこれらがあなたのコントラクトであることを認識できるように、必ずContracts.EndContractBlock()すべてのブロックの後に行を配置してください。if (cond) { throw new Exception(...) }
    • 非パブリックAPIメソッドでContract.Requiresは、コントラクトに自由に使用できます。
    • デバッグ ビルドでのみランタイム チェックを有効にします。

上記について 1 つの注意点: コントラクト チェックは、デバッグビルドで常に有効になっています。チームの他の開発者がこのライブラリを構築する場合は、Code Contracts もインストールする必要があります。

セクション 5.1.3から: プロジェクトを強制的にコントラクトでビルドする:

シナリオ 2 (Requires⟨Exn⟩) を使用していて、ソース コードを他の開発者が利用できるようにする場合は、ソースをビルドするためにツールを使用する必要があることを彼らに警告したい場合があります。その場合は、次のスニペットをプロジェクト ファイルの最後 (CSharp または VisualBasic ターゲットのインポート後) に挿入できます。

<PropertyGroup>
<CompileDependsOn>$(CompileDependsOn);CheckForCodeContracts</CompileDependsOn>
</PropertyGroup>
<Target Name="CheckForCodeContracts"
        Condition="'$(CodeContractsImported)' != 'true'">
  <Error Text="Project requires Code Contracts: http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx" />
</Target>

また、セクション 6.1: アセンブリ モードを参照してください。ここでは、カスタム パラメータの検証標準のコントラクト Requiresの違いについて説明しています。このセクションでは、コントラクト リライター ( ccrewrite) が常にデバッグビルドで実行されることを明確にしています。

于 2016-02-20T19:49:52.930 に答える