I have an IEnumerable
parameter that is required to be non-empty. If there's a precondition like the one below then the collection will be enumerated during it. But it will be enumerated again the next time I reference it, thereby causing a "Possible multiple enumeration of IEnumerable" warning in Resharper.
void ProcessOrders(IEnumerable<int> orderIds)
{
Contract.Requires((orderIds != null) && orderIds.Any()); // enumerates the collection
// BAD: collection enumerated again
foreach (var i in orderIds) { /* ... */ }
}
These workarounds made Resharper happy but wouldn't compile:
// 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());
There are other workarounds that would be valid but maybe not always ideal like using ICollection or IList, or performing a typical if-null-throw-exception.
Is there a solution that works with code contracts and IEnumerables like in the original example? If not then has someone developed a good pattern for working around it?
Use one of the methods designed to work with IEnumerable
s, such as Contract.Exists
:
Determines whether an element within a collection of elements exists within a function.
Returns
true if and only if predicate returns true for any element of type T in collection.
So your predicate could just return true
.
Contract.Requires(orderIds != null);
Contract.Requires(Contract.Exists(orderIds,a=>true));