A closer look at yield
The yield keyword in C# is pretty powerful and expressive, but it doesn’t seem to be very widely known about. In this post we’ll take a quick look at what yield does and then I’ll post a follow-up that looks at what the compiler generates for you. Let’s start by looking at a simple (and contrived) example:
private static readonly string[] StringValues = new string[] { "The", "quick", "brown", "fox",
"jumped", "over", "the", "lazy", "dog" };
static IEnumerable<string> TestIterator() { foreach(string value in StringValues) { yield return value; } }
The return type for the TestIterator method is IEnumerable<string>, but you can see that we don’t have a return statement in the implementation. Instead, we’re using the yield return statement to return each item that we want the caller to operate on. The compiler automatically generates a class that implements IEnumerable<string> for us. We can call this function using the following code:
foreach(string value in TestIterator()) { Console.WriteLine("In foreach:{0}", value); }
This code will iterate over the IEnumerable<string> instance that is returned from the TestIterator method. In this example we’ve simply iterated over an existing collection, so we’re not providing much functionality! A more interesting example would be for a binary tree such as:
class BinaryTree<T> { public T Item { get; set; } public BinaryTree<T> Left { get; set; } public BinaryTree<T> Right { get; set; } }
In this case, the yield keyword makes it a breeze to add IEnumerable support. First, we add IEnumerable<T> to the implemented interfaces and then we just need the code below to provide the implementation:
public IEnumerator<T> GetEnumerator() { yield return Item; if (Left != null) { foreach (T t in Left) { yield return t; } } if (Right != null) { foreach (T t in Right) { yield return t; } } }
This code returns the item for the current node and then recurses into the items from the left and right hand of the tree – how easy is that? This is one of the big advantages of the yield keyword: it allows you to write readable and concise code to produce an iterator.
Stay tuned for part 2, when we’ll take a look at the code that the compiler generates for us...
Comments
Anonymous
July 14, 2008
PingBack from http://blog.a-foton.ru/2008/07/a-closer-look-at-yield/Anonymous
July 14, 2008
In part 1 , we took a quick tour of the yield keyword. In this post we’re going to have a look at theAnonymous
July 15, 2008
This is an interesting feature that I saw in one of the feeds that is on my list. Follow the text and