For Each...Next ステートメント (Visual Basic)For Each...Next Statement (Visual Basic)

ステートメントのグループをコレクション内の各要素に対して繰り返されます。Repeats a group of statements for each element in a collection.

構文Syntax

For Each element [ As datatype ] In group  
    [ statements ]  
    [ Continue For ]  
    [ statements ]  
    [ Exit For ]  
    [ statements ]  
Next [ element ]  

指定項目Parts

用語Term 定義Definition
element 必要なFor Eachステートメント。Required in the For Each statement. 省略可能で、Nextステートメント。Optional in the Next statement. 変数。Variable. コレクションの要素を反復処理するために使用します。Used to iterate through the elements of the collection.
datatype 省略可能な場合 Option Infer (既定)、またはelementは既に宣言されている。 場合に必要なOption Inferがオフとelement既に宣言されていません。Optional if Option Infer is on (the default) or element is already declared; required if Option Infer is off and element isn't already declared. elementのデータ型。The data type of element.
group 必須。Required. コレクション型またはオブジェクト型を含む変数を指定します。A variable with a type that's a collection type or Object. コレクションを参照、statementsられます。Refers to the collection over which the statements are to be repeated.
statements 省略可能です。Optional. 1 つまたは複数のステートメント間For EachNext内の各項目で実行されるgroupします。One or more statements between For Each and Next that run on each item in group.
Continue For 省略可能です。Optional. 先頭に制御を転送、For Eachループします。Transfers control to the start of the For Each loop.
Exit For 省略可能です。Optional. うちに制御を転送、For Eachループします。Transfers control out of the For Each loop.
Next 必須。Required. 定義を終了、For Eachループします。Terminates the definition of the For Each loop.

簡単な例Simple Example

使用して、 For Each.Nextコレクションまたは配列の各要素の一連のステートメントを繰り返し表示するときにループ処理します。Use a For Each...Next loop when you want to repeat a set of statements for each element of a collection or array.

ヒント

Aをしています.次のステートメントのうまくときに、ループの各繰り返しを制御変数に関連付けるし、その変数の最初と最後の値を決定します。A For...Next Statement works well when you can associate each iteration of a loop with a control variable and determine that variable's initial and final values. ただし、コレクションを扱う場合は、最初と最後の値の概念は意味のあると、コレクションは、要素の数がわからないとは限りません。However, when you are dealing with a collection, the concept of initial and final values isn't meaningful, and you don't necessarily know how many elements the collection has. このような場合で、 For Each.Nextループは、多くの場合、ことをお勧めします。In this kind of case, a For Each...Next loop is often a better choice.

次の例では、 For Each.NextIn the following example, the For EachNext ステートメントは、リスト コレクションのすべての要素を反復処理します。statement iterates through all the elements of a List collection.

' 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

例については、次を参照してください。コレクション配列します。For more examples, see Collections and Arrays.

入れ子になったループNested Loops

入れ子にすることができますFor Each内に別の 1 つのループを配置することでループします。You can nest For Each loops by putting one loop within another.

次の例で入れ子になったFor Each.NextThe following example demonstrates nested For EachNext 構造体。structures.

' 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 

各ループが一意ありますループを入れ子にするとelement変数。When you nest loops, each loop must have a unique element variable.

さまざまな種類を 1 つの制御構造の入れ子にすることもできます。You can also nest different kinds of control structures within each other. 詳細については、次を参照してください。制御構造の入れ子になったします。For more information, see Nested Control Structures.

終了しの続行Exit For and Continue For

Exit Forステートメントは、実行を終了する、 For.NextThe Exit For statement causes execution to exit the ForNext これに続くステートメントにループと転送の制御、Nextステートメント。loop and transfers control to the statement that follows the Next statement.

Continue Forステートメント コントロールに直ちに移します、ループの次の反復処理します。The Continue For statement transfers control immediately to the next iteration of the loop. 詳細については、次を参照してください。 Continue ステートメントします。For more information, see Continue Statement.

次の例は、使用する方法を示します、Continue ForExit Forステートメント。The following example shows how to use the Continue For and Exit For statements.

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

