Istruzione Yield (Visual Basic)

Invia l'elemento successivo di una raccolta a un'istruzione For Each...Next.

Sintassi

Yield expression  

Parametri

Termine Definizione
expression Obbligatorio. Espressione convertibile in modo implicito nel tipo della funzione iteratore o della funzione di accesso Get che contiene l'istruzione Yield.

Osservazioni:

L'istruzione Yield restituisce un elemento di una raccolta alla volta. L'istruzione Yield è inclusa in una funzione iteratore o in una funzione di accesso Get, che esegue iterazioni personalizzate su una raccolta.

Si utilizza una funzione iteratore usando un’Istruzione For Each...Next o query LINQ. Ogni iterazione del ciclo For Each chiama la funzione iteratore. Quando si raggiunge un'istruzione Yield nella funzione iteratore, viene restituito expression e viene mantenuta la posizione corrente nel codice. L'esecuzione viene riavviata a partire da quella posizione la volta successiva che viene chiamata la funzione iteratore.

Deve esistere una conversione implicita dal tipo di expression nell'istruzione Yield al tipo restituito dell'iteratore.

È possibile usare un'istruzione Exit Function o Return per terminare l'iterazione.

"Yield" non è una parola riservata e ha un significato speciale solo quando viene usato in una funzione Iterator o in una funzione di accesso Get.

Per altre informazioni sulle funzioni iteratori e sulle funzioni di accesso Get, vedere Iteratori.

Funzioni iteratore e funzioni di accesso Get

La dichiarazione di una funzione iteratore o di una funzione di accesso Get deve soddisfare i requisiti seguenti:

Una funzione iteratore non può verificarsi in un evento, un costruttore di istanza, un costruttore statico o un distruttore statico.

Una funzione iteratore può essere una funzione anonima. Per altre informazioni, vedere Iteratori.

Gestione delle eccezioni

Un'istruzione Yield può trovarsi all'interno di un blocco Try di un’Istruzione Try...Catch...Finally. Un blocco Try con un'istruzione Yield può avere blocchi Catch e può avere un blocco Finally.

Un'istruzione Yield non può trovarsi all'interno di un blocco Catch o di un blocco Finally.

Se il corpo For Each (all'esterno della funzione iteratore) genera un'eccezione, non viene eseguito un blocco Catch nella funzione iteratore, ma viene eseguito un blocco Finally nella funzione iteratore. Un blocco Catch all'interno di una funzione iteratore rileva solo le eccezioni che si verificano all'interno della funzione iteratore.

Implementazione tecnica

Il codice seguente restituisce un oggetto IEnumerable (Of String) da una funzione iteratore e quindi scorre gli elementi dell'oggetto IEnumerable (Of String).

Dim elements As IEnumerable(Of String) = MyIteratorFunction()  
    …  
For Each element As String In elements  
Next  

La chiamata a MyIteratorFunction non esegue il corpo della funzione. La chiamata restituisce invece IEnumerable(Of String) nella variabile elements.

In un'iterazione del ciclo For Each, il metodo MoveNext viene chiamato per elements. Questa chiamata esegue il corpo di MyIteratorFunction fino a quando non viene raggiunta l'istruzione Yield successiva. L'istruzione Yield restituisce un'espressione che determina non solo il valore della variabile element per l'utilizzo dal corpo del ciclo, ma anche la proprietà Current degli elementi, che è IEnumerable (Of String).

In ogni iterazione successiva del ciclo For Each, l'esecuzione del corpo dell'iteratore continua da dove è stata interrotta, fermandosi ancora quando raggiunge un'istruzione Yield. Il ciclo For Each viene completato quando viene raggiunta la fine della funzione iteratore o un'istruzione Return o Exit Function.

Esempio 1

L'esempio seguente contiene un'istruzione Yield all'interno di un ciclo For…Next. Ogni iterazione del corpo dell'istruzione For Each in Main crea una chiamata alla funzione iteratore Power. Ogni chiamata alla funzione iteratore procede fino alla prossima esecuzione dell'istruzione Yield, che si verifica durante l'iterazione successiva del ciclo For…Next.

Il tipo restituito del metodo iteratore è IEnumerable<T>, un tipo di interfaccia iteratore. Quando il metodo iteratore viene chiamato, restituisce un oggetto enumerabile che contiene le potenze di un numero.

Sub Main()
    For Each number In Power(2, 8)
        Console.Write(number & " ")
    Next
    ' Output: 2 4 8 16 32 64 128 256
    Console.ReadKey()
End Sub

Private Iterator Function Power(
ByVal base As Integer, ByVal highExponent As Integer) _
As System.Collections.Generic.IEnumerable(Of Integer)

    Dim result = 1

    For counter = 1 To highExponent
        result = result * base
        Yield result
    Next
End Function

Esempio 2

Nell'esempio seguente viene illustrata una funzione di accesso Get che è un iteratore. La dichiarazione di proprietà include un modificatore Iterator.

Sub Main()
    Dim theGalaxies As New Galaxies
    For Each theGalaxy In theGalaxies.NextGalaxy
        With theGalaxy
            Console.WriteLine(.Name & "  " & .MegaLightYears)
        End With
    Next
    Console.ReadKey()
End Sub

Public Class Galaxies
    Public ReadOnly Iterator Property NextGalaxy _
    As System.Collections.Generic.IEnumerable(Of Galaxy)
        Get
            Yield New Galaxy With {.Name = "Tadpole", .MegaLightYears = 400}
            Yield New Galaxy With {.Name = "Pinwheel", .MegaLightYears = 25}
            Yield New Galaxy With {.Name = "Milky Way", .MegaLightYears = 0}
            Yield New Galaxy With {.Name = "Andromeda", .MegaLightYears = 3}
        End Get
    End Property
End Class

Public Class Galaxy
    Public Property Name As String
    Public Property MegaLightYears As Integer
End Class

Per altri esempi, vedere Iteratori.

Vedi anche