yield (C# Reference) Home
This page is specific to:.NET Framework Version:2.03.03.54.0
C# Language Reference
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;
Remarks

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 [T:System.Collections.Generic.IEnumerable'1] 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).

Example

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 
*/


C# Language Specification

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

  • 19.3 Iterators

  • 22 Iterators

See Also

Concepts

Reference

Other Resources

Change History

Date

History

Reason

October 2008

Added content.

Customer feedback.

Community Content

A quick note on the yield keyword and lazy evaluation
Added by:David M Morton

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.

Small Typo
Added by:Thomas Lee

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

Thanks David
Added by:jhhhj
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.
Examples of use of yield
Added by:jaime_olivares
Some examples about the use of 'yield' at: http://www.codeproject.com/KB/collections/Enumerators.aspx
Is there a difference between 'yield return' or 'return yield'
Added by:Alex_82
Does it have any difference between 'yield return' and 'return yield' ??
© 2009 Microsoft Corporation. All rights reserved.   Terms of Use | Trademarks | Privacy Statement
Page view tracker
Rate the Lightweight library
x
Lightweight builds on ScriptFree (loband) by adding features you've requested: a SearchBox and default code language selection.
Do you like the SearchBox?
Do you like the tabbed code blocks?
How useful is this topic?
Tell us more.
Thanks
x
You're helping to improve MSDN Online.
Feedback
Switch View
Classic
Lightweight Beta
ScriptFree
Switch View