こんにちは!エンジニアリングの世界へようこそ。
Excelのマクロ記録や、なんとなく動くコードをコピペする日々から、「自分の手でしっかりとロジックを組み立てたい!」と一歩を踏み出したあなたへ。
今回は、プログラムの基本中の基本でありながら、プロの現場でもパフォーマンスやバグの温床になりやすい「ループ処理(繰り返し)」についてお話しします。
特にVB.NETにおける `For` 文と `For Each` 文の違い、そしてコレクションを操作する際の「絶対にやってはいけない罠」について、実務の現場でスッと使える知見を交えて解説していきましょう。
ここをクリアすれば、あなたのVB.NETの基礎力は確実に一段階アップします。さあ、一緒に扉を開けましょう!
—
1. そもそも「ループ処理」ってなに?なぜ必要なの?
プログラムを書いていると、「同じ処理を100回繰り返したい」「リストに入っている名前を上から順に全部チェックしたい」という場面に必ず直面します。
もし、これを人間が手作業でやろうとしたらどうでしょう?
.net
Console.WriteLine(“こんにちは!”)
Console.WriteLine(“こんにちは!”)
Console.WriteLine(“こんにちは!”)
‘ …これを100回? 手が疲れますよね。
コンピュータの最大の強さは「疲れないこと」「高速であること」です。この繰り返しをスマートに命令するのが「ループ処理(反復構文)」です。
VB.NETで最もよく使われるのが、回数を指定する `For` 文 と、リストの中身を順番になめる `For Each` 文 です。この2つの違いと正しい使い分けをマスターしていきましょう。
—
2. 回数を数えて実行する:`For` 文の基本
`For` 文は、「何回繰り返すか」が決まっているときに使います。「1から10まで数えながら処理する」といった場面の王様です。
基本のコード例
.net
‘ 1から5まで数え上げてメッセージを表示する
For i As Integer = 1 To 5
Console.WriteLine(i & “回目のループです。”)
Next
コードの解説
- `For i As Integer = 1 To 5`:
「`i` というカウンター変数を用意し、1からスタートして、5になるまでループを回します」という宣言です。
- `Next`:
「ここまで来たら、`i` を1つ増やして(インクリメントして)`For` の行に戻りなさい」という合図です。
💡 先輩エンジニアからのワンポイントアドバイス
カウンター変数(上記の `i`)は、「今、何回目の処理をしているか」を数字で把握したいときに絶大な効果を発揮します。例えば、配列の何番目のデータかを指定したいときは、迷わずこの `For` 文を使いましょう。
—
3. リストを優しく舐め尽くす:`For Each` 文の基本
一方、`For Each` 文は、配列やリスト(コレクション)の中にある要素を、先頭から順番に取り出して処理したいときに使います。数を数える必要すらありません。
基本のコード例
.net
‘ 果物の名前が入ったリスト(配列)を準備する
Dim fruits As String() = {“りんご”, “みかん”, “バナナ”}
‘ リストの中身を一つずつ取り出して処理する
For Each fruit As String in fruits
Console.WriteLine(“好きな果物は ” & fruit & ” です!”)
Next
コードの解説
- `For Each fruit As String In fruits`:
「`fruits` というリストから、中身を1つずつ取り出して一時的に `fruit` という変数に入れなさい」という意味です。
- 何番目か(インデックス)を自分で管理する必要が一切ないため、コードが非常にシンプルで読みやすくなります。
💡 先輩エンジニアからのワンポイントアドバイス
実務では、配列や `List(Of T)` のすべての要素をただ順番に処理したい場合、基本的には `For Each` を選ぶのが正解です。なぜなら、「数え間違えて配列の範囲外エラー(IndexOutOfRange)を起こす」という初学者のミスを構造的に防いでくれるからです。
—
4. 【要注意】現場で一番多いバグ!「ループ中の要素削除」の罠
さて、ここからが少し応用、かつ実務で一番ハマりやすいポイントです。
「ループでリストを回しながら、そのリストの要素を消す」という操作をしたことはありませんか?
実はこれ、`For Each` 文でやると絶対にエラー(例外)になります。
❌ やってはいけない例(エラーになるコード)
.net
Dim numbers As New List(Of Integer) From {1, 2, 3, 4, 5}
‘ 【注意】For Eachで回しながら要素を消そうとすると…
For Each num As Integer In numbers
If num = 3 Then
numbers.Remove(num) ‘ ← ここで例外(InvalidOperationException)が発生!
If
Next
なぜエラーになるのか?
`For Each` は、内部的に「今、リストのどこを見ているか」というイテレーター(列挙子)の安全な状態を監視しています。その最中にリストの構造(要素数)が勝手に書き換わると、「道案内の地図が書き換えられた!」とパニックを起こし、安全のためにプログラムを強制終了させるのです。
⭕ 正しい回避法:後ろから数えて消す(`For` 文を使う)
もしループ中に要素を削除する必要がある場合は、`For Each` ではなく、`For` 文を使って「後ろから前へ(逆順)」処理します。
.net
Dim numbers As New List(Of Integer) From {1, 2, 3, 4, 5}
‘ リストの最後尾から先頭に向かってループを回す
For i As Integer = numbers.Count – 1 To 0 Step -1
If numbers(i) = 3 Then
numbers.RemoveAt(i) ‘ 後ろから消すので、前方のインデックスはズレない!
End If
Next
- `Step -1`: カウンターを「減らす」方向(逆順)に動かす魔法の言葉です。
- 後ろから消していけば、今から処理しようとする前方の要素のインデックス番号がズレないため、安全に要素を削除できます。
—
5. まとめ:賢いエンジニアの使い分けルール
最後に、今日から使える使い分けの基準をまとめます。
1. インデックス(何番目か)の数字が必要なとき、または逆順で処理したいとき
👉 `For` 文 を使う
2. リストの要素をただ順番に読み込んで処理したいだけの場合
👉 `For Each` 文 を使う(コードがスッキリして安全!)
3. ループ中に要素を削除・追加したい場合
👉 `For Each` は使わず、逆順の `For` 文か、`.RemoveAll()` などのLINQメソッドを検討する
ここをクリアすれば、ループ処理で路頭に迷うことはもうありません。
基礎をしっかりと固めて、メンテナンス性の高い美しいVB.NETコードを書いていきましょう。あなたのプログラミングライフを応援しています!
