August 13th, 2008

The implementation of iterators in C# and its consequences (part 2)

Now that you have the basic idea behind iterators under your belt, you can already answer some questions on iterator usage. Here’s a scenario based on actual events:

I have an iterator that is rather long and complicated, so I’d like to refactor it. For illustrative purposes, let’s say that the enumerator counts from 1 to 100 twice. (In real life, of course, the iterator will not be this simple.)

IEnumerable<int> CountTo100Twice()
{
 int i;
 for (i = 1; i <= 100; i++) {
  yield return i;
 }
 for (i = 1; i <= 100; i++) {
  yield return i;
 }
}

As we learned in Programming 101, we can pull common code into a subroutine and call the subroutine. But when I do this, I get a compiler error:

IEnumerable<int> CountTo100Twice()
{
 CountTo100();
 CountTo100();
}

void CountTo100() { int i; for (i = 1; i <= 100; i++) { yield return i; } }

What am I doing wrong? How can I move the “count to 100” into a subroutine and call it twice from the CountTo100Twice function?

As we saw last time, iterators are not coroutines. The technique above would have worked great had we built iterators out of, say, fibers instead of building them out of state machines. As state machines, all yield return statements must occur at the “top level”. So how do you iterate with the help of subroutines?

You make the subroutine its own iterator and suck the results out from the main function:

IEnumerable<int> CountTo100Twice()
{
 foreach (int i in CountTo100()) yield return i;
 foreach (int i in CountTo100()) yield return i;
}

IEnumerable<int> CountTo100() { for (i = 1; i <= 100; i++) { yield return i; } }

Exercise: Consider the following fragment:

 foreach (int i in CountTo100Twice()) {
  …
 }

Explain what happens on the 150th call to MoveNext() in the above loop. Discuss its consequences for recursive enumerators (such as tree traversal).

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.