Introduction
In C#, the yield keyword is used in combination with an iterator to create custom iterator blocks. An iterator is a special kind of method that allows you to iterate over a collection of items, generating values on-the-fly, and returning them one by one. The yield keyword simplifies the implementation of custom iterators, making the code more readable and efficient.
The entire source code can be downloaded from GitHub
The general syntax of an iterator method using the yield keyword is as follows.
public IEnumerable<ElementType> CustomIterator()
{
// Initialization (optional)
foreach (var item in collection)
{
// Pre-yield logic (optional)
yield return value;
// Post-yield logic (optional)
}
// Cleanup (optional)
}
Let's break down the parts of the iterator method.
- The return type should be IEnumerable<T> or IEnumerator<T>, where T is the type of elements that will be yielded.
- The method body consists of a series of yield return statements that generate and return values one by one.
- The yield return statement produces the next element of the iteration sequence.
- The method can also include a yield break statement, which immediately ends the iterator without any more yields.
Example
Before delving into the concept of "yield" and its applications, let's first explore the workings of regular iteration.
namespace YieldTutorial
{
internal class ProcessLoop
{
public static void DisplayRecords()
{
//all records will be loaded into studList, then process each record in this collection.
var studList= GetStudents(1_000_000);
foreach (var record in studList)
{
if (record.Id < 1000)
Console.WriteLine($"Id :{record.Id}, FirstName : {record.FirstName}, LastName : {record.LastName} ");
else
break;
}
}
private static IEnumerable<Student> GetStudents(int upperLimit)
{
var studList =new List<Student>();
for(int i = 0; i < upperLimit; i++)
{
studList.Add(new Student
{
Id = i,
FirstName = $"FName{i}",
LastName = $"LName{i}"
});
}
return studList;
}
}
}
The DisplayRecords method does the following.
- Calls the GetStudents method to fetch a collection of student records (maximum of 1 million records).
- Iterates each record in the studList using a foreach loop.
- Within the loop, it checks if the Id of the current student is less than 1000.
- If the condition is true, it prints the student's Id, FirstName, and LastName.
- If the condition is false (meaning the Id is 1000 or greater), it breaks out of the loop.
The GetStudents method is a private method responsible for generating student records up to a specified upper limit. Based on the loop index, it creates a list of students and assigns each student a unique Id, FirstName, and LastName.
Overall, the DisplayRecords method fetches student records and prints the details of students whose Id is less than 1000.
It's important to note that this implementation of iteration eagerly generates all the student records into the studList before starting the iteration. In scenarios where there are a significant number of records or infinite sequences, this approach may lead to unnecessary memory consumption. The yield keyword could be used to lazily generate the records, improving memory efficiency and performance in certain cases.
Now, let us look at the example below, which has used the "yield" keyword.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YieldTutorial
{
internal class ProcessLoopWithYield
{
public static void DisplayRecordsWithYield()
{
//all records will be loaded into studList, then process each record in this collection.
var studList = GetStudentByYield(1_000_000);
foreach (var record in studList)
{
if (record.Id < 1000)
Console.WriteLine($"Id :{record.Id}, FirstName : {record.FirstName}, LastName : {record.LastName} ");
else
break;
}
}
private static IEnumerable<Student> GetStudentByYield(int upperLimit)
{
for (int i = 0; i < upperLimit; i++)
{
yield return new Student
{
Id = i,
FirstName = $"FName{i}",
LastName = $"LName{i}"
};
}
}
}
}


Join the conversation! Your thoughts help the community grow.