前回は、演算子の基本について学びました。
今回は、配列・List・Dictionaryという代表的なコレクションの違いと使い方を解説します。
C#のコレクションとは?
コレクションとは、複数の値をまとめて管理することができる仕組みです。
C#には様々なコレクションが用意されていますが、まずは次の3つを押さえれば十分です。
- 配列(Array):決まった数のデータを順番に管理したいときに使う
- リスト(List<T>):後からデータを追加・削除したいときに使う。実務で最もよく使われる
- ディクショナリ(Dictionary<TKey, TValue>):名前やIDなど「キー」と値をセットで管理したいときに使う
本記事では、これら3つのコレクションの使い方や違いを解説していきます。
配列(Array)の使い方
配列は、同じ型の複数の値をまとめて管理できる構造で、C#では最もシンプルなコレクションです。
配列の宣言と初期化
配列の宣言には複数の書き方があります。どの方法でも、結果として同じ配列が作成されます。
var fruits1 = new string[] { "Apple", "Banana", "Cherry" }; // varを使う場合はnewが必要
string[] fruits2 = { "Apple", "Banana", "Cherry" }; // varを使わない場合はnewを省略できる
string[] fruits3 = ["Apple", "Banana", "Cherry"]; // C# 12以降のコレクション式
どの書き方でも問題ありませんが、C# 12以降であればコレクション式を使うのがいいでしょう。
配列の要素の取り出し方
配列の各要素には0から始める番号(=インデックス)が振られています。
以下のようにインデックスを指定することで、配列内の特定の要素を取り出すことができます。
var fruits = new string[] { "Apple", "Banana", "Cherry" };
Console.WriteLine(fruits[0]); // 出力:Apple
Console.WriteLine(fruits[2]); // 出力:Cherry
存在しないインデックスを指定すると、実行時にIndexOutOfRangeException
というエラーが発生するので注意してください。
var fruits = new string[] { "Apple", "Banana", "Cherry" };
Console.WriteLine(fruits[3]); // エラー:インデックスが範囲外
配列を扱う際は、インデックスが配列の長さ内に収まっていることを常に意識しましょう。
配列をループで処理する
配列の全要素を繰り返し処理するには、foreach
を使うのが便利です。
以下は配列内の全要素をコンソールに出力する例です。
var fruits = new string[] { "Apple", "Banana", "Cherry" };
// 配列 fruits の全要素を順番に取り出して処理する
foreach (var fruit in fruits)
{
// 現在の要素(fruit)をコンソールに表示する
Console.WriteLine(fruit);
}
実務で配列を使う主なケース
実務では次に紹介するListよりも使う場面は限られますが、以下のようなケースで使われます。
- パフォーマンス重視の処理(例:画像処理、音声処理、ゲームロジックなど)
- 要素数が明確で変化しない場面
- メモリ消費を最小限にしたいとき
List<T>(リスト)の使い方とよく使う機能
Listは、C#で最もよく使われるコレクションです。
配列と違って、要素の追加や削除などをとても簡単に行うことができます。
Listの宣言と初期化
Listは、以下のようにして宣言・初期化します。
var fruits1 = new List<string> { "Apple", "Banana", "Cherry" };
List<string> fruits2 = new() { "Apple", "Banana", "Cherry" }; // C# 9以降の省略形
List<string> fruits3 = ["Apple", "Banana", "Cherry"]; // C# 12以降のコレクション式
// 初期値を指定しない場合は空のリストが生成される
var fruits4 = new List<string>();
Listに入れたいデータの型(T
)を指定するのがポイントで、例えば List<string>
なら「文字列だけのリスト」、List<int>
なら「整数だけのリスト」になります。
T
は「Type(型)」の頭文字で、Listにどんな型のデータを入れたいかを指定します。
List<T>のように、様々な型に対応できるような仕組みを「ジェネリック」と呼びます。
Listの基本操作
Listでは要素の追加や削除、取得、ループ処理が簡単に行えます。
配列と同様に、インデックス(0から始まる番号)やforeachを使うこともできます。
// リストの初期化(空のリストを作成)
var numbers = new List<int>();
// 要素の追加
numbers.Add(10);
numbers.Add(20);
numbers.Add(30);
// インデックス1の要素を取得
Console.WriteLine(numbers[1]); // 出力: 20
// リストの要素数を取得
Console.WriteLine(numbers.Count); // 出力: 3
// 要素の削除(値が一致する最初の要素を削除)
numbers.Remove(20);
// 全要素を順に取り出して表示
foreach (int num in numbers)
{
Console.WriteLine(num);
}
// 出力結果:
// 10
// 30
Listのよく使う機能
Listには、要素の追加・削除以外にも挿入や検索などを行う多様な機能(メソッド)が用意されています。
Add(value)
:末尾に値を追加Insert(index, value)
:指定位置に値を挿入Remove(value)
:値が一致する最初の要素を削除RemoveAt(index)
:指定インデックスの要素を削除Clear()
:すべての要素を削除Contains(value)
:指定の値が含まれているかを判定IndexOf(value)
:値が最初に見つかったインデックスを返すCount
:現在の要素数を取得
特にAdd
やContains
、Count
は実務でも頻繁に使うことになるでしょう。
さらに次回で紹介するLINQを使えば、集計や並べ替えなどより多様な処理を行うことができます。
Listと配列の違い・使い分け
Listと配列の最も大きな違いは「要素の追加・削除ができるかどうか」です。
- List:後から自由に要素を追加・削除できる
- 配列:サイズが固定で、後から要素を増減できない
実務では基本的にListで問題ないと思いますが、下記のような場合には配列が適しています。
- 「最初から要素数が決まっていて、今後も増減しない」
- 「できるだけ処理速度やメモリ効率を重視したい」
用途やパフォーマンス要件に応じて使い分けるようにしましょう。
Dictionary<TKey, TValue>(ディクショナリ)の基礎
Dictionary
は、キーと値をセットで管理するコレクションです。
辞書・連想配列・マップとも呼ばれ、「名前(キー)」と「年齢(値)」のように、関連するデータをペアで扱いたいときに使われます。
Listと比べると使用頻度は落ちますが、大事な概念なので押さえておきましょう。
Dictionaryの宣言と初期化
Dictionaryは、以下のように宣言・初期化します。
var ages1 = new Dictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 },
{ "Charlie", 35 }
};
// C# 9以降はnewの後ろの型名を省略可
Dictionary<string, int> ages2 = new()
{
{ "Alice", 30 },
{ "Bob", 25 },
{ "Charlie", 35 }
};
// 初期値を指定しない場合は空のディクショナリが生成される
var ages3 = new Dictionary<string, int>();
Listと同様にジェネリックの仕組みが使われており、宣言時に<キーの型, 値の型>を指定します。
Dictionary<string, int>であれば、キーが文字列型で値が数値型となります。
Dictionaryの使い方
以下は要素(キー・値)の追加や削除を行い、中身を表示する例です。
// Dictionaryの宣言と初期化
var ages = new Dictionary<string, int>();
// キーと値を追加
ages.Add("Alice", 30);
ages.Add("Bob", 25);
ages.Add("Charlie", 35);
// キーから対応する値を取り出す
Console.WriteLine(ages["Alice"]); // 出力: 30
// キーから対応する要素を削除
ages.Remove("Bob");
// 全要素を順に取り出して表示
foreach (var pair in ages)
{
Console.WriteLine($"{pair.Key} は {pair.Value} 歳です");
}
// 出力結果:
// Alice は 30 歳です
// Charlie は 35 歳です
値の安全な取得(TryGetValue)
上の例では、ages["Alice"]
のようにキーを直接指定して値を取得しましたが、もしキーが存在しない場合はKeyNotFoundException
というエラーが発生します。
キーが存在しない場合でもエラーを発生させたくない場合は、TryGetValue
を使うと安全です。
// 対象のキーがディクショナリに存在するかチェック
if (ages.TryGetValue("Charlie", out int age))
{
// 対象のキーが存在した場合(ageには対象要素の値が入る)
Console.WriteLine($"Charlieは{age}歳です");
}
else
{
// 対象のキーが存在しない場合
Console.WriteLine("Charlieは登録されていません");
}
値の安全な追加(TryAdd)
上の例では、Add
メソッドを使って要素を追加しましたが、もしキーが既に存在する場合はArgumentException
というエラーが発生します。
エラーを発生させたくない場合は、TryAdd
を使うと安全です。(.NET 5以降で使用可能)
if (ages.TryAdd("Alice", 30))
{
// 対象のキーが存在しなかった場合(追加成功)
Console.WriteLine("要素が追加されました");
}
else
{
// 対象のキーが存在した場合(追加されない)
Console.WriteLine("要素は追加されませんでした");
}
なお以下のように直接キーを指定した場合は、キーが存在しなければ新規追加、存在すれば値が上書きされるので注意してください。
ages["Alice"] = 30; // 新規追加
ages["Alice"] = 35; // 上書き(値が30 → 35になる)
Console.WriteLine(ages["Alice"]); // 出力: 35
まとめ
最後に、今回説明した3つのコレクションの特徴と用途を整理します。
コレクション | 管理方法 | 要素数の変更 | 使いどころ |
---|---|---|---|
配列(Array) | 番号(インデックス)で管理 | 不可 | 要素数が決まっていて変化しない場合 |
List<T>(リスト) | 番号(インデックス)で管理 | 可能 | 要素の追加・削除を柔軟に行いたい場合 |
Dictionary<TKey, TValue> | キーで管理 | 可能 | 「ID」や「名前」などキーと値の対応が必要な場合 |
まずはListの使い方をしっかり身につけ、途や状況に応じて配列やDictionaryも使い分けられるようにしていきましょう。
次回は「LINQの基本」について解説します。
LINQはコレクションを効率よく操作する際に非常によく使われる機能なので、今回の内容とセットで学んでいきましょう。
参考ドキュメント



