Sunday, May 11, 2008

Return Yield and Return?

Debugging some c# code involving the yield statement revealed some interesting behavior.
The implementation of the yield statement is more complex than it appears on the surface.
Consider the following code:

class Program
{

static void Main(string[] args)
{
foreach (string state in collection())
{
Console.WriteLine(state);
}

Console.ReadLine();
}

private static IEnumerable collection()
{
// Console.WriteLine("before Alaska");
yield return "Alaska";
// Console.WriteLine("before Alabama");
yield return "Alabama";
// Console.WriteLine("before Kentucky");
yield return "Kentucky";

}

}

///////////////////

As expected this code results in:
Alaska
Alabama
Kentucky

Now uncomment the additional Console.Writeline statements and the code will result in:
before Alaska
Alaska
before Alabama
Alabama
before Kentucky
Kentucky

Unless you have discovered this already this should be unsettling. If you are not seeing what the big deal is set breakpoints on every line of code (stepping through is not enough). What you will see is the code appearing to hop in and back out of the collection function and then back in at the line after the line it left on. It is not executing the function repeatedly and it is not exiting it completely.

This behavior has few equivalents anywhere else in the c# language. There is power here (probably not widely known) and there is danger here (probably now widely understood).

permalink

No comments: