Yield 语句 (Visual Basic)

将集合的下一个 For Each...Next 元素发送到语句。

语法

Yield expression  

参数

术语 定义
expression 必填。 可隐式转换为包含Yield语句的迭代器函数或Get访问器类型的表达式。

注解

Yield 语句一次返回集合的一个元素。 该 Yield 语句包含在迭代器函数或 Get 访问器中,该函数对集合执行自定义迭代。

通过使用 For Each... 使用迭代器函数 ...Next 语句 或 LINQ 查询。 循环的每个 For Each 迭代都会调用迭代器函数。 Yield在迭代器函数中到达语句时,expression将返回,并保留代码中的当前位置。 下次调用迭代器函数时,将从该位置重新启动执行。

隐式转换必须存在于语句中的Yield类型expression到迭代器的返回类型。

可以使用 Exit FunctionReturn 语句结束迭代。

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

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

迭代器函数和 Get 访问器

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

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

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

异常处理

语句Yield可以位于 Try 的块内Try...抓住。。。Finally 语句。 具有Try语句的Yield块可以拥有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 不会执行函数的主体。 相反,调用将返回变量中的elementsIEnumerable(Of String)

在循环迭代 For Each 时,将 MoveNext 调用 elements该方法。 此调用将执行下一个语句的正文 MyIteratorFunction ,直到达到下一 Yield 个语句。 该 Yield 语句返回一个表达式,该表达式不仅确定变量的值 element 供循环正文使用,而且还 Current 确定元素的属性,即一个 IEnumerable (Of String)

在循环的每个后续迭代 For Each 中,迭代器正文的执行将继续从其离开的位置继续,在到达 Yield 语句时再次停止。 循环For Each在到达迭代器函数或ReturnExit Function语句的末尾时完成。

示例 1

以下示例有一个Yield位于 For... 中的语句下一个循环。 For Each 语句正文Main的每个迭代都会创建对迭代器函数的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

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

另请参阅