12

IEnumerable空でないことが必要なパラメーターがあります。以下のような前提条件がある場合、コレクションはその間に列挙されます。しかし、次に参照するときに再度列挙されるため、Resharper で「IEnumerable の複数列挙の可能性」という警告が発生します。

void ProcessOrders(IEnumerable<int> orderIds)
{
    Contract.Requires((orderIds != null) && orderIds.Any());  // enumerates the collection

    // BAD: collection enumerated again
    foreach (var i in orderIds) { /* ... */ }
}

これらの回避策はResharperを満足させましたが、コンパイルしませんでした:

// enumerating before the precondition causes error "Malformed contract. Found Requires 
orderIds = orderIds.ToList();
Contract.Requires((orderIds != null) && orderIds.Any());
---
// enumerating during the precondition causes the same error
Contract.Requires((orderIds != null) && (orderIds = orderIds.ToList()).Any());

ICollection や IList を使用したり、典型的な if-null-throw-exception を実行したりするなど、有効であるが常に理想的であるとは限らない他の回避策があります。

元の例のように、コード コントラクトと IEnumerables で動作するソリューションはありますか? そうでない場合、誰かがそれを回避するための適切なパターンを開発しましたか?

4

1 に答える 1

8

IEnumerable次のように、 sで動作するように設計された方法の1つを使用しContract.Existsます。

要素のコレクション内の要素が関数内に存在するかどうかを判別します。

戻り値

コレクション内のタイプTの要素に対して述語がtrueを返す場合にのみtrue。

したがって、述語は単にを返す可能性がありますtrue


Contract.Requires(orderIds != null);
Contract.Requires(Contract.Exists(orderIds,a=>true));
于 2012-07-04T10:35:35.880 に答える