What is the use of
“Yield” keyword?
“Yield helps you to provide
custom stateful iteration over .NET collections.”
There are two scenarios where “yield” keyword is useful:-
- Customized iteration through a collection without creating a temporary collection.
- Stateful iteration.
Scenario 1:-
Customized iteration through a collection
Let’s try to understand what customized iteration means with
an example. Consider the below code.
Let say we have a simple list called as “MyList” which has
collection of 5 continuous numeric values 1,2,3,4 and 5. This list is browsed/iterated
from console application from within static
void main method.
For now let’s visualize the “main()” method as a caller. So
the caller i.e. “main()” method calls
the list and displays the items inside it.
Simple…till now ;-).
static List<int> MyList = new List<int>();
static void FillValues()
{
MyList.Add(1);
MyList.Add(2);
MyList.Add(3);
MyList.Add(4);
MyList.Add(5);
}
static void Main(string[] args) // Caller
{
FillValues(); // Fills the list
with 5 values
foreach (int i in MyList) // Browses through the list
{
Console.WriteLine(i);
}
Console.ReadLine();
}
Now let me complicate this situation let’s say the caller
only wants values greater than “3” from the collection. So the obvious thing as a c# developer we will
do is create a function as shown below. This function will have temporary
collection. In this temporary collection we will first add values which are
greater than “3” and return the same to the caller. The caller can then iterate
through this collection.
static IEnumerable<int> FilterWithoutYield()
{
List<int> temp = new List<int>();
foreach (int i in MyList)
{
if (i > 3)
{
temp.Add(i);
}
}
return temp;
}
Now the above approach is fine but it would be great if we would
get rid of the collection, so that our code becomes simple. This where “yield”
keyword comes to help. Below is a simple code how we have used yield.
“Yield” keyword will return back the control to the caller,
the caller will do his work and re-enter the function from where he had left
and continue iteration from that point onwards. In other words “yield” keyword
moves control of the program to and fro between caller and the collection.
static IEnumerable<int> FilterWithYield()
{
foreach (int i in MyList)
{
if (i > 3) yield return i;
}
}
So for the above code following are details steps how the
control will flow between caller and collection. You can also see the pictorial
representation in the next diagram shown below.
- Step 1:- Caller calls the function to iterate for number’s greater than 3.
- Step 2:- Inside the function the for loop runs from 1 to 2 , from 2 to 3 until it encounters value greater than “3” i.e. “4”. As soon as the condition of value greater than 3 is met the “yield” keyword sends this data back to the caller.
- Step 3:- Caller displays the value on the console and re-enters the function for more data. This time when it reenters, it does not start from first. It remembers the state and starts from “5”. The iteration continues further as usual.
Scenario 2:- Stateful
iteration
Now let us add more complications to the above scenario.
Let’s say we want to display running total of the above collection. What do I mean?.
In other words we will browse from 1 to 5 and as we browse
we would keep adding the total in variable. So we start with “1” the running total is “1”, we move to value “2”
the running total is previous value “1” plus current value “2” i.e. “3” and so
on.
Below is the pictorial representation of the running total
looks like.
In other words we would like to iterate through the
collection and as we iterate would like to maintain running total state and
return the value to the caller ( i.e. console application). So the function now
becomes something as shown below. The “runningtotal” variable will have the old
value every time the caller re-enters the function.
static IEnumerable<int> RunningTotal()
{
int runningtotal=0;
int index=0;
foreach(int i in MyList)
{
index = index + 1;
if(index==1)
{
runningtotal = i;
}
else
{
runningtotal = i +
runningtotal;
}
yield return (runningtotal);
}
}
Below goes the caller code and output.
foreach (int i in RunningTotal())
{
Console.WriteLine(i);
}
Console.ReadLine();
You can also visit my site for c# interview questions with answers .In addition to my site recently I
have also created a blog c#interview questions and answers.
2 comments:
Nice post very helpful
dbakings
Nice post good one here i am attaching a link for c# interview questions
C# interview questions
Post a Comment