Here's my previous accepted answer to exactly the same question:
http://stackoverflow.com/questions/384392/yield-keyword-value-added/384404#384404
Another way to look at iterator methods is that they do the hard work of turning an algorithm "inside out". Consider a parser. It pulls text from a stream, looks for patterns in it and generates a high-level logical description of the content.
Now, I can make this easy for myself as a parser author by taking the SAX approach, in which I have a callback interface that I notify whenever I find the next piece of the pattern. So in the case of SAX, each time I find the start of an element, I call the beginElement
method, and so on.
But this creates trouble for my users. They have to implement the handler interface and so they have to write a state machine class that responds to the callback methods. This is hard to get right, so the easiest thing to do is use a stock implementation that builds a DOM tree, and then they will have the convenience of being able to walk the tree. But then the whole structure gets buffered up in memory - not good.
But how about instead I write my parser as an iterator method?
IEnumerable<LanguageElement> Parse(Stream stream)
{
// imperative code that pulls from the stream and occasionally
// does things like:
yield return new BeginStatement("if");
// and so on...
}
That will be no harder to write than the callback-interface approach - just yield return an object derived from my LanguageElement
base class instead of calling a callback method.
The user can now use foreach to loop through my parser's output, so they get a very convenient imperative programming interface.
The result is that both sides of a custom API look like they're in control, and hence are easier to write and understand.