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 FunctionReturn 语句来终止迭代。

“Yield”不是保留字,只有在 Iterator 函数或 Get 访问器中使用时才有特殊含义。

有关迭代器函数和 Get 访问器的详细信息,请参阅迭代器

迭代器函数和 Get 访问器

迭代器函数或 Get 访问器的声明必须满足以下要求:

不能在事件、实例构造函数、静态构造函数或静态析构函数中使用迭代器函数。

迭代器函数可以是匿名函数。 有关更多信息,请参见 迭代器

异常处理

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 语句后才会停止。 在到达迭代器函数的结尾或者 ReturnExit 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

有关其他示例,请参阅迭代器

请参阅