Yield 语句 (Visual Basic)
将集合的下一个元素发送到 For Each...Next
语句。
语法
Yield expression
parameters
术语 | 定义 |
---|---|
expression |
必需。 一个表达式,可隐式转换为包含 Yield 语句的迭代器函数或 Get 访问器的类型。 |
注解
Yield
语句一次返回集合的一个元素。 Yield
语句包含在迭代器函数或 Get
访问器中,它们对集合执行自定义迭代。
可以通过使用 For Each...Next 语句或 LINQ 查询来使用迭代器函数。 For Each
循环的每次迭代都会调用迭代器函数。 迭代器函数运行到 Yield
语句时,会返回一个 expression
,并保留当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。
expression
语句中必须存在从 Yield
类型到迭代器返回类型的隐式转换。
可以使用 Exit Function
或 Return
语句来终止迭代。
“Yield”不是保留字,只有在 Iterator
函数或 Get
访问器中使用时才有特殊含义。
有关迭代器函数和 Get
访问器的详细信息,请参阅迭代器。
迭代器函数和 Get 访问器
迭代器函数或 Get
访问器的声明必须满足以下要求:
它必须包含迭代器修饰符。
返回类型必须为 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>。
它不能含有任何
ByRef
参数。
不能在事件、实例构造函数、静态构造函数或静态析构函数中使用迭代器函数。
迭代器函数可以是匿名函数。 有关更多信息,请参见 迭代器。
异常处理
Yield
语句可以位于 Try...Catch...Finally 语句的 Try
块内。 具有 Yield
语句的 Try
块可以具有 Catch
块,并且可以具有 Finally
块。
Yield
语句不能位于 Catch
块或 Finally
块内。
如果 For Each
主体(在迭代器函数之外)引发异常,则不会执行迭代器函数中的 Catch
块,但会执行迭代器函数中的 Finally
块。 迭代器函数内的 Catch
块仅捕获迭代器函数内发生的异常。
技术实现
以下代码从迭代器函数返回 IEnumerable (Of String)
,然后遍历 IEnumerable (Of String)
的元素。
Dim elements As IEnumerable(Of String) = MyIteratorFunction()
…
For Each element As String In elements
Next
调用 MyIteratorFunction
并不执行该函数的主体。 相反,该调用会将 IEnumerable(Of String)
返回到 elements
变量中。
在 For Each
循环迭代时,将为 MoveNext 调用 elements
方法。 此调用将执行 MyIteratorFunction
的主体,直至到达下一个 Yield
语句。 Yield
语句返回的表达式不仅决定了循环体使用的 element
变量值,还决定了元素的 Current 属性(它是 IEnumerable (Of String)
)。
在 For Each
循环的每个后续迭代中,迭代器主体的执行将从它暂停的位置继续,直至到达 Yield
语句后才会停止。 在到达迭代器函数的结尾或者 Return
或 Exit Function
语句时,For Each
循环便已完成。
示例 1
下例包含一个位于 For…Next 循环内的 Yield
语句。 Main
中的 For Each 语句体的每次迭代都会创建对 Power
迭代器函数的调用。 对迭代器函数的每个调用将继续到 Yield
语句的下一次执行(在 For…Next
循环的下一次迭代期间发生)。
迭代器方法的返回类型是 IEnumerable<T>(一种迭代器接口类型)。 当调用迭代器方法时,它将返回一个包含数字幂的可枚举对象。
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
示例 2
下面的示例演示一个作为迭代器的 Get
访问器。 属性声明包含 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
有关其他示例,请参阅迭代器。