5

次のロジックのコードが少しあります。

//pseudo-code
foreach (element in elementList) {
    if (element is whatever)
        return element;
    }
}

理論的には、常に1つの要素が存在するため、この方法では問題は発生しません。いずれにせよ、念のため、メソッドの最後にアサーションを付けました。

//pseudo-code
foreach (element in elementList) {
    if (element is whatever)
        return element;
    }
}

Contract.Assert(false, "Invalid state!");

問題は、このメソッドが何かを返す必要があり、コンパイラがアサーションがプログラムの実行を中断することを理解していないことです。コントラクトを使用する前は、このような状況で、問題を解決するために例外をスローしていました。これをContract.Assert()でどのように処理しますか?Contract.Assert()呼び出しの後にnullまたはdefault(element_type)を返し、それが呼び出されないことを認識してコンパイラーをシャットダウンしますか?または、これを行う他のよりエレガントな方法はありますか?

ありがとう

4

2 に答える 2

2

あなたは一緒に行くことができます

var result = null;
foreach (element in elementList) {
    if (element is whatever)
        result = element;
        break;
    }
}

Contract.Assert(result != null, "Invalid state!");
return result;

それは休憩をもたらしますが、それはリターンの周りでよりきれいに見えます。

さらにきれいになります

return elementList.Where( e => e is whatever).First();

@devouredが指摘したように編集すると、上記がリスト全体にヒットします

どこのないクリーナー

return elementList.First( e => e is whatever);

編集終了

何も見つからない場合、それはただ爆発します。

しかし、本当にアサーションが必要な場合は、

var results = elementList.Where( e => e is whatever);
Contract.Assert(results.Count() == 1, "Boo");
return results.First();

しかし、それはリスト全体も繰り返します。

于 2010-05-06T07:03:25.833 に答える
1

Contract.Requiresここよりも(前提条件)の方がいいと思いますContract.Assert。スニペットの前提条件は、elementListに条件が成立する要素が少なくとも1つ含まれていることです。

Assert(false)読者が関数の残りの部分を理解し、フロー制御に従って到達する状況を推測する必要があるに依存するのではなく、それについて明示する必要がありAssert(false)ます。

だから、私は次のように書き直します:

//precondition (checked only in debug builds)
Contract.Require(elementList.Where(e => e is whatever).Count > 0,"elementList requires at least one element meeting condition whatever");
//do work (throws in release builds, never reached in debug ones)
return elementList.First( e => e is whatever);
于 2010-08-03T14:46:16.600 に答える