Множественное перечисление IEnumerable, вызванное предварительным условием контракта

У меня есть параметр 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, как в исходном примере? Если нет, то разработал ли кто-нибудь хороший шаблон для обхода этого?

11
задан Keith 4 July 2012 в 10:29
поделиться