Using 'yield' for Deferred Execution

C# provides the yield keyword, which can be used to create iterator methods. These methods produce a sequence of values lazily, allowing for deferred execution. This can be particularly useful when working with large data sets or when you want to avoid loading everything into memory at once.

In the below example, GetNumbers() is an iterator method that yields a sequence of squared numbers. The key here is that the values are generated one by one as you iterate through the sequence, and they're not all calculated and stored in memory at once.

The yield keyword allows you to maintain the state of the iterator between iterations and offers a clean way to implement custom iterators without explicitly managing state variables.

This approach is beneficial for scenarios where loading or calculating all the values at once is memory-intensive or time-consuming. It's a powerful technique to create more memory-efficient and responsive code.

Remember that while the yield keyword can be a great tool, it's important to understand how it works, as it can have implications on resource management and potential side effects when used in certain ways.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        foreach (var number in GetNumbers())
        {
            Console.WriteLine(number);
        }
    }

    public static IEnumerable<int> GetNumbers()
    {
        for (int i = 0; i < 10; i++)
        {
            yield return i * i;
        }
    }
}