Ho un parametro IEnumerable
che è necessario non vuoto. Se c'è una precondizione come quella qui sotto, la raccolta verrà enumerata durante questo. Ma verrà enumerato di nuovo la prossima volta che lo riferimento. (A "Possibile enumerazione multiplo di IEnumerable" avvertimento in ReSharper.)IEnumerazione di enumerazione multipla causata dalla precondizione del contratto
void ProcessOrders(IEnumerable<int> orderIds)
{
Contract.Requires((orderIds != null) && orderIds.Any()); // enumerates the collection
// BAD: collection enumerated again
foreach (var i in orderIds) { /* ... */ }
}
Queste soluzioni alternative fatte ReSharper felice, ma non sarebbe la compilazione:
// 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());
Non ci sono altre soluzioni che sarebbero valide, ma forse no è sempre l'ideale come usare ICollection o IList, o eseguire una tipica eccezione if-null-throw.
Esiste una soluzione che funziona con i contratti di codice e IEnumerables come nell'esempio originale? Se no, allora qualcuno ha sviluppato un buon modello per aggirarlo?
Penso che probabilmente è solo una cattiva idea quella di avere un contratto dipende da un IEnumerable - come IEnumerables per definizione può incorrere in effetti collaterali. –
Finora ho usato ICollection come soluzione alternativa e non ho mai avuto problemi, anche se sono curioso di sapere se esiste una soluzione per IEnumerables. – Keith