Sdílet prostřednictvím


yield (Referenční dokumentace jazyka C#)

Pokud použijete klíčové slovo yield v konkrétním příkazu, dáváte tak najevo, že metoda, operátor nebo přístupový objekt get, který je součástí příkazu, je iterátor.Používání klíčového slova yield minimalizuje nutnost nasazení explicitní extra třídy (třídy, která definuje stav výčtu, viz například IEnumerator), pokud implementujete vzor IEnumerable a IEnumerator pro vlastní typ kolekce.

Následující příklad znázorňuje dvě formy příkazu yield.

yield return <expression>;
yield break;

Poznámky

Pomocí příkazu yield return lze vrátit vždy jeden prvek.

Metodu iterátoru spotřebujete pomocí příkazu foreach nebo dotazu LINQ.Každá iterace smyčky foreach zavolá metodu iterátoru.Jakmile je v metodě iterátoru dosažen příkaz yield return, je vrácen výraz expression a v kódu je ponecháno aktuální umístění.Provádění je restartováno ze zmíněného umístění pokaždé, když je zavolána funkce iterátoru.

K ukončení iterace můžete použít příkaz yield break.

Další informace o iterátorech naleznete v tématu Iterátory (C# and Visual Basic).

Iterátory a přístupové objekty get

Deklarace iterátoru musí splňovat následující požadavky:

Typ yield iterátoru, který vrátí třídu IEnumerable nebo IEnumerator, je objekt object. Pokud iterátor vrátí třídu IEnumerable nebo IEnumerator, musí být proveden implicitní převod z typu výrazu v příkazu yield return na parametr obecného typu.

Metody, které mají následující charakteristiky, nemohou obsahovat příkaz yield return nebo yield break:

Zpracování výjimek

Příkaz yield return nelze umístit do bloku try-catch.Příkaz yield return lze umístit do bloku try příkazu try-finally.

Příkaz yield break lze umístit do bloku try nebo do bloku catch, nikoli však do bloku finally.

Pokud tělo foreach (mimo metodu iterátoru) vyvolá výjimku, je proveden blok finally v metodě iterátoru.

Technická implementace

Následující kód vrátí z metody iterátoru třídu IEnumerable<string> a poté iteruje skrz příslušné prvky.

IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
   …
}

Volání MyIteratorMethod neprovede tělo metody.Namísto toho volání vrátí třídu IEnumerable<string> do proměnné elements.

Při iteraci smyčky foreach je pro prvek elements zavolána metoda MoveNext.Toto volání provádí tělo metody MyIteratorMethod, dokud není dosažen další příkaz yield return.Výraz vrácený příkazem yield return stanovuje nejen hodnotu proměnné element určené ke spotřebě tělem smyčky, ale také vlastnost Current prvků, která je třídou IEnumerable<string>.

Při každé další iteraci smyčky foreach pokračuje tělo iterátoru od posledního místa a zastaví se opět tehdy, až dosáhne příkazu yield return.Smyčka foreach je dokončena, jakmile je dosaženo konce metody iterátoru nebo příkazu yield break.

Příklad

Následující příklad obsahuje příkaz yield return, který se nachází uvnitř smyčky for.Každá iterace těla příkazu foreach v procesu Process vytváří volání funkce iterátoru Power.Každé volání funkce iterátoru pokračuje do dalšího provedení příkazu yield return, které nastane při další iteraci smyčky for.

Návratový typ metody iterátoru je IEnumerable, což je typ rozhraní iterátoru.Při volání metody iterátoru je vrácen vyčíslitelný objekt, který obsahuje mocniny čísla.

public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8: 
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }

    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;

        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }

    // Output: 2 4 8 16 32 64 128 256
}

Následující příklad znázorňuje přístupový objekt get, který je iterátorem.V tomto příkladu vrací každý příkaz yield return instanci třídy definované uživatelem.

public static class GalaxyClass
{
    public static void ShowGalaxies()
    {
        var theGalaxies = new Galaxies();
        foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
        {
            Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
        }
    }

    public class Galaxies
    {

        public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }
        }

    }

    public class Galaxy
    {
        public String Name { get; set; }
        public int MegaLightYears { get; set; }
    }
}

Specifikace jazyka C#

Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.

Viz také

Referenční dokumentace

foreach, in (Referenční dokumentace jazyka C#)

Koncepty

Průvodce programováním v C#

Další zdroje

Referenční dokumentace jazyka C#

Iterátory (C# and Visual Basic)