Yield ステートメント (Visual Basic)
コレクションの次の要素を For Each...Next
ステートメントに送ります。
構文
Yield expression
パラメーター
用語 | 定義 |
---|---|
expression |
必須です。 Yield ステートメントを含む iterator 関数または Get アクセサーの型に暗黙的に変換可能な式。 |
Remarks
Yield
ステートメントでは、コレクションの要素を一度に 1 つずつ返します。 Yield
ステートメントは、コレクションに対してカスタムの反復を実行する iterator 関数または Get
アクセサーに含まれます。
iterator 関数を使用するには、For Each...Next ステートメントまたは LINQ クエリを使用します。 For Each
ループの各反復は、iterator 関数を呼び出します。 Yield
ステートメントが iterator 関数に到達すると、expression
が返され、コードの現在の位置が保持されます。 次回、Iterator 関数が呼び出されると、この位置から実行が再開されます。
Yield
ステートメント内の expression
の型から、iterator の戻り値の型への暗黙的な変換が存在する必要があります。
Exit Function
または Return
ステートメントを使用すると、反復を終了できます。
"Yield" は予約語ではなく、Iterator
関数または Get
アクセサーで使用される場合にのみ特別な意味を持ちます。
iterator 関数と Get
アクセサーの詳細については、「反復子」を参照してください。
iterator 関数と Get アクセサー
iterator 関数または Get
アクセサーの宣言では、次の要件を満たしている必要があります。
Iterator 修飾子を含める必要があります。
戻り値の型は、IEnumerable、IEnumerable<T>、IEnumerator、または IEnumerator<T> であることが必要です。
ByRef
パラメーターを使用することはできません。
iterator 関数を、イベント、インスタンス コンストラクター、静的コンストラクター、静的デストラクターで指定することはできません。
iterator 関数は、匿名関数にすることができます。 詳細については、「 反復子」を参照してください。
例外処理
Yield
ステートメントは Try...Catch...Finally ステートメントの Try
ブロック内に指定できます。 Yield
ステートメントがある Try
ブロックには、Catch
ブロックと Finally
ブロックを記述することができます。
Yield
ステートメントを Catch
ブロックや Finally
ブロックに記述することはできません。
(iterator 関数の外部の) For Each
本体で例外がスローされた場合、iterator 関数の Catch
ブロックは実行されず、iterator 関数の Finally
ブロックが実行されます。 iterator 関数内の Catch
ブロックでキャッチされるのは、iterator 関数内で発生した例外だけです。
技術的な実装
次のコードでは、iterator 関数から 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
変数の値だけでなく、IEnumerable (Of String)
である要素の Current プロパティも判断する式が返されます。
For Each
ループの以降の各反復処理では、反復子本体の実行が中断した場所から続行し、Yield
ステートメントに到達したときに再度停止します。 iterator 関数または Return
または Exit Function
ステートメントの最後に到達すると、For Each
ループは完了します。
例 1
次の例では、For…Next ループ内に Yield
ステートメントが含まれます。 Main
内の For Each ステートメント本体の各反復処理では、Power
Iterator 関数が呼び出されます。 Iterator 関数を呼び出すごとに、Yield
ステートメントの次の実行に進みます。これは、For…Next
ループの次の反復処理で行われます。
Iterator メソッドの戻り値の型は、反復子インターフェイス型の IEnumerable<T> です。 Iterator メソッドが呼び出されると、数値の累乗を含む列挙可能なオブジェクトが返されます。
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
その他の例については、「反復子」を参照してください。
関連項目
.NET