Visual BasicのFor Eachループは、コレクションや配列のすべての要素を順次反復処理するために設計されています。これにより、インデックスへの明示的なアクセスを必要とせず、列挙可能なオブジェクト(Collection、Array、リストなど)との作業が簡素化されます。
構文:
For Each element As DataType In collection ' elementに対するアクション Next
他のループとの違い:
For — カウンターと範囲を指定する必要があり、インデックスを使って要素にアクセスする必要がある場合に効果的です。While — 条件が真である限り実行され、予測不可能な反復回数に適しています。For Each — インデックスにアクセスせずにすべての要素を反復処理し、現代のコレクションに適しています。For Eachの制約と特性:
例:
Dim items As New List(Of Integer)({1, 2, 3}) For Each item As Integer In items Console.WriteLine(item) Next
ループ内でコレクションを変更しようとするとエラーが発生する可能性があります:
For Each item As Integer In items If item = 2 Then items.Remove(item) ' 例外! End If Next
For Eachを使用してコレクションの要素を値で変更できますか?要素が構造体の場合はどうですか?
いいえ、コレクションの要素が構造体(値型)の場合、For Eachの反復変数は値のコピーを持ちます。変数の変更はコレクションの実際の要素に影響を与えません。例えば:
Structure Point Public X As Integer End Structure Dim points As New List(Of Point)({New Point With {.X = 1}}) For Each pt In points pt.X = 100 ' points(0).Xは変更されません Next
ストーリー
プロジェクトでは、従業員の構造体フィールドを変更するためにFor Eachが使用されました。反復処理は元のデータを変更しませんでした。なぜなら、反復対象のオブジェクトがコピーであり、コレクションの要素そのものでなかったからです。そのため、給与の更新が反映されませんでした。
ストーリー
For Eachのループ中に条件内で要素を削除したところ、結果としてアプリケーションはInvalidOperationExceptionをスローして異常終了しました。
ストーリー
変更可能性を考慮せずにFor Eachを使用してコレクションを反復処理した結果、外部データソースがそのコレクションを読み込むと同時に更新することになり、論理計算エラーを引き起こす無限ループに至りました。