Interview Question: What is Yield Return? Let’s have fun with it



logo

Yield is a contextual keyword available only in certain contextual statements, mainly interacts with the foreach loop. It allows each iteration in a foreach loop to be generated only when needed. In this way it improves the performance of the query.

 

Today we will discuss about it with a small funny code. Let’s see how much we actually know about this keyword. If you can answer the output of the code, you already know about it.

 

To better understand the use of this keyword, have a look into the below code snippet where we have two methods – one returns a list of string and the other returns an IEnumerable of string using the yield keyword:

 

 
public class Person
{
    private readonly string[] m_names = { "Kunal", "Michael", "Iris", "Chris" };
 
    public List<string> GetNamesAsList()
    {
        var resultantNames = new List<string>();
        foreach (var name in m_names)
        {
            Console.WriteLine("Name from GetNamesAsList() : {0}", name);
            resultantNames.Add(name);
        }
        return resultantNames;
    }
 
    public IEnumerable<string> GetNamesAsEnumerable()
    {
        foreach (var name in m_names)
        {
            Console.WriteLine("Names from GetNamesAsEnumerable() : {0}", name);
            yield return name;
        }
    }
}

 

Now, if you can tell me what the below code does and prints output in the string, you understand how yield return works and if you can not, just read on the next part to learn more about the yield return statement.

 

 
class Program
{
    static void Main(string[] args)
    {
        var person = new Person();
        var listOfNames = person.GetNamesAsList();
        var enumerableOfNames  = person.GetNamesAsEnumerable();
 
        Console.ReadLine();
    }
}

 

In a C# program you can mark things as IEnumerable and that means the thing can be enumerated. The best way to work through something that can be enumerated is by using the foreach loop, as shown above. You have already worked with the foreach when you looped through items in a collection like List, Array, ObservableCollection etc. Similarly, in the above code we used foreach to iterate through the collection and return the results as a list of string first or as an enumerable.

 

In the default foreach loop, we have to create a local variable to store the names after iterating through the class and then return the local variable as a list of names to the caller. In the other case, whenever we are iterating through the collection, we can directly return each individual names directly from the loop instead of using any local variable to store them temporarily as you can see in the GetNamesAsEnumerable() method above.

 

The yield return also works as lazy return. That means, it will return the value when we need it. Let’s discuss on the above code. The output of the above code snippet is simple. It will just print the names from the GetNamesAsList() method and will skip the outputs of GetNamesAsEnumerable() method. The reason behind this is, unless we use the results of the method, the said method won’t ever be executed. This is actually quite a handy feature of yield return statements. Here is the output of the same:

 

Output of yield return

 

This is very important and you should know about this. When you use the yield keyword in a statement, you indicate that the method or operator in which it appears is an iterator. You use an iterator to perform a custom iteration over a collection. You can also use the yield return statement to return each element one at a time. You just use an iterator method by using a foreach statement or a LINQ query.

 

So, when will the GetNamesAsEnumerable() method be called? This will call once you start using the returned value. If you call the Count() method to the returned value i.e. enumerableOfNames.Count(), the whole iteration will be executed. For example, the below code will execute it completely and print the outputs:

 

 
var enumerableOfNames  = person.GetNamesAsEnumerable();
var count = enumerableOfNames.Count();

 

Output of yield return when Count() called

 

Let’s take another example of it where we will retrieve the second element from the enumerable. In this case, you will see that the whole bunch of method executed just up to the second element and then it returned the desired output.

 

 
var enumerableOfNames  = person.GetNamesAsEnumerable();
var secondElement = enumerableOfNames.ElementAt(1);

 

Output of yield return when second element is accessed

 

Each iteration of the foreach loop calls the iterator method. When a yield return statement is reached in the iterator method, expression is returned and the current location in code is retained. Execution of it restarts from that location the next time that the iterator function is called.

 

It’s not recommended to use yield in every loop where you are iterating through the collection. Use it properly when you need.

 

I hope that, this basic keyword discussion was helpful to you to refresh the knowledge. Like this, I will come up with few more basic questions in later post. Suggestions are most welcome.

 

Connect with me on Twitter, Facebook and Google+ to get the technical updates. Subscribe to my blog’s rss feed and email newsletter to get the post updates directly to your inbox. Have a great day.

1 comments


 
© 2008-2014 Kunal-Chowdhury.com | Designed by Kunal Chowdhury
Back to top