Instrução For Each...Next (Visual Basic)
Repete um grupo de instruções para cada elemento em uma coleção.
For Each element [ As datatype ] In group
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ element ]
Parts
Term |
Definition |
element |
Necessário o For Eachdedemonstrativo. Opcional na Nextdedemonstrativo. Variável. Usado para iterar por meio dos elementos da coleção. |
datatype |
Necessário se element já não está declarado. Tipo de dados de element. |
group |
Required. variávelde objeto. Refere-se à coleção através da qual o statements estão a ser repetido. |
statements |
Optional. Uma ou mais instruções entre For Each e Next que executar em cada item da group. |
Continue For |
Optional. Transfere o controle para o início do For Eachdeloop. |
Exit For |
Optional. Transfers control out of the For Each loop. |
Next |
Required. Terminates the definition of the For Each loop. |
Comentários
Use a For Each...Next loop quando você deseja repetir um conjunto de instruções para cada elemento de uma coleção ou matriz.
Visual Basic avalia a coleção somente uma vez, antes que o loop é iniciado. Se o seu bloco de demonstrativo altera element ou group, essas alterações não afetam a iteração do loop.
Quando todos os elementos da coleção tiverem sido atribuídos sucessivamente a element, o For Eachpára deloop e o controle passa a seguinte demonstrativo de Nextdemonstrativo.
Se element não foi declarada fora desse loop, você precisa declará-la na For Each demonstrativo. Você pode declarar o tipo de element explicitamente usando um Asdedemonstrativo, ou você pode contar com inferência de tipo para atribuir o tipo. Em ambos os casos, o escopo da element é o corpo do loop. No entanto, você não pode declarar element tanto fora como dentro do loop.
Opcionalmente, você pode especificar element na Next demonstrativo. Isso melhora a legibilidade do seu programa, especialmente se você tiver aninhado For Each loops. Você deve especificar a mesma variável como aquela que aparece no correspondente For Each demonstrativo.
Talvez você queira evitar a alteração do valor de element dentro de um loop. Isso pode dificultar a leitura e depurar seu código. Alterar o valor de group não afeta a coleção ou seus elementos, que foram determinados quando o loop foi digitado pela primeira vez.
Dica
A Instrução For...Next (Visual Basic) funciona bem quando você pode associar cada iteração de um loop com uma variável de controle e determinar dessa variávelinicial e final valores. Entretanto, quando você está lidando com uma coleção, o conceito de valores iniciais e finais não é significativo, e você não sabe necessariamente quantos elementos da coleção tem. Nesse caso, um For Each...Next loop é uma escolha melhor.
Se seu código depende atravessando uma coleção em uma ordem específica, um For Each...Nextloop é não é a melhor opção, a menos que saiba as características doobjeto de enumeradorexpõe a coleção . A ordem transversal não é determinada por Visual Basic, mas pela MoveNextométodo doobjetode enumerador. Portanto, você não poderá prever qual elemento da coleção é o primeiro a ser retornado em element, ou que é o próximo a serem retornados após um determinado elemento. Você pode obter resultados mais confiáveis usando aestruturade um loopde diferentes, como For...Next or Do...Loop .
O aninhamento de Loops
Você pode aninhar For Each loops colocando um loop dentro de outro. No entanto, cada loop deve ter um único element variável.
Você também pode aninhar diferentes tipos de estruturas de controle em si. For more information, see Estruturas de controle aninhado (Visual Basic).
Se um Nextademonstrativo de um nível de aninhamento externa é encontrado antes do Next de um nível interno, o compilador sinaliza um erro. No entanto, o compilador pode detectar isso sobreposição de erro somente se você especificar element em cada Next demonstrativo.
Sair para
O Sair para demonstrativo faz a execução para sair do For…Nextcontrolam deloop e transferências, a seguinte demonstrativo de Nextdemonstrativo.
Você pode colocar qualquer número de Exit For as instruções em um For Each loop. Quando usado aninhados dentro For Each loops, Exit For faz a execução sair o mais interno de loop e transfere o controle para o próximo nível mais alto de aninhamento.
Exit Foré geralmente usada após uma avaliação alguma condição, por exemplo, em um If...Then...Else estrutura. Talvez você queira usar Exit For para as seguintes condições:
Continuando a iterar é desnecessária ou impossível. Isso pode ser causado por um valor errado ou uma solicitaçãode encerramento.
Uma exceção é detectada em um Try...Catch...Finally. Você pode usar Exit For no final de Finally bloco.
Há um infinito loop, que é um loop que poderia executar um número grande ou até mesmo infinito de vezes. If you detect such a condition, you can use Exit For to escape the loop. For more information, see Declaração Do...Loop (Visual Basic).
O Continue Fordedemonstrativo transfere o controle imediatamente para a próxima iteração do loop. For more information, see Declaração Continue (Visual Basic).
Data Types
O tipo de dados de element deve ser tal que o tipo de dados dos elementos de group pode ser convertido em proprietário.
O tipo de dados de group deve ser um tipo de referência que se refere a uma coleção ou uma matriz que é enumerable. Geralmente isso significa que group refere-se a um objeto que implementa o IEnumerable interface do System.Collections namespace ou o IEnumerable<T> interface da System.Collections.Generic namespace. System.Collections.IEnumerableDefine o GetEnumeratormétodo, que retorna um enumeradordeobjeto da coleção. Oobjeto de enumeradorimplementa o System.Collections.IEnumeratorinterface da System.Collectionsnamespace e expõe a Currentpropriedade e o Reset e MoveNext métodos. Visual Basic as utiliza para percorrer a coleção.
Os elementos de group são geralmente do tipo Object , mas pode ter qualquer executar-vez que tipo de dados.
Narrowing Conversions
Quando Option Strict for definido como On, conversões explicitas de restrição normalmente causam erros do compilador. Em um For Each demonstrativo, no entanto, as conversões de elementos no group para element são avaliados e executada em tempo de execução, e os erros de compilador causados por restringir conversões são suprimidos.
No exemplo a seguir, a atribuição de m como o valor inicial para n oferece não compilar quando Option Strict está no porque a conversão de um Long para um Integer é uma conversão de restrição. No For Each demonstrativo, no entanto, nenhum erro de compilador é reportado, mesmo que a atribuição de number requer a mesma conversão de Long para Integer. No For Eachademonstrativo que contém um número grande, uma execução-de tempo de erro ocorre quando ToInteger é aplicado a grande número.
Option Strict On
Module Module1
Sub Main()
' The assignment of m to n causes a compiler error when
' Option Strict is on.
Dim m As Long = 987
'Dim n As Integer = m
' The For Each loop requires the same conversion but
' causes no errors, even when Option Strict is on.
For Each number As Integer In New Long() {45, 3, 987}
Console.Write(number & " ")
Next
Console.WriteLine()
' Output: 45 3 987
' Here a run-time error is raised because 9876543210
' is too large for type Integer.
'For Each number As Integer In New Long() {45, 3, 9876543210}
' Console.Write(number & " ")
'Next
Console.ReadKey()
End Sub
End Module
Chamadas de IEnumerator
Quando a execução de um For Each...Nextloop começa, Visual Basic verifica se group se refere a umobjeto válidodocoleção. Caso contrário, ele lança uma exceção. Caso contrário, ele chama o MoveNextmétodo e a Currentapropriedade doobjeto enumeradorpara retornar o primeiro elemento. Se MoveNext indica que não há nenhum elemento próximo, ou seja, se a coleção estiver vazia, o For Eachpára deloop e o controle passa a seguinte demonstrativo de Nextdemonstrativo. Caso contrário, define o Visual Basic element para o primeiro elemento e executa a demonstrativo de bloco.
Cada vez que encontrar em Visual Basic o Next demonstrativo, ele retorna para o For Each demonstrativo. Novamente chama MoveNext e Current para retornar o próximo elemento e novamente, ele executa o bloco ou a interrompe o loop dependendo do resultado. Esse processo continua até MoveNext indica que não há nenhum elemento próximo ou um Exit For demonstrativo é encontrado.
Modificações
Modificar a coleção. O enumeradordeobjeto retornado por GetEnumerator normalmente não permite alterar a coleção , adicionando, excluindo, substituindo, ou reorganizando elementos. Se você alterar a coleção depois que você inicia uma For Each...Nextloop, oobjeto de enumeradorse torna inválidoe a próxima tentativa de acessar um elemento faz com que uma InvalidOperationExceptionexceção.
No entanto, esse bloqueio de modificação não é determinado por Visual Basic, mas a implementação da IEnumerable interface. É possível implementar IEnumerable de forma que permite a modificação durante a iteração. Se você estiver considerando fazendo tal modificação dinâmica, certifique-se de que você entenda as características da IEnumerable implementação na coleção que você está usando.
A modificação de elementos de coleção. O Currenté depropriedade doobjeto de enumerador ReadOnly (Visual Basic), e ela retorna uma cópia local de cada elemento da coleção . Isso significa que você não pode modificar os próprios elementos em um For Each...Next loop. Qualquer modificação que você fizer afeta somente a cópia local de Current e não será refletida de volta para a coleçãosubjacente. No entanto, se um elemento é um tipo de referência, você pode modificar os membros da instância para o qual ele aponta. The following example illustrates this.
Sub lightBlueBackground(ByVal thisForm As System.Windows.Forms.Form)
For Each thisControl As System.Windows.Forms.Control In thisForm.Controls
thisControl.BackColor = System.Drawing.Color.LightBlue
Next thisControl
End Sub
O exemplo anterior pode modificar o BackColor membro de cada thisControl elemento, embora ele não é possível modificar thisControl próprio.
Atravessando os Arrays. Porque o Arrayclasse implementa o IEnumerabletodos os arrays deinterface, exponham a GetEnumeratormétodo. Isso significa que você pode iterar por meio de uma matriz com um For Each...Next loop. No entanto, você pode apenas ler os elementos da matriz. Não é possível alterá-los. For an illustration, see Como: executar várias instruções para cada elemento de uma coleção ou matriz (Visual Basic).
Exemplo
O exemplo a seguir mostra como usar o For Each…Next demonstrativo.
' Create a list of strings by using a
' collection initializer.
Dim lst As New List(Of String) _
From {"abc", "def", "ghi"}
' Iterate through the list.
For Each item As String In lst
Debug.Write(item & " ")
Next
Debug.WriteLine("")
'Output: abc def ghi
O exemplo a seguir demonstra aninhadas For Each…Next estruturas.
' Create lists of numbers and letters
' by using array initializers.
Dim numbers() As Integer = {1, 4, 7}
Dim letters() As String = {"a", "b", "c"}
' Iterate through the list by using nested loops.
For Each number As Integer In numbers
For Each letter As String In letters
Debug.Write(number.ToString & letter & " ")
Next
Next
Debug.WriteLine("")
'Output: 1a 1b 1c 4a 4b 4c 7a 7b 7c
O exemplo a seguir mostra como usar o Continue For e Exit For instruções.
Dim numberSeq() As Integer =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
For Each number As Integer In numberSeq
' If number is between 5 and 7, continue
' with the next iteration.
If number >= 5 And number <= 8 Then
Continue For
End If
' Display the number.
Debug.Write(number.ToString & " ")
' If number is 10, exit the loop.
If number = 10 Then
Exit For
End If
Next
Debug.WriteLine("")
' Output: 1 2 3 4 9 10
O exemplo a seguir lista todas as pastas no diretório C:\ usando o deDirectoryInfoclasse.
Dim dInfo As New System.IO.DirectoryInfo("c:\")
For Each dir As System.IO.DirectoryInfo In dInfo.GetDirectories()
Debug.WriteLine(dir.Name)
Next
O exemplo a seguir mostra como classificar uma coleção usando o IComparable interface.
Public Sub ListCars()
' Create some new cars.
Dim cars As New List(Of Car) From
{
New Car With {.Name = "car1", .Color = "blue", .Speed = 20},
New Car With {.Name = "car2", .Color = "red", .Speed = 50},
New Car With {.Name = "car3", .Color = "green", .Speed = 10},
New Car With {.Name = "car4", .Color = "blue", .Speed = 50},
New Car With {.Name = "car5", .Color = "blue", .Speed = 30},
New Car With {.Name = "car6", .Color = "red", .Speed = 60},
New Car With {.Name = "car7", .Color = "green", .Speed = 50}
}
' Sort the cars by color, alphabetically, and then by speed
' in descending order.
cars.Sort()
' View all of the cars.
For Each thisCar As Car In cars
Debug.Write(thisCar.Color.PadRight(5) & " ")
Debug.Write(thisCar.Speed.ToString & " ")
Debug.Write(thisCar.Name)
Debug.WriteLine("")
Next
' Output:
' blue 50 car4
' blue 30 car5
' blue 20 car1
' green 50 car7
' green 10 car3
' red 60 car6
' red 50 car2
End Sub
Public Class Car
Implements IComparable
Public Property Name As String
Public Property Speed As Integer
Public Property Color As String
Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
' Determine the relative order of the objects being compared.
' This is used to sort by color alphabetically, and then by
' speed in descending order.
' Obtain the other object for the comparison.
Dim other As Car = CType(obj, Car)
' Compare the colors.
Dim compare As Integer
compare = String.Compare(Me.Color, other.Color, True)
' If the colors are the same, compare the speeds.
If compare = 0 Then
compare = Me.Speed.CompareTo(other.Speed)
' Use descending order for speed.
compare = -compare
End If
Return compare
End Function
End Class
O exemplo a seguir inclui uma coleçãode personalizadaclasse que tenha um enumeradorde personalizado.
Public Sub ListColors()
Dim colors As New AllColors()
For Each theColor As Color In colors
Debug.Write(theColor.Name & " ")
Next
Debug.WriteLine("")
' Output: red blue green
End Sub
' Collection class.
Public Class AllColors
Implements System.Collections.IEnumerable
Private _colors() As Color =
{
New Color With {.Name = "red"},
New Color With {.Name = "blue"},
New Color With {.Name = "green"}
}
Public Function GetEnumerator() As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return New ColorEnumerator(_colors)
' Instead of creating a using a custom enumerator, you could
' use the GetEnumerator of the array.
'Return _colors.GetEnumerator
End Function
' Custom enumerator.
Private Class ColorEnumerator
Implements System.Collections.IEnumerator
Private _colors() As Color
Private _position As Integer = -1
Public Sub New(ByVal colors() As Color)
_colors = colors
End Sub
Public ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
Get
Return _colors(_position)
End Get
End Property
Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
_position += 1
Return (_position < _colors.Length)
End Function
Public Sub Reset() Implements System.Collections.IEnumerator.Reset
_position = -1
End Sub
End Class
End Class
' Element class.
Public Class Color
Public Property Name As String
End Class
Consulte também
Tarefas
Como: executar várias instruções para cada elemento de uma coleção ou matriz (Visual Basic)
Referência
Instrução For...Next (Visual Basic)
Instrução While...End While (Visual Basic)
Declaração Do...Loop (Visual Basic)
Conceitos
Estruturas de loop (Visual Basic)
Conversões de expansão e restrição (Visual Basic)
Inicializadores de objeto: Tipos nomeados e anônimos (Visual Basic)
Visão geral sobre inicializadores de coleção (Visual Basic)
Histórico de alterações
Date |
History |
Motivo |
Dezembro de 2010 |
Reorganizado a seção de comentários e exemplos de adicionado. |
Aprimoramento de informações. |