任意の数を配置するExit For内のステートメントをFor Eachループします。You can put any number of Exit For statements in a For Each loop. 使用すると内で入れ子になったFor Eachループ、Exit For実行を入れ子の上位のレベルへの最も内側のループと転送コントロールを終了します。When used within nested For Each loops, Exit For causes execution to exit the innermost loop and transfers control to the next higher level of nesting.

Exit For いくつかの条件の評価後は、よく使用など、 If.Then...Else構造体。Exit For is often used after an evaluation of some condition, for example, in an If...Then...Else structure. 使用するExit For次の条件。You might want to use Exit For for the following conditions:

  • 反復処理を続けることは不要なか不可能です。Continuing to iterate is unnecessary or impossible. これは、エラー値や終了要求によって発生する可能性があります。This might be caused by an erroneous value or a termination request.

  • 例外がキャッチされました、 Try.Catch...Finally.使用する場合がありますExit Forの最後に、Finallyブロックします。An exception is caught in a Try...Catch...Finally. You might use Exit For at the end of the Finally block.

  • 何度も長時間または無限でも実行できるループ、無限ループがあります。There an endless loop, which is a loop that could run a large or even infinite number of times. このような条件を検出した場合は使用できますExit Forループを抜けます。If you detect such a condition, you can use Exit For to escape the loop. 詳細については、次を参照してください操作を行います...ステートメントをループです。For more information, see Do...Loop Statement.

IteratorsIterators

使用する、反復子コレクションに対するカスタム イテレーションを実行します。You use an iterator to perform a custom iteration over a collection. 関数は、反復子またはGetアクセサー。An iterator can be a function or a Get accessor. 使用して、Yieldステートメントを一度に 1 つのコレクションの各要素を返します。It uses a Yield statement to return each element of the collection one at a time.

使用して、反復子を呼び出す、For Each...Nextステートメント。You call an iterator by using a For Each...Next statement. For Each ループの各イテレーションは、反復子を呼び出します。Each iteration of the For Each loop calls the iterator. ときに、Yieldステートメントが反復子の式に到達、Yieldステートメントが返され、コードの現在の場所が保持されます。When a Yield statement is reached in the iterator, the expression in the Yield statement is returned, and the current location in code is retained. 次回、反復子が呼び出されると、この位置から実行が再開されます。Execution is restarted from that location the next time that the iterator is called.

次の例では、反復子関数を使用します。The following example uses an iterator function. Iterator 関数が、Yield内にあるステートメント、をしています.[次へ]ループします。The iterator function has a Yield statement that's inside a For…Next loop. ListEvenNumbersメソッドは、の各反復処理、For Eachステートメント本体は、次に進みますこの反復子関数の呼び出しを作成します。Yieldステートメント。In the ListEvenNumbers method, each iteration of the For Each statement body creates a call to the iterator function, which proceeds to the next Yield statement.

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

詳細については、次を参照してください。反復子Yield ステートメント、および反復子します。For more information, see Iterators, Yield Statement, and Iterator.

技術的な実装Technical Implementation

ときに、 For Each.NextWhen a For EachNext ステートメントが実行されて、Visual Basic では、コレクション、ループの開始前に、1 つだけの時間を評価します。statement runs, Visual Basic evaluates the collection only one time, before the loop starts. ステートメント ブロックが変更された場合elementまたはgroup、これらの変更は、ループの反復処理に影響はありません。If your statement block changes element or group, these changes don't affect the iteration of the loop.

ときに、コレクション内のすべての要素連続的に割り当てられているelementFor Each停止をループし、次のステートメントのパスを制御、Nextステートメント。When all the elements in the collection have been successively assigned to element, the For Each loop stops and control passes to the statement following the Next statement.

