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