I am glad the question is here. While the concept of deferred execution is well known, people still make the mistake and enumerate IEnumerable
multiple times, even Eric Lippert did not avoid that in https://ericlippert.com/2014/10/20/producing-combinations-part-three/ . Doing so may and eventually will break your code. If you need to enumerate IEnumerable
multiple times, materialize it (for example with ToList
).
Edit
with all respect to authority of Eric Lippert, let me show how bad multiple enumeration can be. Here is the correct result, based on list:
Zero,One,Two
Zero,One,Three
Zero,One,Four
Zero,Two,Three
Zero,Two,Four
Zero,Three,Four
One,Two,Three
One,Two,Four
One,Three,Four
Two,Three,Four
and here is what happens when we process sequence with unstable order:
Three,One,Four
Four,Two,One
One,Zero,Three
One,Zero,Four
Three,Two,Zero
One,Four,Zero
Two,Four,One
Two,Three,Four
Two,Three,Four
Four,Three,One
and to the points
- one of the enumerations was to count the sequence; a sequence
that does not have a stable count when enumerated multiple times is
a sequence that you should not attempt to make combinations out of!
- counting does not necessarily enumerate the sequence.
- in that series I strongly encourage the use of immutable data structures which are always safe and performant when enumerated
multiple times.
- I agree that trying to make combinations of sequence with unstable count is questionable. But it is not the case here. The sequence has given count and guaranteed items, they are just randomly ordered. Imagine it can be result from some fancy HashSet that can rearrange its internal structure between enumerations for optimization reasons.
- That is true. That possibility is there. But is that really an argument?
- If that is a contract, ok. You expect sequence that you can enumerate as many times as you wish and always get the same result. Stating that explicitely would avoid confusion, not every sequence has this property.