Yield (Instrucción) (Visual Basic)
Envía el siguiente elemento de una colección a una instrucción For Each...Next
.
Sintaxis
Yield expression
Parámetros
Término | Definición |
---|---|
expression |
Obligatorio. Una expresión que se puede convertir implícitamente en el tipo de la función de iterador o el descriptor de acceso Get que contiene la instrucción Yield . |
Comentarios
La instrucción Yield
devuelve los elementos de una colección de uno en uno. La instrucción Yield
se incluye en una función de iterador o en un descriptor de acceso Get
, que realiza iteraciones personalizadas en una colección.
Puede consumir una función de iterador mediante una instrucción For Each...Next o una consulta LINQ. Cada iteración del bucle For Each
llama a la función de iterador. Cuando se accede a una instrucción Yield
en la función de iterador, se devuelve expression
y se conserva la ubicación actual que hay en el código. La ejecución se reinicia desde esa ubicación la próxima vez que se llama a la función del iterador.
Debe existir una conversión implícita del tipo de expression
en la instrucción Yield
al tipo de valor devuelto del iterador.
Para finalizar la iteración se puede usar una instrucción Exit Function
o Return
.
"Yield" no es una palabra reservada y tiene un significado especial solo cuando se usa en una función Iterator
o un descriptor de acceso Get
.
Para más información sobre las funciones de iterador y los descriptores de acceso Get
, consulte Iteradores.
Funciones de iterador y descriptores de acceso Get
La declaración de una función de o un descriptor de acceso Get
debe cumplir los siguientes requisitos:
Debe incluir un modificador Iterator.
El tipo de valor devuelto debe ser IEnumerable, IEnumerable<T>, IEnumerator o IEnumerator<T>.
No puede tener parámetros
ByRef
.
Una función de iterador no puede aparecer en un evento, un constructor de instancia, un constructor estático o un destructor estático.
Una función de iterador puede ser una función anónima. Para más información, consulta Iteradores.
Control de excepciones.
Una instrucción Yield
puede estar dentro de un bloque Try
de una instrucción Try...Catch...Finally. Un bloque Try
que tiene una instrucción Yield
puede tener bloques Catch
y puede tener un bloque Finally
.
Una instrucción Yield
no puede estar dentro de un bloque Catch
o un bloque Finally
.
Si el cuerpo de For Each
(fuera de la función de iterador) produce una excepción, no se ejecuta un bloque Catch
en la función de iterador, pero se ejecuta un bloque Finally
en la función de iterador. Un bloque Catch
dentro de una función de iterador detecta solo las excepciones que se producen dentro de la función de iterador.
Implementación técnica
El siguiente código devuelve un valor IEnumerable (Of String)
desde una función de iterador y, después, recorre los elementos de IEnumerable (Of String)
.
Dim elements As IEnumerable(Of String) = MyIteratorFunction()
…
For Each element As String In elements
Next
La llamada a MyIteratorFunction
no ejecuta el cuerpo de la función. En su lugar, la llamada devuelve un valor IEnumerable(Of String)
en la variable elements
.
En una iteración del bucle For Each
, se llama al método MoveNext para elements
. Esta llamada ejecuta el cuerpo de MyIteratorFunction
hasta que se alcanza la siguiente instrucción Yield
. La instrucción Yield
devuelve una expresión que determina no solo el valor de la variable element
para que la utilice el cuerpo del bucle, sino también la propiedad Current de elements, que es un valor IEnumerable (Of String)
.
En cada iteración subsiguiente del bucle For Each
, la ejecución del cuerpo del iterador continúa desde donde se dejó, deteniéndose de nuevo al alcanzar una instrucción Yield
. El bucle For Each
se completa cuando se alcanza el fin de la función del iterador o una instrucción Return
o Exit Function
.
Ejemplo 1
El siguiente ejemplo tiene una instrucción Yield
que se encuentra dentro de un bucle For…Next. Cada iteración del cuerpo de instrucción For Each en Main
crea una llamada a la función de iterador Power
. Cada llamada a la función de iterador prosigue con la siguiente ejecución de la instrucción Yield
, que se produce durante la siguiente iteración del bucle For…Next
.
El tipo de valor devuelto del método iterador es IEnumerable<T>, que es un tipo de interfaz de iterador. Cuando se llama al método iterador, este devuelve un objeto enumerable que contiene las potencias de un número.
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
Ejemplo 2
En el ejemplo siguiente se muestra un descriptor de acceso Get
que es un iterador. La declaración de la propiedad incluye un modificador 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
Para ver más ejemplos, consulte Iteradores.