場合Option Inferは Visual Basic コンパイラ (既定の設定)、上のデータ型を推論できるelementします。If Option Infer is on (its default setting), the Visual Basic compiler can infer the data type of element. オフの場合とelement宣言されていない、ループの外側に宣言する必要がありますで、For Eachステートメント。If it is off and element hasn't been declared outside the loop, you must declare it in the For Each statement. データ型を宣言するelementを明示的に、使用、As句。To declare the data type of element explicitly, use an As clause. 外側の要素のデータ型が定義されていない場合、 For Each.Nextコンス トラクター、そのスコープがループの本体。Unless the data type of element is defined outside the For Each...Next construct, its scope is the body of the loop. 宣言することはできません注element外側と、ループ内での両方。Note that you cannot declare element both outside and inside the loop.

必要に応じて指定することができますelementで、Nextステートメント。You can optionally specify element in the Next statement. 入れ子にしていない場合は特に、プログラムの読みやすさが向上しますこのFor Eachループします。This improves the readability of your program, especially if you have nested For Each loops. 対応する表示されるものと同じ変数を指定する必要がありますFor Eachステートメント。You must specify the same variable as the one that appears in the corresponding For Each statement.

値を変更しないようにするelementループ内で。You might want to avoid changing the value of element inside a loop. これを行うことが難しくを読み取って、コードをデバッグします。Doing this can make it more difficult to read and debug your code. 値を変更するgroupコレクションまたはその要素は、ループが最初に入力されたときに決定されたには影響しません。Changing the value of group doesn't affect the collection or its elements, which were determined when the loop was first entered.

場合に、ループが入れ子しているときに、Nextする前に、外側の入れ子レベルのステートメントが見つかりましたが、Nextコンパイラがエラーを内部レベルの。When you're nesting loops, if a Next statement of an outer nesting level is encountered before the Next of an inner level, the compiler signals an error. ただし、コンパイラが検出できるこれを指定する場合にのみ、エラーを重複elementですべてNextステートメント。However, the compiler can detect this overlapping error only if you specify element in every Next statement.

特定の順序でコレクションを走査することで、コードが依存している場合、 For Each.Nextループが最適な選択肢はありませんが、コレクション、列挙子オブジェクトの特性がわかっている場合を除き公開します。If your code depends on traversing a collection in a particular order, a For Each...Next loop isn't the best choice, unless you know the characteristics of the enumerator object the collection exposes. 走査の順序がによっての Visual Basic では、によって決定されていない、MoveNext列挙子オブジェクトのメソッド。The order of traversal isn't determined by Visual Basic, but by the MoveNext method of the enumerator object. コレクションの要素が、最初に返される予測できないことのため、 element、特定の要素の後に返される次であるか。Therefore, you might not be able to predict which element of the collection is the first to be returned in element, or which is the next to be returned after a given element. など、さまざまなループ構造を使用して、信頼性の高い結果を実現することがありますFor.NextまたはDo.Loop.You might achieve more reliable results using a different loop structure, such as For...Next or Do...Loop.

ランタイム内の要素を変換できる必要がありますgroupelementします。The runtime must be able to convert the elements in group to element. [Option Strict] ステートメントは、拡大と縮小の両方が許可されているかどうかを制御します。 (Option Strictはオフで、既定値)、または拡大変換だけを許可するかどうか (Option Strict上)。The [Option Strict] statement controls whether both widening and narrowing conversions are allowed (Option Strict is off, its default value), or whether only widening conversions are allowed (Option Strict is on). 詳細については、次を参照してください。縮小変換します。For more information, see Narrowing conversions.

データ型groupコレクションまたは列挙可能なである配列を参照する参照型である必要があります。The data type of group must be a reference type that refers to a collection or an array that's enumerable. つまり通常groupを実装するオブジェクトを指す、IEnumerableのインターフェイス、System.Collections名前空間またはIEnumerable<T>のインターフェイス、System.Collections.Generic名前空間。Most commonly this means that group refers to an object that implements the IEnumerable interface of the System.Collections namespace or the IEnumerable<T> interface of the System.Collections.Generic namespace. System.Collections.IEnumerable 定義、GetEnumeratorメソッドで、コレクションの列挙子オブジェクトを返します。System.Collections.IEnumerable defines the GetEnumerator method, which returns an enumerator object for the collection. 列挙子オブジェクトを実装して、System.Collections.IEnumeratorのインターフェイス、System.Collections名前空間を公開し、CurrentプロパティおよびResetMoveNextメソッド。The enumerator object implements the System.Collections.IEnumerator interface of the System.Collections namespace and exposes the Current property and the Reset and MoveNext methods. Visual Basic では、これらを使用して、コレクションをスキャンします。Visual Basic uses these to traverse the collection.

