I’ve been playing with Code Contracts and something about purity keeps coming up. In terms of side effects, what exactly is the guarantee offered by IEnumerable and IEnumerator?
IEnumerators are, by the very nature, impure objects. Being more like the index variable in a loop than real objects, they should be used once and discarded. ILists, on the other hand, are generally durable objects. You can iterate through them as often as you like with no ill effects. So our first two rules are clear. Any function that takes an IEnumerator is impure while any that takes an IList is, assuming read-only access, pure. IEnumerable is the tricky case. There is nothing in the contract that says GetEnumerator has to be free from side-effects, but off hand I can’t think of anything where it would be a problem.
This is important for API design because it changes what signatures need to be exposed. If you can’t trust GetEnumerator to be pure, then any classes that accept IEnumerator should also accept arguments of type IList.