Pro každý...Další příkaz (Visual Basic)
Skupina příkazů se opakuje pro každý prvek v kolekci.
For Each element [ As datatype ] In group
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ element ]
Části
Termín |
Definice |
element |
Vyžaduje For Each prohlášení.Nepovinné Next prohlášení.Proměnná.Používá pro iterování prvků kolekce. |
datatype |
Požadováno pokud element není již deklarován.Datový typ element. |
group |
Povinné.Proměnné s typem, který je typ kolekce nebo objekt.Odkazuje na kolekci, nad nímž statements k opakování. |
statements |
Nepovinné.Jeden nebo více příkazů mezi For Each a Next spuštění u každé položky v group. |
Continue For |
Nepovinné.Převede ovládací prvek na začátku For Each smyčky. |
Exit For |
Nepovinné.Převede ovládací prvek z For Each smyčky. |
Next |
Povinné.Ukončí definici For Each smyčky. |
Jednoduchý příklad
Use a For Each...Next opakovat, pokud chcete opakovat sadu příkazů pro každý prvek v kolekci nebo poli.
Tip
A Pro...Další příkaz (Visual Basic) funguje dobře při každé iteraci smyčky přidružit Proměnná ovládacího prvku a určit počáteční a konečné hodnoty dané proměnné.Ale při jednání s kolekcí pojmu počáteční a konečné hodnoty není smysluplné a neznáte nutně kolik prvků kolekce má.V takovémto případě For Each...Next smyčka je často lepší volbou.
V následujícím příkladu For Each...Next příkaz prochází všechny prvky kolekce seznam.
' 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
Další příklady naleznete v tématu Kolekce (C# a Visual Basic) a Matice v jazyce Visual Basic.
Vnořené smyčky
Můžete vnořovat For Each smyčky vložením jedné smyčky v rámci jiného.
Následující příklad ukazuje vnořený For Each...Next struktury.
' 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
Je-li vnořit smyčky každé smyčce musí mít jedinečné element proměnné.
Můžete také vnořit různé druhy struktury řízení do sebe.Další informace naleznete v tématu Vnořené struktury řízení (Visual Basic).
Pro ukončení a pokračovat
Ukončení pro příkaz způsobí spuštění ukončete For...Next smyčky a kdy řízení příkazu, který následuje Next prohlášení.
Continue For Příkaz předá řízení bezprostředně následující iteraci smyčky.Další informace naleznete v tématu Pokračovat v prohlášení (Visual Basic).
Následující příklad ukazuje, jak použít Continue For a Exit For příkazy.
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
Můžete umístit libovolný počet Exit For prohlášení v For Each smyčky.Při použití v rámci vnořené For Each smyčky, Exit For způsobí spuštění ukončete nejvnitřnějšího ovládacího prvku opakovat a převody na nejbližší vyšší úroveň vnoření.
Exit Forje často používán po zhodnocení nějakou podmínku, například v If...Then...Else struktury.Můžete chtít použít Exit For pro následující podmínky:
Pokračováním iterace je zbytečné nebo nemožné.Příčinou může být chybné hodnoty nebo požadavek na ukončení.
Výjimka zachycena v Try...Catch...Finally.Můžete použít Exit For na konci Finally bloku.
Zde nekonečné smyčce, což je smyčky, která by mohla spustit velký nebo dokonce nekonečné udává, kolikrát.Pokud odhalíte takové podmínky můžete použít Exit For k návratu smyčky.Další informace naleznete v tématu Proveďte...Příkaz LOOP (Visual Basic).
Iterátory
Můžete použít iterátor k provedení vlastní iterace v kolekci.Iterace může být například funkce nebo Get přistupujícího objektu.Používá Yield příkaz vrátit každý prvek kolekce, jeden najednou.
Volání pomocí iterace For Each...Next prohlášení.Každém opakování For Each smyčka volá iterace.Při Yield prohlášení je dosaženo v iterační výraz v Yield vrátil prohlášení a zachovány aktuální umístění v kódu.Spuštění z tohoto umístění restartován při příštím se nazývá iterace.
Následující příklad používá funkci iterátoru.Funkce iterační má Yield příkaz, který je uvnitř pro...Další smyčky.V ListEvenNumbers metoda, v každém opakování For Each prohlášení subjektu vytvoří volání funkce iterátor, který pokračuje na další Yield prohlášení.
Public Sub ListEvenNumbers()
For Each number As Integer In EvenSequence(5, 18)
Debug.Write(number & " ")
Next
Debug.WriteLine("")
' Output: 6 8 10 12 14 16 18
End Sub
Private Iterator Function EvenSequence(
ByVal firstNumber As Integer, ByVal lastNumber As Integer) _
As System.Collections.Generic.IEnumerable(Of Integer)
' Yield even numbers in the range.
For number = firstNumber To lastNumber
If number Mod 2 = 0 Then
Yield number
End If
Next
End Function
Další informace naleznete v tématu U iterátorů (C# a Visual Basic), Příkaz yield (Visual Basic) a Iterace (Visual Basic).
Technická implementace
When a For Each…Next příkaz spustí Visual Basic vyhodnocuje kolekce pouze jednou, před spuštěním smyčky.Pokud se změní vaše bloku element nebo group, tyto změny neovlivní iteraci smyčky.
Při všech prvků v kolekci byly postupně přiřazeny element, For Each smyčky zastaví a ovládací prvek projde následující příkaz Next prohlášení.
Pokud element nebyla deklarována mimo této smyčky je třeba deklarovat v For Each prohlášení.Můžete deklarovat typ element explicitně pomocí technologie As prohlášení, nebo se můžete spolehnout na odvození typu proměnné přiřazení typu.V obou případech rozsah element je do těla smyčky.Však nelze deklarovat element vně i uvnitř smyčky.
Volitelně můžete zadat element v Next prohlášení.To zlepšuje čitelnost programu, zejména v případě, že můžete vnořovat For Each smyčky.Je třeba zadat stejné proměnné jako ten, který se zobrazí v odpovídajících For Each prohlášení.
Chcete se vyhnout změně hodnoty element uvnitř smyčky.To může ztížit čtení a ladění kódu.Změna hodnoty group nemá žádný vliv na kolekci nebo jeho části, které byly stanoveny při prvním zadání smyčky.
Když provádíte vnoření smyčky, pokud Next prohlášení vnější úroveň vnoření je zjištěna před Next vnitřní úrovně kompilátor signalizuje chybu.Však kompilátor může zjistit to překrývající se chyba pouze v případě, že zadáte element v každé Next prohlášení.
Pokud váš kód závisí na procházení kolekce v určitém pořadí, For Each...Next smyčka není ideální, pokud znáte charakteristiky objektu čítače výčtu zpřístupňuje kolekci.Pořadí průchodu není určeno jazyka Visual Basic, ale to MoveNext metoda objektu čítače výčtu.Proto není možné odhadnout, který prvek kolekce je první, které mají být vráceny v element, nebo, což je další, které mají být vráceny po daný prvek.Může dosáhnout spolehlivější výsledky pomocí smyčky různé struktury, například For...Next or Do...Loop.
Datový typ element musí být takové, že datový typ prvků group lze převést na něj.
Datový typ group musí být typu odkazu, který odkazuje na kolekci nebo pole, které je vyčíslitelné.Obvykle to znamená, že group odkazuje na objekt, který implementuje IEnumerable rozhraní System.Collections oboru názvů nebo IEnumerable<T> rozhraní System.Collections.Generic oboru názvů.System.Collections.IEnumerabledefinuje GetEnumerator metodu, která vrátí objekt čítače výčtu kolekce.Implementuje objekt enumerator System.Collections.IEnumerator rozhraní System.Collections oboru názvů a poskytuje Current vlastnost a Reset a MoveNext metod.Jazyk Visual Basic používá tyto k procházení kolekce.
Zužující převody
Při Option Strict je nastavena na On, zužující převody obvykle způsobí chyby kompilátoru.V For Each prohlášení, avšak převody z prvků v group na element jsou vyhodnoceny a provedeny v době běhu a odstraňují chyby kompilátoru, které jsou způsobeny zužující převody.
V následujícím příkladu přiřazení m jako počáteční hodnotu pro n není při kompilaci Option Strict totiž na převod Long k Integer je zužujícího převodu.V For Each prohlášení, avšak žádná chyba kompilátoru je uvedena i v případě přiřazení k number stejný převod z Long na Integer.V For Each dojde k chybě při běhu příkazu, který obsahuje velké množství, při ToInteger platí pro velké množství.
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
IEnumerator volání
Při provádění For Each...Next , spustí smyčku jazyka Visual Basic ověří, že group odkazuje na platný objekt.V opačném případě je vyvolána výjimka.V opačném případě se volá MoveNext metody a Current vlastnosti objektu čítače výčtu se vrátíte na první element.Pokud MoveNext označuje, že je bez dalšího prvku, pokud je kolekce prázdná, For Each smyčky zastaví a ovládací prvek projde následující příkaz Next prohlášení.V opačném případě se nastaví Visual Basic element na první prvek a spustí příkaz blokovat.
Pokaždé, když dostal jazyka Visual Basic Next prohlášení, vrací For Each prohlášení.Znovu volá MoveNext a Current vrátit další prvek a znovu jej buď bloku se spustí nebo ukončí smyčku v závislosti na výsledku.Tento proces pokračuje, dokud MoveNext označuje, že je bez dalšího prvku nebo Exit For zjistil prohlášení.
Úprava kolekce. Čítač objekt vrácený funkcí GetEnumerator obvykle neumožňuje změnu kolekce přidávání, odstraňování, nahrazením nebo změna pořadí prvků.Pokud změníte kolekci po spuštění For Each...Next smyčky, objekt čítače výčtu se stane neplatným a další pokus o přístup k elementu způsobí, že InvalidOperationException výjimku.
Však toto blokování změna není určena Visual Basic, ale spíše provádění IEnumerable rozhraní.Je možné implementovat IEnumerable způsobem, který umožňuje úpravu během opakování.Pokud uvažujete o provedení takové dynamické změny, přesvědčte se, zda pochopit vlastnosti IEnumerable implementaci v kolekci, kterou používáte.
Úpravy prvků kolekce.Current Vlastnosti objektu čítače výčtu je Jen pro čtení (Visual Basic), a vrací místní kopie jednotlivých prvků kolekce.To znamená, že nelze změnit samotné prvky v For Each...Next loop.Změny provedete ovlivní pouze místní kopie z Current a neprojeví se zpět do zdrojové kolekce.Nicméně prvku nastavena na odkazový typ, lze upravovat členy instance, na kterou odkazuje.Následující příklad upravuje BackColor každý člen thisControl prvku.Nelze však změnit thisControl sám.
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
V předchozím příkladu lze změnit BackColor každý člen thisControl element, přestože nelze změnit thisControl sám.
Procházení polí. Protože Array implementuje třída IEnumerable rozhraní, matic vystavit GetEnumerator metoda.To znamená, že můžete iterovat matice se For Each...Next loop.Však může číst pouze prvky pole.Nelze je změnit.
Příklad
Následující příklad zobrazí seznam všech složek ve složce C:\ pomocí DirectoryInfo třídy.
Dim dInfo As New System.IO.DirectoryInfo("c:\")
For Each dir As System.IO.DirectoryInfo In dInfo.GetDirectories()
Debug.WriteLine(dir.Name)
Next
Následující příklad ukazuje postup při řazení kolekce.Příklad seřadí instance Car třídy, které jsou uloženy v List<T>.Car Implementuje třída IComparable<T> rozhraní, které vyžaduje, aby CompareTo metoda provádí.
Každé volání CompareTo metoda umožňuje jeden porovnání, která slouží k řazení.Uživatel zapisovat kód v CompareTo metoda vrátí hodnotu pro všechna porovnání aktuálního objektu s jiným objektem.Vrácená hodnota je menší než nula, pokud je aktuální objekt menší než druhý objekt větší než nula, pokud je aktuální objekt větší než jiný objekt a nula Pokud stejný.Díky tomu lze v kódu definovat kritéria pro větší, menší nebo rovno.
V ListCars metoda, cars.Sort() prohlášení seřadí seznamu.Toto volání Sort metoda List<T> způsobí, že CompareTo metoda je volána automaticky pro Car objekty v List.
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(Of Car)
Public Property Name As String
Public Property Speed As Integer
Public Property Color As String
Public Function CompareTo(ByVal other As Car) As Integer _
Implements System.IComparable(Of Car).CompareTo
' A call to this method makes a single comparison that is
' used for sorting.
' Determine the relative order of the objects being compared.
' Sort by color alphabetically, and then by speed in
' descending order.
' 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
Viz také
Referenční dokumentace
Pro...Další příkaz (Visual Basic)
Při...Ukončit při výpisu (Visual Basic)
Proveďte...Příkaz LOOP (Visual Basic)
Koncepty
Rozšiřování a zužující převody (Visual Basic)
Inicializátory objektů: Pojmenované a anonymní typy (Visual Basic)
Inicializátory kolekce (Visual Basic)