Поделиться через


Оператор 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 метода доступа должно соответствовать следующим требованиям:

Функция итератора не может возникать в событии, конструкторе экземпляров, статического конструктора или статического деструктора.

Функция итератора может быть анонимной функцией. Дополнительные сведения см. в разделе Итераторы.

Обработка исключений.

Оператор 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 завершается, когда достигается конец функции итератора или 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

Дополнительные примеры см. в разделе "Итераторы".

См. также