10

私は学校の目的で独自の ArrayList を実装していますが、少し刺激を与えるために、C# 4.0 コード コントラクトを使用しようとしています。コンストラクターにコントラクトを追加する必要があるまでは、すべて問題ありませんでした。空のパラメーター コンストラクターに Contract.Ensures() を追加する必要がありますか?

    public ArrayList(int capacity) {
        Contract.Requires(capacity > 0);
        Contract.Ensures(Size == capacity);

        _array = new T[capacity];
    }

    public ArrayList() : this(32) {
        Contract.Ensures(Size == 32);
    }

はい、各メソッドには明確に定義されたコントラクトが必要です。一方、「メイン」コンストラクターに作業を委譲するだけなら、なぜそれを置くのでしょうか? 論理的には、その必要はありません。

両方のコンストラクターでコントラクトを明示的に定義することが役立つと思われる唯一のポイントは、将来、コントラクトの Intelisense サポートがあるかどうかです。その場合、Intelisense で表示されるように、各メソッドが持つコントラクトを明示すると便利です。

また、Design by Contracts の原則と使用法についてもう少し詳しく説明している本はありますか? 1 つのことは、言語 (この場合は C#) でコントラクトを使用する方法の構文に関する知識を持っていることであり、もう 1 つはそれをいつどのように使用するかを知っていることです。いくつかのチュートリアルと、それに関する Jon Skeet の C# in Depth の記事を読みましたが、可能であればもう少し深く掘り下げたいと思います。

ありがとう

4

5 に答える 5

5

私はトーマスの答えに完全に同意しません。の実装で選択を行っている限り、ArrayList()これらの選択を文書化した契約を結ぶ必要があります。

ここでは、引数 32 を使用してメイン コンストラクターを呼び出すことを選択しています。(既定のサイズの選択だけでなく) 決定できることは他にもたくさんあります。それに契約を与えることは、直接呼び出す代わりに実行できたはずのばかげたことのほとんどを実行しないことArrayList()にしたドキュメントの契約とほとんど同じです。ArrayList(int)

「メインコンストラクターを呼び出すので、メインコンストラクターのコントラクトに仕事をさせてください」という答えは、コントラクトが実装を見る必要をなくすためにあるという事実を完全に無視しています。実行時のアサーション チェックに基づく検証戦略の場合、別のコンストラクター/メソッドをほぼ直接呼び出すような短いコンストラクター/メソッドであってもコントラクトを記述することの欠点は、2 回チェックすることになることです。はい、冗長に思えますが、実行時のアサーション チェックは検証戦略の 1 つに過ぎず、DbC の原則はそれとは無関係です。原則は次のとおりです。呼び出すことができる場合、それが何をするかを文書化するための契約が必要です。

于 2010-05-04T23:59:27.123 に答える
1

を使用するクライアント コード (コード コントラクトを使用ArrayList)EnsureSize == 32Ensure.

だから(例えば):

var x = new ArrayList();
Contract.Assert(x.Size == 32)

「アサートは証明されていません」という警告が表示されます。

すべての契約を明示的に述べる必要があります。コード コントラクト リライター/静的チェッカーは、メソッドを「調べて」影響を確認しません。関連する質問に対する私の回答を参照してください。

于 2010-05-05T22:55:47.310 に答える
1

どちらも Bertrand MeyerのObject Oriented Software Construction, 2nd EditionまたはTouch of Classを読むことをお勧めします。あるいは、同じ著者による 1992 年の記事Applying "Design by Contract"を読むこともできます。

要約する:

  • クラスの不変条件は、コンストラクター (それらのいずれか) が終了した後、およびクラスのパブリック メソッドが実行される前後に保持する必要があります。
  • メソッドの事前条件事後条件は、不変条件とともに、パブリック メソッドに出入りするときに保持する必要がある追加の条件です。

したがって、あなたの場合は、不変条件に注目してください。どのコンストラクターが呼び出されても、正しいオブジェクト (クラスの不変条件を満たすオブジェクト) を生成します。

この関連する回答では、例を含め、同様のトピックについて説明しました。

于 2010-06-29T08:18:39.403 に答える
0

コントラクトによる設計は、関数型プログラミングの数学的ルーツであるPreconditionsPostconditionsに由来します。

それについての本は本当に必要ありません。それはせいぜいコンピューターサイエンスの学位の章です (ほとんどは概念を教えます)。基本的な前提は、関数が期待する前提条件と、正しいパラメーターが与えられたときに生成される出力を記述することです。この関数は、不適切な初期パラメーターでは機能しないと予想されます。アルゴリズムについても同じことが言えます。それは確実であり、期待される結果を提供することが保証されています。

それが私が現在勉強している学位で教えられた方法ですが、もっと良い定義があるかもしれません. 契約による設計に関するウィキペディアの記事はオブジェクト指向の傾斜で書かれていますが、事前/事後条件は言語に依存しません。

于 2010-05-05T23:17:20.117 に答える
0

ええと、「Ensures」をデフォルトの c'tor にも入れた理由がよくわかりません。すでに完全なコントラクトを実装しているメインの c'tor を呼び出すため、デフォルトの c'tor もそれを行います (定義上)。したがって、これは論理的な冗長性であり、大きな「禁止事項」です。あなたが言うように、多分それは実用的な意味を持っているかもしれません-Code Contractsがそれほど良いことを知りません...

文献に関して - 最良の情報源は次のとおりです。

チッ!トーマス

于 2010-05-04T17:19:37.403 に答える