縮小変換Narrowing Conversions

ときにOption Strictに設定されているOn、通常、縮小変換でコンパイラ エラーが発生します。When Option Strict is set to On, narrowing conversions ordinarily cause compiler errors. For Eachステートメント、ただし、内の要素からの変換groupelementが評価され、実行時に実行し、縮小変換によるコンパイラ エラーが抑制されます。In a For Each statement, however, conversions from the elements in group to element are evaluated and performed at run time, and compiler errors caused by narrowing conversions are suppressed.

割り当て、次の例でmの初期値としてnときにコンパイルされませんOption Strictためではへの変換、LongInteger縮小変換です。In the following example, the assignment of m as the initial value for n doesn't compile when Option Strict is on because the conversion of a Long to an Integer is a narrowing conversion. For Eachステートメントでは、コンパイラ エラーがないへの代入も報告numberから同じ変換が必要LongIntegerします。In the For Each statement, however, no compiler error is reported, even though the assignment to number requires the same conversion from Long to Integer. For Each数が多いを含むステートメントでは、実行時エラーが発生したときにToInteger膨大な数に適用されます。In the For Each statement that contains a large number, a run-time error occurs when ToInteger is applied to the large number.

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 の呼び出しIEnumerator Calls

ときの実行、 For Each.Nextループの開始、ことを確認します Visual Basicgroupは有効なコレクション オブジェクトを参照します。When execution of a For Each...Next loop starts, Visual Basic verifies that group refers to a valid collection object. それ以外の場合は、例外をスローします。If not, it throws an exception. それ以外の場合、呼び出し、MoveNextメソッドとCurrent最初の要素を返す列挙子オブジェクトのプロパティ。Otherwise, it calls the MoveNext method and the Current property of the enumerator object to return the first element. 場合MoveNextがない、次の要素は、コレクションが空の場合を示します、For Each停止をループし、次のステートメントのパスを制御、Nextステートメント。If MoveNext indicates that there is no next element, that is, if the collection is empty, the For Each loop stops and control passes to the statement following the Next statement. Visual Basic の場合は、設定elementに最初の要素と、ステートメント ブロックを実行します。Otherwise, Visual Basic sets element to the first element and runs the statement block.

Visual Basic が発生するたびに、Nextにステートメントを返します、For Eachステートメント。Each time Visual Basic encounters the Next statement, it returns to the For Each statement. もう一度呼び出してMoveNextCurrentブロックが実行か、次の要素と、もう一度返しますまたは、結果に応じて、ループを停止します。Again it calls MoveNext and Current to return the next element, and again it either runs the block or stops the loop depending on the result. までこのプロセスは継続MoveNext次の要素がないことを示しますまたはExit Forステートメントが見つかりました。This process continues until MoveNext indicates that there is no next element or an Exit For statement is encountered.

コレクションを変更します。Modifying the Collection. によって返される列挙子オブジェクトGetEnumerator通常変更することは、コレクションを追加、削除、置換、またはいずれかの要素の順序を変更します。The enumerator object returned by GetEnumerator normally doesn't let you change the collection by adding, deleting, replacing, or reordering any elements. 開始した後に、コレクションを変更する場合、 For Each.Nextループ列挙子オブジェクトが無効と要素にアクセスするには、次の試行により、InvalidOperationException例外。If you change the collection after you have initiated a For Each...Next loop, the enumerator object becomes invalid, and the next attempt to access an element causes an InvalidOperationException exception.

