What is the yield keyword used for in C#?

2 min read 07-09-2024
What is the yield keyword used for in C#?


Understanding the "yield" Keyword in C# for Creating Iterators

The "yield" keyword in C# is a powerful tool for creating iterators, which are functions that generate a sequence of values. It's often used to simplify code and improve performance, especially when dealing with large datasets or when you want to process data on demand.

Let's explore the example provided and understand how the "yield" keyword works:

IEnumerable<object> FilteredList()
{
    foreach(object item in FullList)
    {
        if(IsItemInPartialList(item))
            yield return item;
    }
}

In this code snippet, FilteredList() is a method that aims to filter a list (FullList) based on a condition (IsItemInPartialList()). Instead of creating a new list and returning it, the method uses yield return to generate the filtered elements one by one as they are needed.

Here's how the "yield" keyword works:

  1. Iteration: When the FilteredList() method is called, it doesn't actually execute the foreach loop immediately. Instead, it acts as a generator, returning an IEnumerable<object>.
  2. First Request: When the code needs to access the first element of the sequence, the foreach loop inside FilteredList() starts executing until it reaches the first item that passes the IsItemInPartialList() condition.
  3. "yield return": At this point, yield return item is executed, returning the first matching item and pausing the execution of the FilteredList() method.
  4. Next Request: The next time the code needs an element from the sequence, the execution of FilteredList() resumes from where it left off, and the loop continues until it finds the next matching item.
  5. Repeat: This process continues for every element in the sequence. When the loop finishes, the FilteredList() method returns.

Benefits of using "yield":

  • Lazy Evaluation: yield enables lazy evaluation, meaning that elements are generated only when they are needed. This is beneficial when working with large datasets because it avoids the overhead of creating and storing the entire result set in memory.
  • Memory Efficiency: By generating elements on demand, yield helps conserve memory, especially when dealing with large collections.
  • Flexibility: You can easily modify the filtering logic within the FilteredList() method without affecting the code that consumes it.

Example:

Let's say we have a list of numbers:

List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

We want to filter the numbers to only include even numbers. Using yield, we can create an iterator method:

IEnumerable<int> EvenNumbers()
{
    foreach (int number in numbers)
    {
        if (number % 2 == 0)
        {
            yield return number;
        }
    }
}

Now, we can iterate through the even numbers in the numbers list:

foreach (int evenNumber in EvenNumbers())
{
    Console.WriteLine(evenNumber); // Output: 2, 4, 6, 8, 10
}

In conclusion, the "yield" keyword is a powerful feature in C# that allows you to create iterators, generating sequences of values on demand. By utilizing lazy evaluation and memory efficiency, it can simplify your code and improve performance when working with large datasets.