Sdílet prostřednictvím


For Each...Next – 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 For...Next – 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# and Visual Basic) a Pole 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é řídicí struktury (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 Continue – příkaz (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 Do...Loop – příkaz (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 Iterátory (C# and Visual Basic), Yield – příkaz (Visual Basic) a Iterátor (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 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 ReadOnly (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.Car Implementuje třída IComparable 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 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

For...Next – příkaz (Visual Basic)

While...End While – příkaz (Visual Basic)

Do...Loop – příkaz (Visual Basic)

Koncepty

Struktury smyčky (Visual Basic)

Rozšíření a zúžení převodů (Visual Basic)

Inicializátory objektů: pojmenované a anonymní typy (Visual Basic)

Inicializátory kolekcí (Visual Basic)

Další zdroje

Kolekce (C# and Visual Basic)

Pole v jazyce Visual Basic