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:
Deve includere un modificatore iteratore.
Il tipo restituito deve essere IEnumerable, IEnumerable<T>, IEnumerator o IEnumerator<T>.
Non può avere parametri
ByRef
.
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.