
Yield interacts with the foreach-loop. It is a contextual keyword: yield is a keyword only in certain statements. It allows each iteration in a foreach-loop be generated only when needed. In this way it can improve performance.
This C# article shows ways you can use the yield keyword. Yield makes foreach more powerful.

You will want to use the yield keyword in methods that return the type IEnumerable (without any angle brackets), or the type IEnumerable<Type> with a type parameter in the angle brackets. You need to reference the System.Collections namespace for the first version, and the System.Collections.Generic namespace for the second.
IEnumerableProgram that uses foreach, yield return [C#]
using System;
using System.Collections.Generic;
public class Program
{
static void Main()
{
//
// Compute two with the exponent of 30.
//
foreach (int value in ComputePower(2, 30))
{
Console.Write(value);
Console.Write(" ");
}
Console.WriteLine();
}
public static IEnumerable<int> ComputePower(int number, int exponent)
{
int exponentNum = 0;
int numberResult = 1;
//
// Continue loop until the exponent count is reached.
//
while (exponentNum < exponent)
{
//
// Multiply the result.
//
numberResult *= number;
exponentNum++;
//
// Return the result with yield.
//
yield return numberResult;
}
}
}Output: 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728....

Using foreach loop. In the Main entry point defined in the Program class, you will see one foreach loop. In the part of the foreach loop following the "in" keyword, there is a method call to the ComputePower method, which you can see also in the Program class. Two integral values are passed as arguments to the ComputePower method.
Foreach Loop ExamplesComputePower method. This method receives two parameters, the first being the number integer, and the second being the number of numbers you want to receive. This method returns an IEnumerable<int> type, which is an interface describing a type that implements the internal methods required for using foreach loops. The ComputePower method uses the simple mathematical logic necessary for finding the exponential numbers. In the final statement, you can see the yield return contextual keyword, in the while iterative statement enclosing block.
Static keywords. The ComputePower method includes the public static modifiers in its signature. This is because it does not save state or access any members of the Program class. The yield return does internally store state, in a compiler-generated class.
Static Modifier
Yield return statement. Semantically, the yield return statement is equivalent to a return statement (which passes control flow to the calling method), followed by a 'goto' to the yield statement in the next iteration of the foreach loop. This behavior does not exist in the Common Language Runtime, but is rather implemented by a class generated by the C# compiler, which is then executed and JIT-compiled by the CLR.
Microsoft provides a method that is essentially equivalent on their yield C# Reference page. However, their implementation uses the non-generic IEnumerable type. This likely results in the integers being boxed before returning, because IEnumerable does not have knowledge of their type and instead acts on Object, which is a reference type.
MSDN reference
Here we look at how the method offered on MSDN compares to the method presented here on Dot Net Perls. The method developed here has explicit knowledge of the value type in the IEnumerable collection, which is more informative to the CLR at runtime. For this reason, the performance is much better. The actual result values of the methods is the same.
Loops benchmarked [C#]
// [MSDN]
foreach (int value in Power(2, 30))
{
}
// [DOT NET PERLS]
foreach (int value in ComputePower(2, 30))
{
}
Benchmark notes
1 million iterations of each loop tested.
Code samples have same computational result.
Simulation results for yield keyword usage
MSDN yield return/IEnumerable: 403 ms
Yield return/IEnumerable<int>: 224 ms [faster]
The C# code you have that uses yield is never actually executed by the CLR at runtime. Instead, the C# compiler transforms that code before the runtime ever occurs. The compiler-generated class, marked with the [CompilerGenerated] attribute, instead uses several integral types, both private and public. The result is an entire class that is similar to how your code would look if you manually implemented the interfaces.
Compiler-generated class [C#]
// Nested Types
[CompilerGenerated]
private sealed class <ComputePower>d__0 : IEnumerable<int>,
IEnumerable, IEnumerator<int> // ...
{
// Fields
private int <>1__state;
private int <>2__current;
public int <>3__exponent;
public int <>3__number;
private int <>l__initialThreadId;
public int <exponentNum>5__1;
public int <numberResult>5__2;
public int exponent;
public int number;
// Methods [omitted]
}Notes:
The actual class implements several more interfaces.
The actual class has several methods.
The punctuation characters allow the compiler to ensure
no naming conflicts will occur with your code.

Practically, there are several uses for the yield keyword. For example, you can use it as a filter for displaying random HTML code in your ASP.NET website. Internally, you can select random elements from an array and yield them, such as for advertisements.

We looked in depth at the yield return pattern in the C# language. We rewrote an example from the MSDN article, resulting in superior performance. The yield keyword is contextual, meaning it only has significance in some places and can still be used as an identifier elsewhere. We benchmarked the IEnumerable and IEnumerable generic interfaces, and finally looked into how the C# compiler generates the implementation.
Contextual Keyword Loop Constructs