Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Iterators in C#

0.00/5 (No votes)
25 Mar 2014 1  
The tip just gives a brief on what iterators are in C#

Introduction

This tip explains what actually is an iterator and in how many ways we can implement iterators.

Background

Iterators are available since the early releases of C#. But the use of the Iterators is less known to developers and is also less used. On a daily basis, this concept is less used and also rarely implemented. Yield behind the scenes produces a state machine for computing the values. This can be seen if you can see the compiled code. Also a point to note is that Yield keyword which is used in the Iterators offer deferred execution in C# similar to LINQ in C#.

Definition

Quote:
An iterator is a method, get accessor, or operator that performs a custom iteration over an array or collection class by using the yield keyword -- from M S D N

Using Iterator In a Method

Let's have a simple example of returning the products by calling the GetProducts() method.

public class YieldInMethod
{
    public static IEnumerable<string> GetProducts()
    {
        foreach (var item in Enumerable.Range(1,5))
        {
            yield return "Product" + item.ToString();
        }
    }
    public static void Main(string[] args)
    {
        foreach(var item in GetProducts())
        {
              Console.WriteLine(item);
        }
    }
}

NOTE: An important point to note while using Iterators is that the return type of the Iterator must be IEnumerable, IEnumerator, IEnumerable<t>, or IEnumerator<t>.

What Happened?

When yield return statement is first executed in the Iterator, it immediately returns the product name from the Iterator and writes "Product1" to the console. When the Iterator method is called once again, it returns "Product2" from the Iterator method and is written to the console and so forth. So, for the second execution, instead of returning "Product1" from the method, it returned "Product2" because it knows where it left and resumes the operation, hence returning the second product.

Using Iterator in a GET Accessor

Let's modify the above code a little bit to return the products and Ids from the get accessor.

public class YieldInGet
{
    public IEnumerable<Products> GetProducts 
    {
        get
        {
            yield return new Products() { Id = 1, Name = "Product1" };
            yield return new Products() { Id = 2, Name = "Product2" };
            yield return new Products() { Id = 3, Name = "Product3" };
        }
        
    }
    public static void Main(string[] args)
    {
        YieldInGet yg = new YieldInGet();
        foreach (Products p in yg.GetProducts)
        {
            Console.WriteLine(String.Format("Product Id: {0}, Name: {1}", p.Id, p.Name));
        }
    }
}
public class Products
{
    public int Id { get; set; }
    public string Name { get; set; }
}

When GetProducts property is accessed for, then the property returns the list of products with ids and names of the products each at a time.

Using Iterator in an Operator

The implementation of yield in Operator is pretty much the same as the implementation of yield in a method except that this implementation uses operators to return things. Let's consider a simple Fibonacci series example to demonstrate using iterator in operator.

public class YieldInOperator
{
    public static void Main(string[] args)
    {
        foreach (var item in Fibonacci(5))
        {
            Console.WriteLine(item);       
        }
    }

    public static IEnumerable<int> Fibonacci(int number)
    {
        int a = 0, b = 1;

        yield return a;
        yield return b;

        for (int count = 0; count <= number; count++)
        {
            int temp = a;
            a = b;
            b = temp + b;
            yield return b;
        }
    }
}

When Fibonnacci(5) is called, the value of "a" is returned from the Fibonacci method, followed by b, followed by the numbers sequence of Fibonacci series.

Summary

Whenever a list of huge values are to be returned, you can use yield instead of returning a list.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here