22 out of 43 rated this helpful - Rate this topic

yield (C# Reference)

Updated: October 2008

The yield keyword signals to the compiler that the method in which it appears is an iterator block. The compiler generates a class to implement the behavior that is expressed in the iterator block. In the iterator block, the yield keyword is used together with the return keyword to provide a value to the enumerator object. This is the value that is returned, for example, in each loop of a foreach statement. The yield keyword is also used with break to signal the end of iteration. For more information about iterators, see Iterators (C# Programming Guide). The following example shows the two forms of the yield statement.

yield return <expression>;
yield break;

In a yield return statement, expression is evaluated and returned as a value to the enumerator object; expression has to be implicitly convertible to the yield type of the iterator.

In a yield break statement, control is unconditionally returned to the caller of the iterator, which is either the IEnumerator.MoveNext method (or its generic System.Collections.Generic.IEnumerable<T> counterpart) or the Dispose method of the enumerator object.

The yield statement can only appear inside an iterator block, which can be implemented as the body of a method, operator, or accessor. The body of such methods, operators, or accessors is controlled by the following restrictions:

  • Unsafe blocks are not allowed.

  • Parameters to the method, operator, or accessor cannot be ref or out.

  • A yield return statement cannot be located anywhere inside a try-catch block. It can be located in a try block if the try block is followed by a finally block.

  • A yield break statement may be located in a try block or a catch block but not a finally block.

A yield statement cannot appear in an anonymous method. For more information, see Anonymous Methods (C# Programming Guide).

When used with expression, a yield return statement cannot appear in a catch block or in a try block that has one or more catch clauses. For more information, see Exception Handling Statements (C# Reference).

In the following example, the yield statement is used inside an iterator block, which is the method Power(int number, int power). When the Power method is invoked, it returns an enumerable object that contains the powers of a number. Notice that the return type of the Power method is System.Collections.IEnumerable, an iterator interface type.

public class List
{
    //using System.Collections;
    public static IEnumerable Power(int number, int exponent)
    {
        int counter = 0;
        int result = 1;
        while (counter++ < exponent)
        {
            result = result * number;
            yield return result;
        }
    }

    static void Main()
    {
        // Display powers of 2 up to the exponent 8:
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }
}
/*
Output:
2 4 8 16 32 64 128 256 
*/


For more information, see the following sections in the C# Language Specification:

  • 19.3 Iterators

  • 22 Iterators

Date

History

Reason

October 2008

Added content.

Customer feedback.

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
VB.Net code that gives the same result as the Visual C# example.
Option Strict On
Option Explicit On
Option Infer Off

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim results As System.Collections.Generic.IEnumerable(Of Integer)
        results = Power(2, 8)

        Dim sb As New System.Text.StringBuilder
        For Each num As Integer In results
            sb.Append(num.ToString & " ")
        Next

        MessageBox.Show(sb.ToString)

    End Sub

    Public Function Power(ByVal number As Integer, ByVal exponent As Integer) As System.Collections.Generic.IEnumerable(Of Integer)

        Dim result As New List(Of Integer)

        For index As Integer = 1 To exponent
            result.Add(Convert.ToInt32(Math.Pow(number, index)))
        Next
        Return result.AsEnumerable

    End Function

End Class
Small Typo

The above article states:
"The yield statement can only appear inside an iterator block..."
Correct me if I'm wrong, but in actuality, the yield break; statement does appear outside an iterator block. Perhaps slightly better wording would be:
"The yield return statement can only appear inside an iterator block..."

Aaron

CS Team: Hi Aaron. Thanks for your comment. The C# 4.0 Language Spec (http://www.microsoft.com/downloads/details.aspx?FamilyID=dfbf523c-f98c-4804-afbd-459e846b268e&displaylang=en#filelist) says the following:

8.14 The yield statement

The yield statement is used in an iterator block (§8.2) to yield a value to the enumerator object (§10.14.4) or enumerable object (§10.14.5) of an iterator or to signal the end of the iteration.


yield-statement:
yieldreturn expression ;
yieldbreak;

Understanding yield break and yield return

Here is a blog that explains the usage of yield return and yield break in a simple example

http://iserialized.com/a-quick-start-guide-to-yield-return-and-yield-break/

Is there a difference between 'yield return' or 'return yield'
Does it have any difference between 'yield return' and 'return yield' ??
Examples of use of yield
Some examples about the use of 'yield' at: http://www.codeproject.com/KB/collections/Enumerators.aspx
Thanks David
David, Thanks, your note:

"The yield keyword uses what's known as lazy evaluation. What this means practically is that anything following a "yield return" will not be evaluated until it is requested from the enumerator."

should have been at the very beginning of this article. Because it explains everything in several words. Very clear and concise.
It is sooo true about many articles on MSDN, they start explaning from the middle.
A quick note on the yield keyword and lazy evaluation

The yield keyword uses what's known as lazy evaluation. What this means practically is that anything following a "yield return" will not be evaluated until it is requested from the enumerator. Take the following class for example:

public class ExampleClass{

    public List<string> OriginalStrings { get; set; }
    /// <summary>
/// Returns an enumerated list of reversed strings from OriginalStrings.
/// Causes side effects due to the call to "reverseString".
/// </summary>
/// <returns></returns>
public IEnumerable<string> GetReversedStrings()
{
for (int i = 0; i < OriginalStrings.Count; i++)
yield return reverseString(i);
}
    /// <summary>
/// Replaces the string at the specified index with a reversed version of itself.
/// </summary>
/// <param name="index">The index of the string in OriginalStrings to reverse. </param>
/// <returns>The newly reversed string</returns>
private string reverseString(int index)
{
string value = OriginalStrings[index];
char[] chars = value.ToCharArray();
Array.Reverse(chars);
string[] letters = new string[chars.Length];
for (int i = 0; i < chars.Length; i++)
letters[i] = chars[i].ToString();
string returnValue = string.Join("", letters);
OriginalStrings[index] = returnValue;
return OriginalStrings[index];
}
}


The GetReversedStrings method will yield the result of the call to reverseString, which will set the values of the OriginalStrings to their reversed equivalent, and return the newly reversed string.

Now, let's call this from the main method:

static void Main(string[] args)
{
ExampleClass exampleClass = new ExampleClass();
exampleClass.OriginalStrings = new List<string>() { "Bob", "David", "Jimenez", "Franz" };
exampleClass.GetReversedStrings();
foreach (string s in exampleClass.OriginalStrings)
Console.WriteLine(s);
Console.ReadLine();
}


Notice the output. The strings are not reversed. This is because the result of GetReversedStrings() is never iterated through.

Let's alter the code just a bit.

static void Main(string[] args)
{
ExampleClass exampleClass = new ExampleClass();
exampleClass.OriginalStrings = new List<string>() { "Bob", "David", "Jimenez", "Franz" };
foreach (string value in exampleClass.GetReversedStrings())
{
// do nothing of consequence. This is here simply to iterate through the values.
}
foreach (string s in exampleClass.OriginalStrings)
Console.WriteLine(s);
Console.ReadLine();
}


Now, you'll see a different result when you run this. All of the values will print out reversed. This is because the call to the statement returned in the yield return statement is evaluated only when iterated through.

This can certainly be an advantage, as it is in Linq, but use the keyword improperly, and you might get unexpected results.