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 で動作するソリューションはありますか? そうでない場合、誰かがそれを回避するための適切なパターンを開発しましたか?