18

例外をスローするべきか、呼び出すべきか迷っていますContract.Requires<TException>

例えば:

public static void Function(String str)
{
    if (str == null) throw new ArgumentNullException("str", "Input string cannot be null.");

    // ...
}

public static void Function(String str)
{
    Contract.Requires<ArgumentNullException>(str != null, "Input string cannot be null.");

    // ...
}

Contract.Requires<TException>はシンボルを必要としないため、CONTRACTS_FULLリリース ビルドでも保持できます。

これは私の考慮事項です:

短所:カスタム例外型コンストラクターのオーバーロードされたバージョンを呼び出すことはできません。追加のパラメーターをコンストラクターに渡す方法はまったくありません。

長所:静的ツールのサポート (呼び出し元に契約違反を通知するなど)。

どちらを使用すればよいですか? また、どのような場合に使用しますか?

4

2 に答える 2

8

CodeContract ユーザー ガイドに記載されているif-then-throwとの間の基本的なトレードオフは、リリース ビットを使用してビルドする方法です。Requires<TException>

ケース 1 : のみを使用if-then-throwします。いいえRequires<TException>。この場合、dll/exe でコントラクト ツールを実行せずにリリース ビットをビルドできます。利点は、ビルドが高速で、ツールによってバグが発生するリスクがないことです。2 つ目の利点は、チーム メンバーが CodeContract ツールの使用をオプトアウトできることです。欠点は、require のコントラクト継承が得られないことと、( を使用しない限りEndContract) コントラクトがツールに表示されるとは限らないことです。このケースは、アセンブリ モードを使用して指定します: カスタム パラメーターの検証

ケース 2 : 常にリリース ビットで CodeContract ツールを実行することにしましたRequires<TException>これにより、インターフェイスのインストルメンテーションなどを含むコントラクトの継承を使用および取得できます。コントラクトはクリーンで、ツールで認識できます。欠点は、コードを作成するすべての人が CodeContracts ツールをインストールする必要があることです。このケースを指定するには、コントラクト プロパティ ペインのアセンブリ モード: 標準を使用します。

これで問題が解決することを願っています。

于 2013-04-26T22:28:18.080 に答える
2

この 2 つのアプローチに圧倒的な違いがあるかどうかはわかりませんが、私がコントラクトを好む理由が 2 つあります...

1) メソッドが基づいている前提を示すステートメントをメソッドの先頭に書いているため、コードははるかにきれいです。仮定に違反した場合に何が起こるかの実装でコードを詰まらせることはありません。

2) コードを記述しているときに Visual Studio がコード コントラクトを取得し、呼び出すメソッドが何を期待しているかについてのヒントを提供するという利点があります。これにより、メソッド定義にジャンプしてそこでコードをチェックすることなく、メソッドの有効なパラメーターを送信していることを確認できます。

コードがコンパイルされて実行されると、大きな違いはないと思います。

お役に立てれば。

于 2013-03-01T14:40:23.950 に答える