ただし、この変更のブロックされていない決定 Visual Basic での実装ではなく、IEnumerableインターフェイス。However, this blocking of modification isn't determined by Visual Basic, but rather by the implementation of the IEnumerable interface. 実装することはIEnumerableで反復処理中に変更できるようにします。It is possible to implement IEnumerable in a way that allows for modification during iteration. このような動的な変更を行うを検討している場合の特性を理解するように、IEnumerableを使用するコレクションを実装します。If you are considering doing such dynamic modification, make sure that you understand the characteristics of the IEnumerable implementation on the collection you are using.

コレクションの要素を変更します。Modifying Collection Elements. Current列挙子オブジェクトのプロパティがReadOnly、し、各コレクションの要素のローカル コピーを返します。The Current property of the enumerator object is ReadOnly, and it returns a local copy of each collection element. つまり、要素自体を変更できないことで、 For Each.Nextループします。This means that you cannot modify the elements themselves in a For Each...Next loop. 対して行った変更の影響からローカルのコピーのみCurrent基になるコレクションにも反映されていないとします。Any modification you make affects only the local copy from Current and isn't reflected back into the underlying collection. ただし、要素が参照型の場合は、ポイントするインスタンスのメンバーを変更できます。However, if an element is a reference type, you can modify the members of the instance to which it points. 次の例では、変更、BackColorのそれぞれに所属thisControl要素。The following example modifies the BackColor member of each thisControl element. ただし、変更することはできません、thisControl自体。You cannot, however, modify thisControl itself.

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  

前の例を変更できます、BackColorのそれぞれに所属thisControl要素、それを変更できませんがthisControl自体。The previous example can modify the BackColor member of each thisControl element, although it cannot modify thisControl itself.

配列の反復処理します。Traversing Arrays. Arrayクラスが実装する、IEnumerableインターフェイスでは、すべての配列を公開、GetEnumeratorメソッド。Because the Array class implements the IEnumerable interface, all arrays expose the GetEnumerator method. つまり、配列を反復処理できること、 For Each.Nextループします。This means that you can iterate through an array with a For Each...Next loop. ただし、配列の要素のみを読み取ることができます。However, you can only read the array elements. 変更することはできません。You cannot change them.

Example

次の例を使用して、C:\ ディレクトリ内のすべてのフォルダーを一覧表示、DirectoryInfoクラス。The following example lists all the folders in the C:\ directory by using the DirectoryInfo class.

Dim dInfo As New System.IO.DirectoryInfo("c:\")
For Each dir As System.IO.DirectoryInfo In dInfo.GetDirectories()
    Debug.WriteLine(dir.Name)
Next

Example

次の例では、コレクションを並べ替えるための手順を示しています。The following example illustrates a procedure for sorting a collection. 例では、並べ替えのインスタンスをCarクラスに格納されている、List<T>します。The example sorts instances of a Car class that are stored in a List<T>. Car クラスは、IComparable<T> のメソッドの実装を必要とする CompareTo インターフェイスを実装します。The Car class implements the IComparable<T> interface, which requires that the CompareTo method be implemented.

呼び出しごとに、CompareToメソッドは、並べ替えに使用される単一の比較。Each call to the CompareTo method makes a single comparison that's used for sorting. CompareTo メソッドのユーザーが作成したコードは、現在のオブジェクトと別のオブジェクトとの各比較の値を戻します。User-written code in the CompareTo method returns a value for each comparison of the current object with another object. 現在のオブジェクトが別のオブジェクトよりも小さい場合はゼロ未満の値を、大きい場合はゼロ以上の値を、等しい場合はゼロを戻します。The value returned is less than zero if the current object is less than the other object, greater than zero if the current object is greater than the other object, and zero if they are equal. これによって、より大きい、より小さい、等しい、の条件をコードに定義することができます。This enables you to define in code the criteria for greater than, less than, and equal.

ListCars のメソッドでは、cars.Sort() ステートメントがリストを並べ替えます。In the ListCars method, the cars.Sort() statement sorts the list. SortList<T> メソッドへの呼び出しによって、CompareTo メソッドは Car 内の List オブジェクトに自動的に呼び出されます。This call to the Sort method of the List<T> causes the CompareTo method to be called automatically for the Car objects in the 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

関連項目See also