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