yield (Riferimenti per C#)yield (C# Reference)

Quando si usa la parola chiave contestualeyield in un'istruzione, si indica che il metodo, l'operatore o la funzione di accesso get in cui appare è un iteratore.When you use the yield contextual keyword in a statement, you indicate that the method, operator, or get accessor in which it appears is an iterator. Utilizzando yield per definire un iteratore, si elimina la necessità di una classe esplicita aggiuntiva (la classe che contiene lo stato per un'enumerazione, vedere IEnumerator<T> per un esempio) quando si implementano i modelli IEnumerable e di IEnumerator per un tipo di raccolta personalizzato.Using yield to define an iterator removes the need for an explicit extra class (the class that holds the state for an enumeration, see IEnumerator<T> for an example) when you implement the IEnumerable and IEnumerator pattern for a custom collection type.

Nell'esempio seguente vengono illustrate le due forme dell'istruzione yield.The following example shows the two forms of the yield statement.

yield return <expression>;
yield break;

CommentiRemarks

Si utilizza un'istruzione yield return per restituire un elemento alla volta.You use a yield return statement to return each element one at a time.

La sequenza restituita da un metodo iteratore può essere usata con un'istruzione foreach o una query LINQ.The sequence returned from an iterator method can be consumed by using a foreach statement or LINQ query. Ogni iterazione del ciclo foreach chiama il metodo iteratore.Each iteration of the foreach loop calls the iterator method. Quando si raggiunge un'istruzione yield return nel metodo iteratore, viene restituito expression e viene mantenuta la posizione corrente nel codice.When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. L'esecuzione viene riavviata a partire da quella posizione la volta successiva che viene chiamata la funzione iteratore.Execution is restarted from that location the next time that the iterator function is called.

È possibile utilizzare un'istruzione yield break per terminare l'iterazione.You can use a yield break statement to end the iteration.

Per altre informazioni sugli iteratori, vedere Iteratori.For more information about iterators, see Iterators.

Metodi e funzioni di accesso get dell'iteratoreIterator methods and get accessors

La dichiarazione di un iteratore deve soddisfare i seguenti requisiti:The declaration of an iterator must meet the following requirements:

Il tipo yield di un iteratore che restituisce IEnumerable o IEnumerator è object.The yield type of an iterator that returns IEnumerable or IEnumerator is object. Se l'iteratore restituisce IEnumerable<T> o IEnumerator<T>, deve essere presente una conversione implicita dal tipo dell'espressione nell'istruzione yield return al parametro di tipo generico.If the iterator returns IEnumerable<T> or IEnumerator<T>, there must be an implicit conversion from the type of the expression in the yield return statement to the generic type parameter .

Non è possibile includere un'istruzione yield return o yield break in:You can't include a yield return or yield break statement in:

Gestione delle eccezioniException handling

Un'istruzione yield return non può essere inclusa in un blocco try-catch.A yield return statement can't be located in a try-catch block. Un'istruzione yield return può essere inclusa nel blocco try di un'istruzione try-finally.A yield return statement can be located in the try block of a try-finally statement.

Un'istruzione yield break può essere inclusa in un blocco try o in un blocco catch ma non in un blocco finally.A yield break statement can be located in a try block or a catch block but not a finally block.

Se il corpo di foreach (esterno al metodo iteratore) genera un'eccezione, viene eseguito un blocco finally nel metodo iteratore.If the foreach body (outside of the iterator method) throws an exception, a finally block in the iterator method is executed.

Implementazione tecnicaTechnical implementation

Il codice seguente restituisce IEnumerable<string> da un metodo iteratore e quindi scorre i relativi elementi.The following code returns an IEnumerable<string> from an iterator method and then iterates through its elements.

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

La chiamata a MyIteratorMethod non esegue il corpo del metodo.The call to MyIteratorMethod doesn't execute the body of the method. La chiamata restituisce invece IEnumerable<string> nella variabile elements.Instead the call returns an IEnumerable<string> into the elements variable.

In un'iterazione del ciclo foreach, il metodo MoveNext viene chiamato per elements.On an iteration of the foreach loop, the MoveNext method is called for elements. Questa chiamata esegue il corpo di MyIteratorMethod fino a quando non viene raggiunta l'istruzione yield return successiva.This call executes the body of MyIteratorMethod until the next yield return statement is reached. L'espressione restituita dall'istruzione yield return determina non solo il valore della variabile element per l'utilizzo da parte del corpo del ciclo, ma anche la proprietà Current di elements, che è IEnumerable<string>.The expression returned by the yield return statement determines not only the value of the element variable for consumption by the loop body but also the Current property of elements, which is an IEnumerable<string>.

In ogni iterazione successiva del ciclo foreach, l'esecuzione del corpo dell'iteratore continua da dove è stata interrotta, fermandosi ancora quando raggiunge un'istruzione yield return.On each subsequent iteration of the foreach loop, the execution of the iterator body continues from where it left off, again stopping when it reaches a yield return statement. Il ciclo foreach termina quando si raggiunge la fine del metodo iteratore o un'istruzione yield break.The foreach loop completes when the end of the iterator method or a yield break statement is reached.

EsempioExample

L'esempio seguente contiene un'istruzione yield return all'interno di un ciclo for.The following example has a yield return statement that's inside a for loop. Ogni iterazione del corpo dell'istruzione foreach nel metodo Main crea una chiamata alla funzione iteratore Power.Each iteration of the foreach statement body in the Main method creates a call to the Power iterator function. Ogni chiamata alla funzione iteratore procede fino alla prossima esecuzione dell'istruzione yield return, che si verifica durante l'iterazione successiva del ciclo for.Each call to the iterator function proceeds to the next execution of the yield return statement, which occurs during the next iteration of the for loop.

Il tipo restituito del metodo iteratore è IEnumerable, ovvero un tipo di interfaccia iteratore.The return type of the iterator method is IEnumerable, which is an iterator interface type. Quando il metodo iteratore viene chiamato, restituisce un oggetto enumerabile che contiene le potenze di un numero.When the iterator method is called, it returns an enumerable object that contains the powers of a number.

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
}

EsempioExample

Nell'esempio seguente viene illustrata una funzione di accesso get che è un iteratore.The following example demonstrates a get accessor that is an iterator. Nell'esempio, ogni istruzione yield return restituisce un'istanza di una classe definita dall'utente.In the example, each yield return statement returns an instance of a user-defined class.

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; }
    }
}

Specifiche del linguaggio C#C# language specification

Per ulteriori informazioni, vedere la specifica del linguaggio C#.For more information, see the C# Language Specification. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.The language specification is the definitive source for C# syntax and usage.

Vedere ancheSee also