У меня есть параметр IEnumerable
, который должен быть непустым. Если есть предварительное условие, подобное приведенному ниже, тогда коллекция будет перечисляться во время этого. Но в следующий раз я буду ссылаться на него. (A "Возможное множественное перечисление IEnumerable" предупреждение в Resharper.)
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.
Есть ли решение, которое работает с кодовыми контрактами и IEnumerables, как в исходном примере? Если нет, то кто-то разработал хороший образец для работы вокруг него?