A few posts back, we talked about Arrays and Collections, and how easy they were to deal with.

In this post, we'll talk about a feature of C# that allows us developers to iterate over many different kinds of collections and return elements from them one-by-one. Let's learn about iterators!

## The yield Keyword

Iterators in C# take advantage of a special keyword: `yield`. The `yield` keyword is used exclusively when iterating over collections and arrays, and allows us to return elements in a collection or array individually.

To demonstrate this, let's consider the Fibonacci sequence, where each number is the sum of the previous two numbers. The sequence begins like this:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...

Let's build a C# method to calculate the Fibonacci sequence to a specified number of places.

``````public static IEnumerable<int> Fibonacci(int length)
{
int a = 0, b = 1;
for (int i = 0; i < length; i++)
{
yield return a;
int c = a + b;
a = b;
b = c;
}
}``````

We should note two things about this code block. First of all, the return type of `IEnumerable<int>` states that the return type will be a collection of integers.

We should also note the strange placement of the `yield return a;` line of code. This line tells the compiler that when an iterator iterates over this collection, the value it will get will be the value of `a` at this point. We have placed it before the other lines inside the `for` loop because we want to return the value of `a` before it is changed.

What's most interesting about this `yield return` code block is how we can use it in a `foreach` loop. We can run this method to show the first ten numbers in the Fibonacci sequence like so:

``````static void Main(string[] args)
{
// Display the Fibonacci sequence up to the tenth number.
foreach (int i in Fibonacci(10))
{
Console.Write(i + " ");
}
}``````

Which results in this output:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34

We can even have multiple `yield return` statements in a single code block, such as this example:

``````public static IEnumerable<int> SomeNumbers()
{
yield return 1;
yield return 2;
yield return 7;
yield return 8;
yield return 5;
}``````

The object returned from this method is of type `IEnumerable<int>`, which means we can treat it as a collection of integers and output each number, or use LINQ to find the average of all the numbers.

``````var someNumbers = SomeNumbers();

string allNumbers = "";
foreach(int number in someNumbers)
{
allNumbers += " " + number.ToString();
}

Console.WriteLine(allNumbers.Trim());
Console.WriteLine("Average: " + someNumbers.Average());``````

In short, the `yield` keyword allows us to return elements in a collection one-by-one to a calling method, and the `IEnumerable<T>` interface allows us to specify that a collection of objects can have an iterator.

Now that we know how the `yield` keyword works, we can learn about iterators themselves.

## Iterators

Like the indexers from the previous post, iterators are most useful on collections. Let's create a custom `MonthsOfTheYear` class which holds a list of the months of the year.

``````public class MonthsOfTheYear : IEnumerable
{
private string[] _months =
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
}``````

We can now create an iterator for this class which will `yield return` each month name in the private `_months` array.

``````public class MonthsOfTheYear : IEnumerable
{
//...Other properties and methods
public IEnumerator GetEnumerator()
{
for (int index = 0; index < _months.Length; index++)
{
// Yield each month of the year.
yield return _months[index];
}
}
}``````

We can then instantiate an object from the `MonthsOfTheYear` class and iterate over each name:

``````MonthsOfTheYear months = new MonthsOfTheYear();

foreach(var month in months)
{
Console.WriteLine(month);
}``````

In essence, this allows us to treat the instance of `MonthsOfTheYear` as though it itself is a collection.

## Iterators and Generic Collections

We can also create iterators on custom generic collections.

A few posts ago, we discussed generics. In that post, we created a class `StackQueue<T>` that could both enqueue elements (put them at the "back of the line") and push elements (put them at the "front of the line").

The class we wrote, `StackQueue<T>`, looked like this:

``````public class StackQueue<T>
{
private List<T> elements = new List<T>();

public void Enqueue(T item)
{
Console.WriteLine("Queueing " + item.ToString());
elements.Insert(elements.Count, item);
}

public void Push(T item)
{
Console.WriteLine("Pushing " + item.ToString());
elements.Insert(0, item);
}

public T Pop()
{
var element = elements[0];
Console.WriteLine("Popping " + element.ToString());
elements.RemoveAt(0);
return element;
}
}``````

We will modify this class so that we can implement an iterator.

### Modifying StackQueue<T>

The very first thing we need to do is to have our `StackQueue<T>` class implement the `IEnumerable<T>` interface.

``public class StackQueue<T> : IEnumerable<T>``

Now we need a private variable `_top` that tracks the number of elements in the collection. We will use this in our iterator to know when to stop getting values out of it.

To implement this, we need our `Enqueue()`, `Push()`, and `Pop()` methods to increment or decrement `_top`. Our modified class now looks like this:

``````public class StackQueue<T> : IEnumerable<T>
{
private List<T> elements = new List<T>();
private int _top = 0; //NEW

public void Enqueue(T item)
{
Console.WriteLine("Queueing " + item.ToString());
elements.Insert(elements.Count, item);
_top++; //NEW
}

public void Push(T item)
{
Console.WriteLine("Pushing " + item.ToString());
elements.Insert(0, item);
_top++; //NEW
}

public T Pop()
{
var element = elements[0];
Console.WriteLine("Popping " + element.ToString());
elements.RemoveAt(0);
_top--; //NEW
return element;
}
}``````

Now we can implement our iterators, again using the `yield` keyword:

``````public class StackQueue<T> : IEnumerable<T>
{
//...Other properties and methods

public IEnumerator<T> GetEnumerator()
{
for(int index = 0; index < _top; index++)
{
yield return elements[index];
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}``````

Finally, we can instantiate, populate, and iterate over a `StackQueue<T>` instance like this:

``````var myStackQueue = new StackQueue<int>(); //T is now int

myStackQueue.Enqueue(1);
myStackQueue.Push(2);
myStackQueue.Push(3);
myStackQueue.Enqueue(4);

//At this point, the collection is { 3, 2, 1, 4 }

foreach(var item in myStackQueue)
{
Console.WriteLine(item);
}``````

## Glossary

• Iterators - Objects which "iterate" or move through collections, returning individual elements of said collection.

## New Keywords

• `yield` - Used to identify an iterator. Tells the compiler to return elements in a collection one-by-one to a calling method.

## Summary

The `yield` keyword allows us to return elements in a collection or array one-by-one to a calling method. We use `yield` to construct iterators, which iterate over collections. Iterators in a class behave much like properties of that class, and enable the class to be used in `foreach` loops with minimal code. Finally, iterators can also be used in custom generic collection classes like `StackQueue<T>`, we just need a variable to keep track of the elements in the collection.

Need some help learning about iterators? I'd love to assist! Ask questions in the comments below!

This is last post in the C# in Simple Terms mega series. Thanks for reading! As this post is scheduled to come out on December 21st, the blog will be on hiatus until after the first of the year. We'll see you all in 2021!

Happy Coding!