将集合的下一个 For Each...Next 元素发送到语句。
语法
Yield expression
参数
| 术语 | 定义 |
|---|---|
expression |
必填。 可隐式转换为包含Yield语句的迭代器函数或Get访问器类型的表达式。 |
注解
该 Yield 语句一次返回集合的一个元素。 该 Yield 语句包含在迭代器函数或 Get 访问器中,该函数对集合执行自定义迭代。
通过使用 For Each... 使用迭代器函数 ...Next 语句 或 LINQ 查询。 循环的每个 For Each 迭代都会调用迭代器函数。
Yield在迭代器函数中到达语句时,expression将返回,并保留代码中的当前位置。 下次调用迭代器函数时,将从该位置重新启动执行。
隐式转换必须存在于语句中的Yield类型expression到迭代器的返回类型。
可以使用 Exit Function 或 Return 语句结束迭代。
“Yield”不是保留字,仅在函数或Get访问器中使用Iterator时具有特殊含义。
有关迭代器函数和 Get 访问器的详细信息,请参阅 迭代器。
迭代器函数和 Get 访问器
迭代器函数或 Get 访问器的声明必须满足以下要求:
它必须包含 迭代器 修饰符。
返回类型必须为IEnumerable、IEnumerable<T>或IEnumeratorIEnumerator<T>。
它不能有任何
ByRef参数。
迭代器函数不能发生在事件、实例构造函数、静态构造函数或静态析构函数中。
迭代器函数可以是匿名函数。 有关更多信息,请参见 迭代器。
异常处理
语句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 不会执行函数的主体。 相反,调用将返回变量中的elements值IEnumerable(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
有关其他示例,请参阅 迭代器。