C# - The yield keyword
This is an interesting feature that I saw in one of the feeds that is on my list. Follow the text and reference:
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...