Оператор Yield (Visual Basic)
Отправляет следующий элемент коллекции в инструкцию For Each...Next
.
Синтаксис
Yield expression
Параметры
Термин | Определение |
---|---|
expression |
Обязательный. Выражение, которое неявно преобразуется в тип функции итератора или Get метода доступа, содержащего инструкцию Yield . |
Замечания
Оператор Yield
возвращает один элемент коллекции одновременно. Инструкция Yield
включается в функцию итератора или Get
метод доступа, которая выполняет пользовательские итерации по коллекции.
Функция итератора используется с помощью элемента For Each... Следующая инструкция или запрос LINQ. Каждая итерация For Each
цикла вызывает функцию итератора. Yield
Когда оператор достигается в функции итератора, возвращается, expression
а текущее расположение в коде сохраняется. При следующем вызове функции итератора выполнение возобновляется с этого места.
Неявное преобразование должно существовать из типа expression
инструкции Yield
в тип возвращаемого типа итератора.
Для завершения итерации можно использовать Exit Function
инструкцию или Return
инструкцию.
"Доходность" не является зарезервированным словом и имеет особое значение только в том случае, если он используется в Iterator
функции или Get
методе доступа.
Дополнительные сведения о функциях итераторах и Get
методах доступа см. в разделе "Итераторы".
Функции итератора и получение методов доступа
Объявление функции итератора или Get
метода доступа должно соответствовать следующим требованиям:
Он должен включать модификатор итератора .
Возвращаемый тип должен быть IEnumerable, IEnumerable<T>, IEnumerator или IEnumerator<T>.
У него не может быть никаких
ByRef
параметров.
Функция итератора не может возникать в событии, конструкторе экземпляров, статического конструктора или статического деструктора.
Функция итератора может быть анонимной функцией. Дополнительные сведения см. в разделе Итераторы.
Обработка исключений.
Оператор Yield
может находиться в Try
блоке try... Поймать... Наконец, оператор. Блок 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
не выполняет текст функции. Вместо этого вызов возвращает IEnumerable(Of String)
в переменную elements
.
В итерации цикла For Each
метод MoveNext вызывается для elements
. Этот вызов выполняет тело MyIteratorFunction
до достижения следующего оператора Yield
. Оператор Yield
возвращает выражение, определяющее не только значение переменной element
для потребления текстом цикла, но и Current свойство элементов, которое является .IEnumerable (Of String)
В каждой последующей итерации цикла For Each
выполнение тела итератора продолжается с места остановки и при достижении оператора Yield
оно снова останавливается. Цикл For Each
завершается, когда достигается конец функции итератора или Return
Exit 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
Дополнительные примеры см. в разделе "Итераторы".