C# foreachの使い方を初心者向けに解説|配列・List・Dictionaryのループ処理と注意点
はじめに
C#で配列やList、Dictionaryなどのデータを順番に処理したいときによく使うのがforeach文です。
foreachを使うと、コレクションの中にある要素を1つずつ取り出して処理できます。たとえば、名前の一覧を画面に表示したり、数値の合計を計算したり、Dictionaryのキーと値を一覧表示したりできます。
この記事では、C#初心者向けにforeachの基本構文、配列・List・Dictionaryでの使い方、breakやcontinueとの組み合わせ、よくあるエラーと対処法までわかりやすく解説します。
1. C#のforeachとは?初心者向けに基本を解説
1-1. foreachは配列やListなどの要素を順番に取り出す構文
C#のforeachは、配列やListなどのコレクションに入っている要素を、先頭から順番に取り出して処理するための構文です。
たとえば、次のような名前の配列があるとします。
C#string[] names = { "田中", "佐藤", "鈴木" };
この配列の中身をすべて表示したい場合、foreachを使うと次のように書けます。
C#foreach (string name in names)
{
Console.WriteLine(name);
}
実行結果は次のとおりです。
C#田中
佐藤
鈴木
foreachでは、namesの中にある要素が1つずつnameに代入され、ブロック内の処理が繰り返されます。
1-2. for文との違い:インデックス不要でシンプルに書ける
C#で繰り返し処理を書く方法には、for文もあります。
C#string[] names = { "田中", "佐藤", "鈴木" };
for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(names[i]);
}
for文では、iというインデックス番号を使って配列の要素を取り出します。
一方、foreachではインデックス番号を意識せずに書けます。
C#foreach (string name in names)
{
Console.WriteLine(name);
}
要素を先頭から順番に処理するだけであれば、foreachのほうが読みやすく、初心者にも理解しやすい書き方です。
1-3. foreachが使える主なデータ型
foreachは、複数の要素を持つさまざまなデータ型に対して使えます。
代表的なものは次のとおりです。
C#string[] array = { "A", "B", "C" };
List<string> list = new List<string> { "Apple", "Banana", "Orange" };
Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 }
};
配列、List<T>、Dictionary<TKey, TValue>のように、複数のデータをまとめて扱う型ではforeachがよく使われます。
また、HashSet<T>やQueue<T>、Stack<T>などのコレクションでもforeachを使用できます。
2. C# foreachの基本構文と書き方
2-1. foreach文の基本構文
foreach文の基本構文は次のとおりです。
C#foreach (要素の型 変数名 in コレクション)
{
// 繰り返し実行したい処理
}
たとえば、文字列の配列を処理する場合は次のようになります。
C#string[] fruits = { "Apple", "Banana", "Orange" };
foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}
このコードでは、fruitsの中にある要素が1つずつfruitに入ります。
1回目のループではfruitに"Apple"、2回目では"Banana"、3回目では"Orange"が入ります。
2-2. varを使った書き方
C#では、型を明示せずにvarを使って書くこともできます。
C#var fruits = new List<string> { "Apple", "Banana", "Orange" };
foreach (var fruit in fruits)
{
Console.WriteLine(fruit);
}
varを使うと、C#が右側のコレクションから型を自動的に判断してくれます。
この例では、fruitsはList<string>なので、fruitはstring型として扱われます。
varは便利ですが、初心者のうちは「この変数には何の型が入るのか」を意識しながら使うと理解しやすくなります。
2-3. 型を明示して書く方法
型を明示して書く場合は、次のように記述します。
C#List<int> numbers = new List<int> { 10, 20, 30 };
foreach (int number in numbers)
{
Console.WriteLine(number);
}
この例では、numbersの各要素はint型なので、foreachの変数もint numberと書いています。
型を明示すると、コードを読んだときに「どの型のデータを扱っているのか」がわかりやすくなります。
初心者のうちは、最初は型を明示して書き、慣れてきたらvarを使うとよいでしょう。
2-4. foreach内で実行する処理の書き方
foreachの中では、取り出した要素を使ってさまざまな処理ができます。
たとえば、要素を表示するだけでなく、条件分岐や計算もできます。
C#int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
if (number % 2 == 0)
{
Console.WriteLine(number + "は偶数です");
}
}
実行結果は次のとおりです。
C#2は偶数です
4は偶数です
このように、foreachはif文や計算処理と組み合わせて使うことができます。
3. 配列をforeachでループ処理する方法
3-1. 文字列配列をforeachで表示する例
配列は、同じ型のデータを複数まとめて扱うための基本的なデータ型です。
文字列配列をforeachで処理する例を見てみましょう。
C#string[] colors = { "Red", "Blue", "Green" };
foreach (string color in colors)
{
Console.WriteLine(color);
}
実行結果は次のようになります。
C#Red
Blue
Green
配列の中にある文字列が、先頭から順番に取り出されて表示されます。
3-2. 数値配列をforeachで合計する例
foreachは、数値の合計を計算するときにも便利です。
C#int[] scores = { 80, 90, 75, 60 };
int total = 0;
foreach (int score in scores)
{
total += score;
}
Console.WriteLine("合計点: " + total);
実行結果は次のとおりです。
C#合計点: 305
foreachで1つずつ点数を取り出し、totalに加算しています。
平均点を求めたい場合は、合計を配列の要素数で割ります。
C#double average = (double)total / scores.Length;
Console.WriteLine("平均点: " + average);
3-3. 配列の要素数が変わっても対応しやすい理由
foreachは、配列の要素数を自分で指定する必要がありません。
たとえば、次のように配列の要素が増えても、foreachの書き方は変わりません。
C#string[] animals = { "Dog", "Cat", "Rabbit", "Bird" };
foreach (string animal in animals)
{
Console.WriteLine(animal);
}
for文ではLengthを使って回数を指定しますが、foreachではコレクションの中身を自動的に最後まで処理してくれます。
そのため、要素数が変わる可能性がある場合でも、シンプルで安全に書きやすいのがメリットです。
4. Listをforeachでループ処理する方法
4-1. List<string>をforeachで順番に取り出す
List<T>は、C#でよく使われる可変長のコレクションです。
配列と違い、要素の追加や削除がしやすいという特徴があります。
C#List<string> fruits = new List<string>
{
"Apple",
"Banana",
"Orange"
};
foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}
実行結果は次のようになります。
C#Apple
Banana
Orange
List<string>の各要素が、順番にfruitへ代入されます。
4-2. List<int>を使った計算処理の例
List<int>を使って、数値の合計を求める例です。
C#List<int> prices = new List<int> { 100, 200, 300 };
int total = 0;
foreach (int price in prices)
{
total += price;
}
Console.WriteLine("合計金額: " + total);
実行結果は次のとおりです。
C#合計金額: 600
foreachを使うことで、Listの中にある数値を1つずつ取り出して計算できます。
4-3. Listの要素を検索・条件分岐する方法
Listの中から条件に合う要素だけを処理したい場合は、foreachとif文を組み合わせます。
C#List<int> numbers = new List<int> { 3, 8, 12, 5, 20 };
foreach (int number in numbers)
{
if (number >= 10)
{
Console.WriteLine(number);
}
}
実行結果は次のとおりです。
C#12
20
このコードでは、number >= 10の条件を満たす要素だけを表示しています。
文字列の検索にも使えます。
C#List<string> names = new List<string> { "Tanaka", "Sato", "Suzuki" };
foreach (string name in names)
{
if (name.StartsWith("S"))
{
Console.WriteLine(name);
}
}
実行結果は次のようになります。
C#Sato
Suzuki
4-4. Listの要素をforeach中に削除・追加する際の注意点
foreachでListを処理している最中に、そのListへ要素を追加したり削除したりすると、エラーになることがあります。
次のコードはよくない例です。
C#List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
if (number % 2 == 0)
{
numbers.Remove(number);
}
}
このようにforeachで回している最中にRemoveすると、実行時に例外が発生する可能性があります。
削除したい場合は、RemoveAllを使う方法が簡単です。
C#List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
numbers.RemoveAll(number => number % 2 == 0);
foreach (int number in numbers)
{
Console.WriteLine(number);
}
実行結果は次のとおりです。
C#1
3
5
または、後ろからfor文で削除する方法もあります。
C#List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
for (int i = numbers.Count - 1; i >= 0; i--)
{
if (numbers[i] % 2 == 0)
{
numbers.RemoveAt(i);
}
}
Listの要素を削除・追加したい場合は、foreachではなく、目的に合った別の方法を使うようにしましょう。
5. Dictionaryをforeachでループ処理する方法
5-1. Dictionaryのキーと値をforeachで取り出す
Dictionary<TKey, TValue>は、キーと値をセットで管理するコレクションです。
たとえば、名前と点数を管理する場合に使えます。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 },
{ "鈴木", 75 }
};
このDictionaryをforeachで処理すると、キーと値をまとめて取り出せます。
C#foreach (var score in scores)
{
Console.WriteLine(score.Key + ": " + score.Value);
}
実行結果は次のとおりです。
C#田中: 80
佐藤: 90
鈴木: 75
score.Keyでキー、score.Valueで値を取得できます。
5-2. KeyValuePairを使った基本的な書き方
Dictionaryをforeachで処理するとき、各要素はKeyValuePair<TKey, TValue>として扱われます。
型を明示して書くと、次のようになります。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 },
{ "鈴木", 75 }
};
foreach (KeyValuePair<string, int> item in scores)
{
Console.WriteLine(item.Key + "さんの点数は" + item.Value + "点です");
}
実行結果は次のとおりです。
C#田中さんの点数は80点です
佐藤さんの点数は90点です
鈴木さんの点数は75点です
varを使うと短く書けます。
C#foreach (var item in scores)
{
Console.WriteLine(item.Key + "さんの点数は" + item.Value + "点です");
}
初心者のうちは、Dictionaryのforeachでは「1件分のデータはキーと値のペアになる」と覚えておくとよいでしょう。
5-3. Keysだけをループする方法
Dictionaryのキーだけを取り出したい場合は、Keysプロパティを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 },
{ "鈴木", 75 }
};
foreach (string name in scores.Keys)
{
Console.WriteLine(name);
}
実行結果は次のとおりです。
C#田中
佐藤
鈴木
キーの一覧だけが必要な場合は、scores.Keysをforeachで回すとシンプルです。
5-4. Valuesだけをループする方法
Dictionaryの値だけを取り出したい場合は、Valuesプロパティを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 },
{ "鈴木", 75 }
};
foreach (int score in scores.Values)
{
Console.WriteLine(score);
}
実行結果は次のとおりです。
C#80
90
75
値だけを合計することもできます。
C#int total = 0;
foreach (int score in scores.Values)
{
total += score;
}
Console.WriteLine("合計点: " + total);
Dictionaryでは、キーと値の両方が必要な場合はDictionary本体をforeachし、キーだけならKeys、値だけならValuesを使いましょう。
6. foreachで使える便利な制御文
6-1. breakでループを途中終了する
breakを使うと、foreachのループを途中で終了できます。
C#List<string> names = new List<string> { "田中", "佐藤", "鈴木", "山田" };
foreach (string name in names)
{
if (name == "鈴木")
{
Console.WriteLine("鈴木さんを見つけました");
break;
}
Console.WriteLine(name);
}
このコードでは、nameが"鈴木"になった時点でbreakが実行され、ループが終了します。
実行結果は次のようになります。
C#田中
佐藤
鈴木さんを見つけました
特定の要素が見つかったら、それ以上処理する必要がない場合にbreakは便利です。
6-2. continueで処理をスキップする
continueを使うと、現在のループ処理だけをスキップして、次の要素へ進めます。
C#int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
if (number % 2 == 0)
{
continue;
}
Console.WriteLine(number);
}
実行結果は次のとおりです。
C#1
3
5
このコードでは、偶数の場合にcontinueが実行され、Console.WriteLine(number);がスキップされます。
そのため、奇数だけが表示されます。
6-3. if文と組み合わせて条件に合う要素だけ処理する
foreachはif文と組み合わせることで、条件に合う要素だけを処理できます。
C#List<int> scores = new List<int> { 45, 70, 85, 30, 90 };
foreach (int score in scores)
{
if (score >= 60)
{
Console.WriteLine(score + "点は合格です");
}
}
実行結果は次のとおりです。
C#70点は合格です
85点は合格です
90点は合格です
条件に合うデータだけ表示したい場合、foreachとif文の組み合わせは非常によく使われます。
7. foreachを使うときの注意点
7-1. foreach中にコレクションを変更するとエラーになる
foreachでコレクションを処理している最中に、そのコレクションの要素を追加・削除すると、エラーになることがあります。
C#List<string> names = new List<string> { "田中", "佐藤", "鈴木" };
foreach (string name in names)
{
if (name == "佐藤")
{
names.Remove(name);
}
}
このようなコードは、実行時に次のような例外が発生する可能性があります。
C#InvalidOperationException: Collection was modified; enumeration operation may not execute.
対処法としては、次のような方法があります。
C#names.RemoveAll(name => name == "佐藤");
または、コピーしたListをforeachする方法もあります。
C#foreach (string name in names.ToList())
{
if (name == "佐藤")
{
names.Remove(name);
}
}
ただし、ToList()を使うには次のusingが必要です。
C#using System.Linq;
7-2. foreachでは基本的にインデックス番号を直接扱わない
foreachは、要素を順番に取り出すための構文なので、基本的にインデックス番号を直接扱いません。
C#string[] names = { "田中", "佐藤", "鈴木" };
foreach (string name in names)
{
Console.WriteLine(name);
}
このコードでは、現在何番目の要素を処理しているかはわかりません。
インデックス番号が必要な場合は、for文を使うほうが自然です。
C#for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(i + ": " + names[i]);
}
また、foreachでインデックスを使いたい場合は、自分でカウンター変数を用意します。
C#int index = 0;
foreach (string name in names)
{
Console.WriteLine(index + ": " + name);
index++;
}
7-3. 要素そのものを書き換えたい場合の注意点
foreachで取り出した変数に対して、直接代入することはできません。
次のコードはエラーになります。
C#int[] numbers = { 1, 2, 3 };
foreach (int number in numbers)
{
number = number * 2;
}
foreachの変数numberは読み取り専用のように扱われるため、直接書き換えることはできません。
配列やListの要素そのものを書き換えたい場合は、インデックスを使えるfor文が向いています。
C#int[] numbers = { 1, 2, 3 };
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = numbers[i] * 2;
}
一方、参照型のオブジェクトであれば、オブジェクトのプロパティを変更できる場合があります。
C#class User
{
public string Name { get; set; }
public int Age { get; set; }
}
List<User> users = new List<User>
{
new User { Name = "田中", Age = 20 },
new User { Name = "佐藤", Age = 25 }
};
foreach (User user in users)
{
user.Age += 1;
}
この場合、user自体に別のオブジェクトを代入するのではなく、user.Ageというプロパティを変更しています。
7-4. nullのコレクションをforeachすると例外が発生する
foreachの対象がnullの場合、NullReferenceExceptionが発生します。
C#List<string> names = null;
foreach (string name in names)
{
Console.WriteLine(name);
}
このコードは実行時にエラーになります。
対処法として、foreachの前にnullチェックを行います。
C#List<string> names = null;
if (names != null)
{
foreach (string name in names)
{
Console.WriteLine(name);
}
}
または、空のListで初期化しておく方法もあります。
C#List<string> names = new List<string>();
foreach (string name in names)
{
Console.WriteLine(name);
}
空のListに対してforeachしても、エラーにはならず、単に何も処理されません。
8. foreachとfor文の使い分け
8-1. foreachが向いているケース
foreachが向いているのは、コレクションの要素を先頭から順番に処理したい場合です。
たとえば、次のようなケースです。
C#List<string> names = new List<string> { "田中", "佐藤", "鈴木" };
foreach (string name in names)
{
Console.WriteLine(name);
}
全要素を表示する、合計を計算する、条件に合う要素を探すといった処理では、foreachが読みやすく便利です。
特に、インデックス番号が不要な処理ではforeachを使うとコードがシンプルになります。
8-2. for文が向いているケース
for文が向いているのは、インデックス番号を使いたい場合や、要素を書き換えたい場合です。
たとえば、配列の各要素を2倍にしたい場合は、for文が適しています。
C#int[] numbers = { 1, 2, 3 };
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] *= 2;
}
また、後ろから順番にListの要素を削除したい場合にもfor文が使われます。
C#List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
for (int i = numbers.Count - 1; i >= 0; i--)
{
if (numbers[i] % 2 == 0)
{
numbers.RemoveAt(i);
}
}
8-3. インデックスが必要な場合の書き方
インデックス番号が必要な場合は、基本的にはfor文を使います。
C#string[] names = { "田中", "佐藤", "鈴木" };
for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(i + "番目: " + names[i]);
}
foreachでインデックスを使いたい場合は、カウンター変数を用意します。
C#int index = 0;
foreach (string name in names)
{
Console.WriteLine(index + "番目: " + name);
index++;
}
また、LINQのSelectを使う方法もあります。
C#foreach (var item in names.Select((name, index) => new { name, index }))
{
Console.WriteLine(item.index + "番目: " + item.name);
}
この方法を使うには、次のusingが必要です。
C#using System.Linq;
初心者のうちは、インデックスが必要ならfor文、不要ならforeachと考えるとわかりやすいです。
8-4. 可読性を重視するならforeachが便利
可読性を重視する場合、foreachはとても便利です。
C#foreach (string name in names)
{
Console.WriteLine(name);
}
このコードは、「namesの中のnameを1つずつ処理する」という意味が直感的にわかります。
一方、for文はインデックスの初期化、条件式、増加処理を書く必要があります。
C#for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(names[i]);
}
どちらも正しい書き方ですが、単純に全要素を順番に処理するだけなら、foreachのほうが読みやすいことが多いです。
9. foreachでよくあるエラーと対処法
9-1. Collection was modifiedエラーの原因と解決策
foreachでよくあるエラーの1つが、コレクションを変更したときに発生するエラーです。
C#List<int> numbers = new List<int> { 1, 2, 3, 4 };
foreach (int number in numbers)
{
if (number == 2)
{
numbers.Remove(number);
}
}
このコードでは、foreachでnumbersを処理している最中に、同じnumbersから要素を削除しています。
その結果、次のようなエラーが発生することがあります。
C#Collection was modified; enumeration operation may not execute.
解決策としては、RemoveAllを使います。
C#numbers.RemoveAll(number => number == 2);
または、コピーを作ってループします。
C#foreach (int number in numbers.ToList())
{
if (number == 2)
{
numbers.Remove(number);
}
}
大量のデータを扱う場合は、コピーによるメモリ使用量にも注意しましょう。
9-2. NullReferenceExceptionが出る原因と対処法
foreachの対象がnullの場合、NullReferenceExceptionが発生します。
C#List<string> names = null;
foreach (string name in names)
{
Console.WriteLine(name);
}
対処法は、nullチェックを行うことです。
C#if (names != null)
{
foreach (string name in names)
{
Console.WriteLine(name);
}
}
また、変数を宣言するときに空のListで初期化しておくと安全です。
C#List<string> names = new List<string>();
C#では、nullの可能性があるコレクションをforeachする前に、必ず値が入っているか確認しましょう。
9-3. 型が合わない場合のエラー
foreachで指定した型と、コレクションの要素の型が合わない場合はエラーになります。
たとえば、List<int>の要素をstringとして取り出そうとすると問題になります。
C#List<int> numbers = new List<int> { 1, 2, 3 };
foreach (string number in numbers)
{
Console.WriteLine(number);
}
numbersの要素はint型なので、foreachの変数もintにする必要があります。
C#foreach (int number in numbers)
{
Console.WriteLine(number);
}
型がわかりにくい場合は、varを使うとC#が自動で型を推論してくれます。
C#foreach (var number in numbers)
{
Console.WriteLine(number);
}
ただし、varを使う場合でも、実際にどの型が入っているのかを理解しておくことが大切です。
9-4. Dictionaryのキー・値の取り出し方を間違えた場合
Dictionaryをforeachすると、1つずつ取り出される要素はキーと値のペアです。
次のように、Dictionaryをそのままstringとして受け取ることはできません。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 }
};
foreach (string score in scores)
{
Console.WriteLine(score);
}
正しくは、KeyValuePairまたはvarを使います。
C#foreach (var score in scores)
{
Console.WriteLine(score.Key + ": " + score.Value);
}
キーだけを取り出したい場合は、Keysを使います。
C#foreach (string name in scores.Keys)
{
Console.WriteLine(name);
}
値だけを取り出したい場合は、Valuesを使います。
C#foreach (int point in scores.Values)
{
Console.WriteLine(point);
}
Dictionaryでは、キーと値のどちらを使いたいのかを意識して書くことが大切です。
10. C# foreachの実践サンプルコード
10-1. 配列の全要素を表示するサンプル
まずは、配列の全要素を表示する基本的なサンプルです。
C#using System;
class Program
{
static void Main()
{
string[] languages = { "C#", "Java", "Python", "JavaScript" };
foreach (string language in languages)
{
Console.WriteLine(language);
}
}
}
実行結果は次のとおりです。
C#C#
Java
Python
JavaScript
配列の中にある要素が、先頭から順番に表示されます。
10-2. Listから条件に一致する要素を表示するサンプル
次に、Listの中から条件に一致する要素だけを表示するサンプルです。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> scores = new List<int> { 45, 80, 60, 30, 95 };
foreach (int score in scores)
{
if (score >= 60)
{
Console.WriteLine(score + "点: 合格");
}
}
}
}
実行結果は次のとおりです。
C#80点: 合格
60点: 合格
95点: 合格
if文を使うことで、条件に合う要素だけを処理できます。
10-3. Dictionaryの内容を一覧表示するサンプル
Dictionaryのキーと値を一覧表示するサンプルです。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 80 },
{ "佐藤", 90 },
{ "鈴木", 75 }
};
foreach (var item in scores)
{
Console.WriteLine(item.Key + "さん: " + item.Value + "点");
}
}
}
実行結果は次のとおりです。
C#田中さん: 80点
佐藤さん: 90点
鈴木さん: 75点
Dictionaryでは、item.Keyでキー、item.Valueで値を取得します。
10-4. break・continueを使ったサンプル
最後に、breakとcontinueを使ったサンプルです。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
foreach (int number in numbers)
{
if (number == 2)
{
continue;
}
if (number == 5)
{
break;
}
Console.WriteLine(number);
}
}
}
実行結果は次のとおりです。
C#1
3
4
numberが2のときはcontinueで表示処理をスキップします。
numberが5のときはbreakでループを終了します。
このように、breakとcontinueを使うと、ループの流れを細かく制御できます。
11. C# foreachに関するよくある質問
11-1. foreachでインデックスを取得できますか?
foreach自体には、インデックス番号を自動で取得する機能はありません。
インデックスが必要な場合は、カウンター変数を用意します。
C#string[] names = { "田中", "佐藤", "鈴木" };
int index = 0;
foreach (string name in names)
{
Console.WriteLine(index + ": " + name);
index++;
}
実行結果は次のとおりです。
C#0: 田中
1: 佐藤
2: 鈴木
よりシンプルにインデックスを扱いたい場合は、for文を使うのがおすすめです。
C#for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(i + ": " + names[i]);
}
11-2. foreach中にListの要素を削除できますか?
基本的には、foreach中に同じListの要素を削除するのは避けるべきです。
次のようなコードはエラーの原因になります。
C#foreach (int number in numbers)
{
if (number % 2 == 0)
{
numbers.Remove(number);
}
}
削除したい場合は、RemoveAllを使うと安全です。
C#numbers.RemoveAll(number => number % 2 == 0);
または、後ろからfor文で削除します。
C#for (int i = numbers.Count - 1; i >= 0; i--)
{
if (numbers[i] % 2 == 0)
{
numbers.RemoveAt(i);
}
}
「表示するだけ」「条件に合うものを探すだけ」ならforeach、「要素を削除・変更する」ならfor文や専用メソッドを検討しましょう。
11-3. foreachとLINQはどう使い分けますか?
foreachは、要素を1つずつ取り出して処理を実行したいときに使います。
C#foreach (int number in numbers)
{
Console.WriteLine(number);
}
一方、LINQは、データの抽出、変換、並び替え、集計などを簡潔に書きたいときに便利です。
C#var evenNumbers = numbers.Where(number => number % 2 == 0);
条件に合う要素を取得するだけならLINQ、取得した要素に対して複数の処理を行うならforeachがわかりやすい場合があります。
たとえば、偶数だけを表示する場合は、LINQとforeachを組み合わせることもできます。
C#foreach (int number in numbers.Where(number => number % 2 == 0))
{
Console.WriteLine(number);
}
初心者のうちは、まずforeachで処理の流れを理解し、慣れてきたらLINQを使うとよいでしょう。
11-4. UnityのC#でもforeachは使えますか?
はい、UnityのC#でもforeachは使えます。
たとえば、GameObjectのListを順番に処理する場合に使えます。
C#using System.Collections.Generic;
using UnityEngine;
public class Sample : MonoBehaviour
{
public List<GameObject> enemies;
void Start()
{
foreach (GameObject enemy in enemies)
{
Debug.Log(enemy.name);
}
}
}
Unityでも、配列やListを順番に処理したい場面は多いため、foreachはよく使われます。
ただし、Unityのパフォーマンスが重要な処理、特に毎フレーム実行されるUpdate内で大量のデータを処理する場合は、処理コストにも注意が必要です。
通常の規模であればforeachは問題なく使えますが、大量のオブジェクトを頻繁に処理する場合は、for文やデータ構造の見直しも検討しましょう。
まとめ
C#のforeachは、配列、List、Dictionaryなどのコレクションを順番に処理するための便利な構文です。
基本構文は次の形です。
C#foreach (要素の型 変数名 in コレクション)
{
// 処理
}
配列では要素を1つずつ取り出して表示したり、数値の合計を計算したりできます。
C#int[] numbers = { 1, 2, 3 };
foreach (int number in numbers)
{
Console.WriteLine(number);
}
Listでも同じように使えます。
C#List<string> names = new List<string> { "田中", "佐藤", "鈴木" };
foreach (string name in names)
{
Console.WriteLine(name);
}
Dictionaryでは、キーと値をセットで取り出せます。
C#foreach (var item in scores)
{
Console.WriteLine(item.Key + ": " + item.Value);
}
foreachは、インデックス番号が不要なループ処理に向いています。
一方で、要素の削除・追加、インデックスを使った処理、要素そのものの書き換えには注意が必要です。
使い分けの目安は次のとおりです。
C#// 全要素を順番に処理するならforeach
foreach (var item in items)
{
Console.WriteLine(item);
}
// インデックスが必要ならfor
for (int i = 0; i < items.Count; i++)
{
Console.WriteLine(items[i]);
}
C#初心者の方は、まず配列やListを使った簡単なforeachから練習してみましょう。慣れてくると、Dictionaryや条件分岐、break・continueとの組み合わせも自然に使えるようになります。

