Compartilhar via


Instrução Yield (Visual Basic)

Envia o próximo elemento de uma coleção para uma declaração de For Each...Next .

Yield expression

Parâmetros

Termo

Definição

expression

Obrigatório. Uma expressão que é implicitamente conversível para o tipo de função do iterador ou acessadores de Get que contém a instrução de Yield .

Comentários

A declaração de Yield retorna um elemento de uma coleção em vez. A declaração de Yield está incluída em uma função de iterador ou em um acessador de Get , que executem iterações personalizados em uma coleção.

Você consome uma função de iterador usando Instrução For Each...Next (Visual Basic) ou consulta LINQ. Cada iteração do loop de For Each chama a função de iterador. Quando uma declaração de Yield é alcançada na função de iterador, expression é retornado, e o local atual no código é mantido. A execução é reiniciada de aquele local na próxima vez que a função de iterador é chamada.

Uma conversão implícita deve existir do tipo de expression na declaração de Yield para o tipo de retorno de iterador.

Você pode usar uma instrução de Exit Function ou de Return para finalizar a iteração.

“Produzir” não é uma palavra reservada e tem um significado especial somente quando é usado em uma função de Iterator ou em um acessador de Get .

Para obter mais informações sobre funções de iterador e os acessores de Get , consulte Iteradores (C# e Visual Basic).

Funções de iterador e obtém acessadores

A declaração de uma função de iterador ou um acessador de Get deve atender aos seguintes requisitos:

Uma função de iterador não pode ocorrer em um evento, em um construtor de instância, em um construtor estático, ou em um destrutor estático.

Uma função de iterador pode ser uma função anônimo. Para obter mais informações, consulte Iteradores (C# e Visual Basic).

Manipulação de exceção

Uma declaração de Yield pode estar dentro de um bloco de Try de Instrução Try...Catch...Finally (Visual Basic). Um bloco de Try que tem uma declaração de Yield pode ter blocos de Catch , e pode ter um bloco de Finally .

Uma declaração de Yield não pode ser dentro de um bloco de Catch ou um bloco de Finally .

Se o corpo de For Each (fora da função de iterador) gera uma exceção, um bloco de Catch na função de iterador não é executado, mas um bloco de Finally na função de iterador é executado. Um bloco de Catch dentro de uma função de iterador somente captura exceções que ocorrem dentro da função de iterador.

Implementação técnica

O código a seguir retorna IEnumerable (Of String) de uma função de iterador e em seguida iterar-lo através dos elementos de IEnumerable (Of String).

Dim elements As IEnumerable(Of String) = MyIteratorFunction()
    …
For Each element As String In elements
Next

A chamada a MyIteratorFunction não executa o corpo da função. Em vez de chamada retorna IEnumerable(Of String) na variável de elements .

Em uma iteração do loop de For Each de MoveNext , o método é chamado para elements. Esta chamada executa o corpo de MyIteratorFunction até que a próxima instrução de Yield seja alcançado. A declaração de Yield retorna uma expressão que não apenas determinar o valor da variável de element consumíveis pelo corpo de loop mas também da propriedade de Current de elementos, que é IEnumerable (Of String).

Em cada iteração do loop subsequente de For Each , a execução do corpo de iterador continua de onde parou novamente, parando quando atinge uma instrução de Yield . O loop de For Each termina quando o final da função de iterador ou de uma instrução de Return ou de Exit Function é alcançado.

Exemplo

O exemplo tem uma instrução de Yield que está dentro de um loop de For… Next . Cada iteração do corpo de instrução de Para cada em Main cria uma chamada para a função de iterador de Power . Cada chamada à função de iterador continua a seguir execução da declaração de Yield , que ocorre durante a próxima iteração do loop de For…Next .

O tipo de retorno do método de iterador é IEnumerable, um tipo de interface de iterador. Quando o método de iterador é chamado, retorna um objeto enumerável que contém a potências de um número.

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

O exemplo a seguir demonstra um acessador de Get que é um iterador. A declaração de propriedade inclui um modificador de 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

Para exemplos adicionais, consulte Iteradores (C# e Visual Basic).

Requisitos

Visual Studio 2012

Consulte também

Outros recursos

Iteradores (C# e Visual Basic)

Instruções (Visual Basic)