C# Dictionaryの使い方を初心者向けに解説|追加・取得・検索・削除までわかる完全ガイド
はじめに
C#でデータを扱うときによく使われるコレクションのひとつがDictionaryです。Dictionaryは「キー」と「値」をセットで管理できる仕組みで、商品コードから商品名を取得したり、ユーザーIDからユーザー情報を取り出したり、単語の出現回数を数えたりするときに便利です。
C# Dictionaryを使えるようになると、「特定の名前に対応する点数を取り出す」「IDに対応するデータを探す」「同じキーがあるか確認してから追加する」といった処理を簡単に書けるようになります。
この記事では、C# Dictionaryの基本から、追加・取得・検索・更新・削除・ループ・並び替え・よくあるエラーまで、初心者向けにわかりやすく解説します。
1. C#のDictionaryとは?キーと値でデータを管理する基本
1-1. Dictionaryの役割を初心者向けにわかりやすく解説
C#のDictionaryは、キーを使って値を管理するコレクションです。
たとえば、次のように「商品コード」と「商品名」を対応させたい場合に使えます。
C#Dictionary<string, string> products = new Dictionary<string, string>();
products.Add("A001", "ノートパソコン");
products.Add("A002", "マウス");
products.Add("A003", "キーボード");
この場合、"A001"がキー、"ノートパソコン"が値です。
キーを指定すれば、対応する値をすぐに取得できます。
C#Console.WriteLine(products["A001"]);
実行結果は次のようになります。
C#ノートパソコン
このように、C# Dictionaryは「何かを目印にしてデータを取り出したい」ときに便利です。
1-2. キーと値の関係とは
Dictionaryでは、データを「キー」と「値」の組み合わせで管理します。
C#キー → 値
たとえば、学生番号と名前を管理する場合は次のように考えられます。
C#1001 → 田中
1002 → 佐藤
1003 → 鈴木
C#で書くと次のようになります。
C#Dictionary<int, string> students = new Dictionary<int, string>();
students.Add(1001, "田中");
students.Add(1002, "佐藤");
students.Add(1003, "鈴木");
キーには重複しない値を使います。同じキーを複数登録することはできません。
一方、値は重複しても問題ありません。
C#students.Add(1004, "田中");
このように、別の学生番号に同じ名前を登録することはできます。
1-3. 配列・List・Dictionaryの違い
C#には、複数のデータを扱うための仕組みとして、配列、List、Dictionaryなどがあります。
配列は、要素数が決まっているデータを順番に管理するのに向いています。
C#string[] names = { "田中", "佐藤", "鈴木" };
Console.WriteLine(names[0]);
Listは、要素を追加・削除しながら順番に管理するのに向いています。
C#List<string> names = new List<string>();
names.Add("田中");
names.Add("佐藤");
names.Add("鈴木");
Dictionaryは、番号や名前などのキーを使って値を管理するのに向いています。
C#Dictionary<int, string> students = new Dictionary<int, string>();
students.Add(1001, "田中");
students.Add(1002, "佐藤");
使い分けの目安は次のとおりです。
| 種類 | 特徴 | 向いている場面 |
|---|---|---|
| 配列 | 要素数が固定 | 決まった数のデータを扱う |
| List | 順番にデータを管理 | 追加・削除しながら一覧を扱う |
| Dictionary | キーと値で管理 | IDやコードから値を探す |
「何番目のデータか」で扱うなら配列やList、「このキーに対応するデータは何か」で扱うならDictionaryが便利です。
1-4. Dictionaryを使うメリットと向いている場面
Dictionaryの大きなメリットは、キーを指定して値をすばやく取得できることです。
たとえば、商品コードから商品名を取得したい場合、Listだと1件ずつ探す必要があります。
C#List<string> productCodes = new List<string> { "A001", "A002", "A003" };
しかしDictionaryなら、キーを指定するだけで目的の値を取得できます。
C#Dictionary<string, string> products = new Dictionary<string, string>
{
{ "A001", "ノートパソコン" },
{ "A002", "マウス" },
{ "A003", "キーボード" }
};
Console.WriteLine(products["A002"]);
実行結果は次のとおりです。
C#マウス
Dictionaryは、次のような場面に向いています。
| 場面 | キー | 値 |
|---|---|---|
| 商品管理 | 商品コード | 商品名 |
| ユーザー管理 | ユーザーID | ユーザー情報 |
| 設定管理 | 設定名 | 設定値 |
| 点数管理 | 名前 | 点数 |
| カウント処理 | 単語 | 出現回数 |
特に「一意のIDやコードを使ってデータを取り出す処理」では、Dictionaryがよく使われます。
1-5. Dictionaryを使わないほうがよいケース
Dictionaryは便利ですが、すべての場面で最適とは限りません。
次のような場合は、Dictionary以外を使ったほうがよいことがあります。
まず、順番が重要なデータにはDictionaryはあまり向いていません。Dictionaryはキーと値の対応関係を管理するためのものであり、並び順を目的に使うコレクションではありません。
C#List<string> steps = new List<string>
{
"ログインする",
"商品を選ぶ",
"購入する"
};
このように、手順やランキングなど順番そのものが重要な場合はListがわかりやすいです。
また、キーが必要ない場合もDictionaryを使う必要はありません。
C#List<string> fruits = new List<string>
{
"りんご",
"みかん",
"バナナ"
};
単純な一覧であれば、Listで十分です。
さらに、キーに重複が必要な場合もDictionaryは不向きです。Dictionaryのキーは一意である必要があります。
2. C# Dictionaryの基本構文と宣言方法
2-1. Dictionaryの基本的な書き方
C# Dictionaryの基本構文は次のとおりです。
C#Dictionary<キーの型, 値の型> 変数名 = new Dictionary<キーの型, 値の型>();
たとえば、キーをstring、値をintにする場合は次のように書きます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
このDictionaryでは、名前をキーにして点数を管理できます。
C#scores.Add("田中", 90);
scores.Add("佐藤", 85);
scores.Add("鈴木", 78);
値を取得するときは、キーを指定します。
C#Console.WriteLine(scores["田中"]);
実行結果は次のようになります。
C#90
2-2. using System.Collections.Genericが必要な理由
Dictionaryを使うには、通常はファイルの先頭に次のusingを記述します。
C#using System.Collections.Generic;
DictionaryはSystem.Collections.Generic名前空間に含まれているためです。
基本的なコード全体は次のようになります。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("佐藤", 85);
Console.WriteLine(scores["田中"]);
}
}
最近のC#プロジェクトでは、テンプレートによっては暗黙的にusingが有効になっている場合もあります。ただし、初心者のうちはusing System.Collections.Generic;が必要だと覚えておくと理解しやすいです。
2-3. Dictionary<TKey, TValue>の意味
C#のDictionaryは、正式には次のような形で表されます。
C#Dictionary<TKey, TValue>
TKeyはキーの型、TValueは値の型を意味します。
たとえば次のDictionaryでは、TKeyがstring、TValueがintです。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
これは「文字列のキーに対して、整数の値を持つDictionary」という意味です。
別の例として、キーがint、値がstringの場合は次のようになります。
C#Dictionary<int, string> users = new Dictionary<int, string>();
これは「整数のキーに対して、文字列の値を持つDictionary」です。
2-4. string・intなどよく使う型の組み合わせ例
C# Dictionaryでは、キーと値にさまざまな型を指定できます。
よく使う組み合わせは次のとおりです。
C#Dictionary<string, string> settings = new Dictionary<string, string>();
Dictionary<string, int> scores = new Dictionary<string, int>();
Dictionary<int, string> users = new Dictionary<int, string>();
Dictionary<int, bool> flags = new Dictionary<int, bool>();
具体例を見てみましょう。
C#Dictionary<string, string> settings = new Dictionary<string, string>();
settings.Add("Theme", "Dark");
settings.Add("Language", "Japanese");
この例では、設定名をキーにして設定値を管理しています。
C#Dictionary<string, int> stock = new Dictionary<string, int>();
stock.Add("Apple", 10);
stock.Add("Orange", 5);
この例では、商品名をキーにして在庫数を管理しています。
2-5. varを使ったDictionaryの宣言方法
C#では、varを使ってDictionaryを宣言することもできます。
C#var scores = new Dictionary<string, int>();
これは次のコードと同じ意味です。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
varを使うとコードを短く書けます。ただし、型がわかりにくくなる場合もあるため、初心者のうちは明示的に型を書いたほうが理解しやすいです。
初期化と同時に値を入れる場合は、次のように書けます。
C#var scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
型が明らかな場面では、varを使うと読みやすくなります。
3. Dictionaryに要素を追加する方法
3-1. Addメソッドで要素を追加する
Dictionaryに要素を追加する基本的な方法は、Addメソッドを使うことです。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("佐藤", 85);
scores.Add("鈴木", 78);
Addメソッドの書き方は次のとおりです。
C#dictionary.Add(キー, 値);
値を確認してみます。
C#Console.WriteLine(scores["佐藤"]);
実行結果は次のようになります。
C#85
Addは「新しいキーと値を追加する」ためのメソッドです。
3-2. インデクサーを使って要素を追加する
Dictionaryでは、インデクサーを使って要素を追加することもできます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores["田中"] = 90;
scores["佐藤"] = 85;
このように、キーを指定して値を代入できます。
C#Console.WriteLine(scores["田中"]);
実行結果は次のとおりです。
C#90
インデクサーを使う場合、キーが存在しなければ追加されます。キーがすでに存在する場合は、値が上書きされます。
3-3. 初期化と同時に要素を追加する
Dictionaryは、作成と同時に要素を追加できます。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
この書き方は、最初から入れるデータが決まっている場合に便利です。
インデクサー形式で初期化することもできます。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
["田中"] = 90,
["佐藤"] = 85,
["鈴木"] = 78
};
どちらもDictionaryを初期化するときによく使われます。
3-4. Addとインデクサーの違い
Addとインデクサーは、どちらもDictionaryに要素を追加できますが、動作が異なります。
Addは、同じキーがすでに存在するとエラーになります。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("田中", 95); // エラー
一方、インデクサーは同じキーがある場合、値を上書きします。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores["田中"] = 90;
scores["田中"] = 95;
Console.WriteLine(scores["田中"]);
実行結果は次のようになります。
C#95
使い分けの目安は次のとおりです。
| 方法 | キーがない場合 | キーがある場合 |
|---|---|---|
| Add | 追加する | エラー |
| インデクサー | 追加する | 上書きする |
「重複をエラーとして検出したい」ならAdd、「なければ追加、あれば更新したい」ならインデクサーが便利です。
3-5. 同じキーを追加したときに起こるエラー
Dictionaryでは、同じキーを複数追加できません。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("田中", 95);
このコードを実行すると、同じキーを追加しようとしてエラーになります。
エラーを防ぐには、追加前にContainsKeyで確認します。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
if (!scores.ContainsKey("田中"))
{
scores.Add("田中", 90);
}
または、TryAddを使う方法もあります。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
bool added = scores.TryAdd("田中", 90);
if (added)
{
Console.WriteLine("追加しました");
}
else
{
Console.WriteLine("すでにキーが存在します");
}
TryAddは、追加できた場合にtrue、すでにキーがある場合にfalseを返します。
4. Dictionaryから値を取得する方法
4-1. キーを指定して値を取得する
Dictionaryから値を取得する基本は、キーを指定する方法です。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
int score = scores["田中"];
Console.WriteLine(score);
実行結果は次のようになります。
C#90
この方法はシンプルですが、指定したキーが存在しない場合はエラーになります。
4-2. TryGetValueで安全に値を取得する
存在しないキーを指定する可能性がある場合は、TryGetValueを使うのがおすすめです。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
if (scores.TryGetValue("鈴木", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("指定したキーは存在しません");
}
実行結果は次のようになります。
C#指定したキーは存在しません
TryGetValueは、キーが存在する場合にtrueを返し、値をout変数に入れます。キーが存在しない場合はfalseを返します。
初心者がDictionaryから値を取得するときは、まずTryGetValueを覚えると安全です。
4-3. 存在しないキーを指定したときのエラー
次のコードでは、存在しないキーを指定しています。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
Console.WriteLine(scores["鈴木"]);
"鈴木"というキーは登録されていないため、実行時にKeyNotFoundExceptionが発生します。
Dictionaryでは、インデクサーで値を取得する場合、キーが存在することが前提になります。
4-4. KeyNotFoundExceptionを防ぐ方法
KeyNotFoundExceptionを防ぐには、値を取得する前にキーの存在を確認します。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
if (scores.ContainsKey("鈴木"))
{
Console.WriteLine(scores["鈴木"]);
}
else
{
Console.WriteLine("キーが見つかりません");
}
ただし、値の取得まで行う場合はTryGetValueのほうが効率的で読みやすいです。
C#if (scores.TryGetValue("鈴木", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("キーが見つかりません");
}
キーの確認と値の取得を同時にできるため、実務でもよく使われます。
4-5. 初心者が覚えるべき取得方法の使い分け
Dictionaryの値を取得する方法は、状況によって使い分けます。
キーが必ず存在するとわかっている場合は、インデクサーで取得しても問題ありません。
C#int score = scores["田中"];
キーが存在するかわからない場合は、TryGetValueを使いましょう。
C#if (scores.TryGetValue("田中", out int score))
{
Console.WriteLine(score);
}
初心者向けの使い分けは次のとおりです。
| 状況 | おすすめ |
|---|---|
| キーが必ず存在する | インデクサー |
| キーが存在するかわからない | TryGetValue |
| キーの有無だけ確認したい | ContainsKey |
迷った場合は、TryGetValueを使うと安全です。
5. Dictionaryでキーや値を検索する方法
5-1. ContainsKeyでキーの存在を確認する
Dictionaryに指定したキーが存在するか確認するには、ContainsKeyを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
if (scores.ContainsKey("田中"))
{
Console.WriteLine("田中さんの点数があります");
}
実行結果は次のようになります。
C#田中さんの点数があります
ContainsKeyは、キーが存在すればtrue、存在しなければfalseを返します。
5-2. ContainsValueで値の存在を確認する
値が存在するか確認したい場合は、ContainsValueを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
if (scores.ContainsValue(90))
{
Console.WriteLine("90点の人がいます");
}
実行結果は次のようになります。
C#90点の人がいます
ただし、Dictionaryはキーで探すことを得意とするコレクションです。値での検索は、キー検索に比べると効率が落ちる場合があります。
5-3. TryGetValueとContainsKeyの違い
ContainsKeyは、キーが存在するかどうかだけを確認します。
C#if (scores.ContainsKey("田中"))
{
Console.WriteLine("キーがあります");
}
TryGetValueは、キーの存在確認と値の取得を同時に行います。
C#if (scores.TryGetValue("田中", out int score))
{
Console.WriteLine(score);
}
値を取得したい場合は、TryGetValueを使うほうが便利です。
C#if (scores.ContainsKey("田中"))
{
int score = scores["田中"];
Console.WriteLine(score);
}
このようにContainsKeyで確認してからインデクサーで取得するより、TryGetValueのほうが簡潔に書けます。
5-4. LINQを使って条件に合う要素を検索する
Dictionaryの中から条件に合う要素を探したい場合は、LINQを使うこともできます。
LINQを使う場合は、次のusingを追加します。
C#using System.Linq;
たとえば、80点以上のデータだけを取得する場合は次のように書きます。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
var highScores = scores.Where(item => item.Value >= 80);
foreach (var item in highScores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
}
}
実行結果は次のようになります。
C#田中: 90
佐藤: 85
Whereを使うと、値やキーに条件を指定して検索できます。
5-5. 検索処理でよくある失敗例
Dictionaryの検索処理でよくある失敗は、キーが存在しないのに直接取得してしまうことです。
C#Console.WriteLine(scores["山田"]);
このようなコードは、"山田"というキーが存在しない場合にエラーになります。
安全に書くなら、次のようにします。
C#if (scores.TryGetValue("山田", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("データがありません");
}
また、大文字と小文字の違いによる検索ミスもよくあります。
C#Dictionary<string, string> users = new Dictionary<string, string>();
users.Add("Admin", "管理者");
Console.WriteLine(users.ContainsKey("admin"));
この場合、"Admin"と"admin"は別のキーとして扱われるため、結果はfalseになります。
大文字・小文字を区別したくない場合は、Dictionary作成時に比較方法を指定します。
C#Dictionary<string, string> users = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
users.Add("Admin", "管理者");
Console.WriteLine(users.ContainsKey("admin"));
実行結果は次のようになります。
C#True
6. Dictionaryの値を更新・変更する方法
6-1. キーを指定して値を上書きする
Dictionaryの値を更新するには、キーを指定して新しい値を代入します。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
scores["田中"] = 95;
Console.WriteLine(scores["田中"]);
実行結果は次のようになります。
C#95
このように、既存のキーに対してインデクサーで値を代入すると、値が上書きされます。
6-2. 既存キーがある場合だけ更新する
キーが存在する場合だけ更新したいときは、ContainsKeyで確認します。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
if (scores.ContainsKey("田中"))
{
scores["田中"] = 95;
}
存在しないキーを誤って追加したくない場合に使える書き方です。
TryGetValueで確認してから更新することもできます。
C#if (scores.TryGetValue("田中", out int currentScore))
{
scores["田中"] = currentScore + 5;
}
この例では、現在の点数に5点加算しています。
6-3. キーがなければ追加、あれば更新する方法
キーがなければ追加し、すでにあれば更新したい場合は、インデクサーを使うのが簡単です。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores["田中"] = 90;
scores["田中"] = 95;
scores["佐藤"] = 85;
"田中"が最初に出てきたときは追加され、2回目は更新されます。
カウント処理でもよく使います。
C#Dictionary<string, int> counts = new Dictionary<string, int>();
string word = "apple";
if (counts.ContainsKey(word))
{
counts[word]++;
}
else
{
counts[word] = 1;
}
この処理は、単語がすでにあればカウントを増やし、なければ1で追加します。
6-4. 値がオブジェクトの場合の更新方法
Dictionaryの値には、文字列や数値だけでなく、クラスのオブジェクトも入れられます。
C#class User
{
public string Name { get; set; }
public int Age { get; set; }
}
ユーザーIDをキーにして、ユーザー情報を管理できます。
C#Dictionary<int, User> users = new Dictionary<int, User>();
users.Add(1, new User { Name = "田中", Age = 20 });
users.Add(2, new User { Name = "佐藤", Age = 25 });
値がオブジェクトの場合、プロパティを変更できます。
C#users[1].Age = 21;
Console.WriteLine(users[1].Age);
実行結果は次のようになります。
C#21
オブジェクトそのものを差し替えることもできます。
C#users[1] = new User { Name = "田中太郎", Age = 22 };
6-5. 更新時に注意したいキーの重複
Dictionaryでは、キーは重複できません。
Addで同じキーを追加するとエラーになります。
C#scores.Add("田中", 90);
scores.Add("田中", 95); // エラー
更新したい場合は、Addではなくインデクサーを使います。
C#scores["田中"] = 95;
「追加なのか、更新なのか」を意識することが大切です。
| やりたいこと | 書き方 |
|---|---|
| 新しいキーだけ追加したい | Add |
| すでにあれば更新したい | インデクサー |
| 追加できたか判定したい | TryAdd |
| 存在確認してから更新したい | ContainsKey |
7. Dictionaryから要素を削除する方法
7-1. Removeで指定したキーの要素を削除する
Dictionaryから要素を削除するには、Removeメソッドを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
scores.Remove("佐藤");
削除後に確認してみます。
C#foreach (var item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
実行結果は次のようになります。
C#田中: 90
鈴木: 78
Removeは、指定したキーに対応する要素を削除します。
7-2. ClearでDictionaryの中身をすべて削除する
Dictionaryの要素をすべて削除したい場合は、Clearを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
scores.Clear();
Console.WriteLine(scores.Count);
実行結果は次のようになります。
C#0
Clearを使うと、Dictionaryの中身が空になります。
7-3. 削除前にContainsKeyで存在確認する方法
存在しないキーをRemoveしてもエラーにはなりません。
C#scores.Remove("山田");
ただし、削除できたかどうかを判定したい場合は、Removeの戻り値を使うと便利です。
C#bool removed = scores.Remove("佐藤");
if (removed)
{
Console.WriteLine("削除しました");
}
else
{
Console.WriteLine("指定したキーは存在しません");
}
ContainsKeyで確認してから削除することもできます。
C#if (scores.ContainsKey("佐藤"))
{
scores.Remove("佐藤");
}
ただし、削除できたか知りたいだけなら、Removeの戻り値を使うほうが簡潔です。
7-4. ループ中に削除するときの注意点
Dictionaryをforeachでループしている最中に、そのDictionaryを直接変更するとエラーになることがあります。
次のようなコードは避けましょう。
C#foreach (var item in scores)
{
if (item.Value < 80)
{
scores.Remove(item.Key); // ループ中の変更でエラーになる可能性
}
}
安全に削除するには、削除対象のキーを先にリスト化します。
C#var keysToRemove = scores
.Where(item => item.Value < 80)
.Select(item => item.Key)
.ToList();
foreach (var key in keysToRemove)
{
scores.Remove(key);
}
ToListで削除対象を別のリストにしてから削除するのがポイントです。
7-5. 削除処理の実用的なサンプルコード
次の例では、在庫数が0の商品をDictionaryから削除します。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Dictionary<string, int> stock = new Dictionary<string, int>
{
{ "りんご", 10 },
{ "みかん", 0 },
{ "バナナ", 5 },
{ "ぶどう", 0 }
};
var removeKeys = stock
.Where(item => item.Value == 0)
.Select(item => item.Key)
.ToList();
foreach (var key in removeKeys)
{
stock.Remove(key);
}
foreach (var item in stock)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
}
}
実行結果は次のようになります。
C#りんご: 10
バナナ: 5
このように、条件に合う要素を削除したい場合は、LINQで削除対象を取り出してからRemoveする方法が便利です。
8. Dictionaryの要素をループで取り出す方法
8-1. foreachでキーと値を取り出す
Dictionaryのすべての要素を取り出すには、foreachを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
foreach (var item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
実行結果は次のようになります。
C#田中: 90
佐藤: 85
鈴木: 78
item.Keyでキー、item.Valueで値を取得できます。
8-2. Keysだけをループ処理する
キーだけを取り出したい場合は、Keysを使います。
C#foreach (var key in scores.Keys)
{
Console.WriteLine(key);
}
実行結果は次のようになります。
C#田中
佐藤
鈴木
キー一覧を表示したいときや、キーを使って別の処理をしたいときに使えます。
8-3. Valuesだけをループ処理する
値だけを取り出したい場合は、Valuesを使います。
C#foreach (var value in scores.Values)
{
Console.WriteLine(value);
}
実行結果は次のようになります。
C#90
85
78
点数の合計や平均を計算したい場合にも使えます。
C#int total = 0;
foreach (var value in scores.Values)
{
total += value;
}
Console.WriteLine(total);
8-4. KeyValuePairの意味と使い方
Dictionaryをforeachで取り出すと、各要素はKeyValuePair<TKey, TValue>として扱われます。
明示的に書くと次のようになります。
C#foreach (KeyValuePair<string, int> item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
KeyValuePairは、キーと値のペアを表す型です。
C#KeyValuePair<string, int>
この場合、キーがstring、値がintのペアという意味になります。
普段はvarを使って書くことが多いです。
C#foreach (var item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
8-5. ループ処理で表示・集計するサンプル
次の例では、Dictionaryに入っている点数を表示し、合計点と平均点を計算します。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 },
{ "鈴木", 78 }
};
int total = 0;
foreach (var item in scores)
{
Console.WriteLine($"{item.Key}さん: {item.Value}点");
total += item.Value;
}
double average = (double)total / scores.Count;
Console.WriteLine($"合計点: {total}");
Console.WriteLine($"平均点: {average}");
}
}
実行結果は次のようになります。
C#田中さん: 90点
佐藤さん: 85点
鈴木さん: 78点
合計点: 253
平均点: 84.33333333333333
Dictionaryのループ処理では、キーと値の両方を使えるため、表示や集計に便利です。
9. Dictionaryを並び替える方法
9-1. キーで昇順・降順に並び替える
Dictionaryをキーで並び替えるには、LINQのOrderByを使います。
C#using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "Tanaka", 90 },
{ "Sato", 85 },
{ "Suzuki", 78 }
};
var sorted = scores.OrderBy(item => item.Key);
foreach (var item in sorted)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
}
}
降順にしたい場合は、OrderByDescendingを使います。
C#var sorted = scores.OrderByDescending(item => item.Key);
9-2. 値で昇順・降順に並び替える
値で並び替える場合も、OrderByを使います。
C#var sorted = scores.OrderBy(item => item.Value);
降順にする場合は次のように書きます。
C#var sorted = scores.OrderByDescending(item => item.Value);
点数の高い順に表示する例です。
C#foreach (var item in scores.OrderByDescending(item => item.Value))
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
9-3. LINQのOrderByを使った並び替え
OrderByは、Dictionaryそのものを並び替えるというより、並び替えた結果を取得するために使います。
C#var sortedScores = scores.OrderByDescending(item => item.Value);
foreach (var item in sortedScores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
必要であれば、並び替えた結果から新しいDictionaryを作ることもできます。
C#var sortedDictionary = scores
.OrderBy(item => item.Key)
.ToDictionary(item => item.Key, item => item.Value);
ただし、Dictionaryは順序を目的に使うコレクションではないため、順番を重視する場合は注意が必要です。
9-4. Dictionaryは基本的に順序を目的に使わない
Dictionaryは、キーを使って値をすばやく取得するためのコレクションです。
そのため、基本的には「順番を管理するため」に使うものではありません。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
このDictionaryに追加した順番で処理できるように見える場合もありますが、順序に依存したコードは避けるのが安全です。
順番が重要な処理では、ListやSortedDictionaryなど、目的に合ったコレクションを検討しましょう。
9-5. 順序が必要な場合の代替手段
順序が必要な場合は、次のような代替手段があります。
| 目的 | 候補 |
|---|---|
| 追加した順番で扱いたい | List |
| キーで常に並べたい | SortedDictionary |
| 必要なときだけ並び替えたい | LINQのOrderBy |
| キーと値のペアを順番付きで扱いたい | List<KeyValuePair<TKey, TValue>> |
たとえば、キーで常に並んだ状態を保ちたい場合はSortedDictionaryを使えます。
C#SortedDictionary<string, int> scores = new SortedDictionary<string, int>();
scores.Add("Tanaka", 90);
scores.Add("Sato", 85);
scores.Add("Suzuki", 78);
foreach (var item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
一時的に表示順を変えたいだけなら、LINQのOrderByで十分です。
10. Dictionaryでよく使うメソッド・プロパティ一覧
10-1. Addの使い方
Addは、Dictionaryに新しいキーと値を追加するメソッドです。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
同じキーがすでに存在する場合はエラーになります。
C#scores.Add("田中", 95); // エラー
重複を避けるには、ContainsKeyやTryAddを使います。
C#if (!scores.ContainsKey("田中"))
{
scores.Add("田中", 90);
}
10-2. Removeの使い方
Removeは、指定したキーの要素を削除します。
C#scores.Remove("田中");
削除できたか確認したい場合は、戻り値を使います。
C#if (scores.Remove("田中"))
{
Console.WriteLine("削除しました");
}
else
{
Console.WriteLine("キーが存在しません");
}
10-3. ContainsKeyの使い方
ContainsKeyは、Dictionaryに指定したキーが存在するかを確認します。
C#if (scores.ContainsKey("田中"))
{
Console.WriteLine("キーが存在します");
}
キーの存在だけを確認したい場合に便利です。
ただし、値も取得したい場合はTryGetValueを使うほうが適しています。
10-4. TryGetValueの使い方
TryGetValueは、キーの存在確認と値の取得を同時に行います。
C#if (scores.TryGetValue("田中", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("キーが存在しません");
}
存在しないキーを指定してもエラーにならないため、安全に値を取得できます。
初心者がC# Dictionaryを使うときに、特に覚えておきたいメソッドです。
10-5. Countで要素数を取得する
Countは、Dictionaryに入っている要素数を取得するプロパティです。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中", 90 },
{ "佐藤", 85 }
};
Console.WriteLine(scores.Count);
実行結果は次のようになります。
C#2
要素があるか確認したい場合にも使えます。
C#if (scores.Count > 0)
{
Console.WriteLine("データがあります");
}
10-6. Clearで全要素を削除する
Clearは、Dictionaryの中身をすべて削除します。
C#scores.Clear();
削除後、Countは0になります。
C#Console.WriteLine(scores.Count);
実行結果は次のようになります。
C#0
すべてのデータをリセットしたいときに使います。
11. Dictionaryでよくあるエラーと対処法
11-1. 同じキーを追加してしまうエラー
Dictionaryでよくあるエラーのひとつが、同じキーをAddで追加してしまうことです。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("田中", 95);
このコードでは、"田中"というキーを2回追加しているためエラーになります。
対処法は、追加前にキーの存在を確認することです。
C#if (!scores.ContainsKey("田中"))
{
scores.Add("田中", 90);
}
また、追加できたかを判定したい場合はTryAddを使います。
C#if (scores.TryAdd("田中", 90))
{
Console.WriteLine("追加しました");
}
else
{
Console.WriteLine("すでに存在します");
}
更新したい場合は、Addではなくインデクサーを使います。
C#scores["田中"] = 95;
11-2. 存在しないキーを取得してしまうエラー
存在しないキーをインデクサーで取得すると、KeyNotFoundExceptionが発生します。
C#Console.WriteLine(scores["山田"]);
このエラーを防ぐには、TryGetValueを使います。
C#if (scores.TryGetValue("山田", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("キーが存在しません");
}
キーがあるかだけ確認したい場合は、ContainsKeyでも構いません。
C#if (scores.ContainsKey("山田"))
{
Console.WriteLine(scores["山田"]);
}
11-3. nullをキーや値に使うときの注意点
Dictionaryでは、キーにnullを使うとエラーになる場合があります。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
string key = null;
// scores.Add(key, 100); // エラー
キーはデータを識別するためのものなので、nullを避けるのが基本です。
一方、値については型によってnullを扱える場合があります。
C#Dictionary<string, string> users = new Dictionary<string, string>();
users.Add("user1", null);
ただし、値がnullになる可能性があると、取得後の処理でエラーが起きることがあります。
C#if (users.TryGetValue("user1", out string name))
{
if (name != null)
{
Console.WriteLine(name.Length);
}
}
nullを扱う場合は、必ずnullチェックを意識しましょう。
11-4. 大文字・小文字の違いによる検索ミス
文字列をキーにする場合、大文字と小文字の違いに注意が必要です。
C#Dictionary<string, string> users = new Dictionary<string, string>();
users.Add("Admin", "管理者");
Console.WriteLine(users.ContainsKey("admin"));
実行結果は次のようになります。
C#False
"Admin"と"admin"は別のキーとして扱われます。
大文字・小文字を区別したくない場合は、Dictionary作成時にStringComparer.OrdinalIgnoreCaseを指定します。
C#Dictionary<string, string> users = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
users.Add("Admin", "管理者");
Console.WriteLine(users.ContainsKey("admin"));
実行結果は次のようになります。
C#True
ログインIDや設定名などで大文字・小文字を区別したくない場合に便利です。
11-5. ループ中の変更によるエラー
Dictionaryをループしている最中に要素を追加・削除すると、エラーになることがあります。
C#foreach (var item in scores)
{
if (item.Value < 80)
{
scores.Remove(item.Key);
}
}
安全に処理するには、変更対象を先に別のリストにします。
C#var keys = scores
.Where(item => item.Value < 80)
.Select(item => item.Key)
.ToList();
foreach (var key in keys)
{
scores.Remove(key);
}
ループ中にDictionaryを変更したい場合は、「直接変更しない」ことを覚えておきましょう。
12. Dictionaryの実践サンプルコード
12-1. 商品コードと商品名を管理するサンプル
商品コードから商品名を取得するサンプルです。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, string> products = new Dictionary<string, string>
{
{ "P001", "ノートパソコン" },
{ "P002", "マウス" },
{ "P003", "キーボード" }
};
string code = "P002";
if (products.TryGetValue(code, out string productName))
{
Console.WriteLine($"商品名: {productName}");
}
else
{
Console.WriteLine("商品が見つかりません");
}
}
}
実行結果は次のようになります。
C#商品名: マウス
商品コードや会員番号など、一意のIDをキーにするとDictionaryの便利さがわかりやすくなります。
12-2. ユーザーIDとユーザー情報を管理するサンプル
ユーザーIDをキーにして、ユーザー情報を管理する例です。
C#using System;
using System.Collections.Generic;
class User
{
public string Name { get; set; }
public string Email { get; set; }
}
class Program
{
static void Main()
{
Dictionary<int, User> users = new Dictionary<int, User>
{
{
1,
new User
{
Name = "田中",
Email = "tanaka@example.com"
}
},
{
2,
new User
{
Name = "佐藤",
Email = "sato@example.com"
}
}
};
int userId = 1;
if (users.TryGetValue(userId, out User user))
{
Console.WriteLine($"名前: {user.Name}");
Console.WriteLine($"メール: {user.Email}");
}
}
}
実行結果は次のようになります。
C#名前: 田中
メール: tanaka@example.com
Dictionaryの値には、自作クラスも入れられます。
12-3. 単語の出現回数をカウントするサンプル
Dictionaryは、出現回数のカウントにもよく使われます。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
string[] words = { "apple", "orange", "apple", "banana", "orange", "apple" };
Dictionary<string, int> counts = new Dictionary<string, int>();
foreach (string word in words)
{
if (counts.ContainsKey(word))
{
counts[word]++;
}
else
{
counts[word] = 1;
}
}
foreach (var item in counts)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
}
}
実行結果は次のようになります。
C#apple: 3
orange: 2
banana: 1
このように、キーを単語、値を回数にすると、簡単に集計処理ができます。
12-4. 設定値をキーと値で管理するサンプル
アプリケーションの設定値をDictionaryで管理する例です。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, string> settings = new Dictionary<string, string>
{
{ "Theme", "Dark" },
{ "Language", "Japanese" },
{ "FontSize", "14" }
};
if (settings.TryGetValue("Theme", out string theme))
{
Console.WriteLine($"テーマ: {theme}");
}
settings["Theme"] = "Light";
Console.WriteLine($"変更後のテーマ: {settings["Theme"]}");
}
}
実行結果は次のようになります。
C#テーマ: Dark
変更後のテーマ: Light
設定名をキーにして値を管理すると、必要な設定を簡単に取得できます。
12-5. 初心者向けの簡単な練習問題
C# Dictionaryに慣れるために、次の練習をしてみましょう。
まず、名前と点数を管理するDictionaryを作成します。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
次に、3人分の点数を追加します。
C#scores.Add("田中", 90);
scores.Add("佐藤", 85);
scores.Add("鈴木", 78);
次の処理を書いてみましょう。
"田中"の点数を表示する"佐藤"の点数を95に更新する"鈴木"のデータを削除するすべての名前と点数を
foreachで表示する"山田"が存在するかTryGetValueで確認する
解答例は次のとおりです。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("佐藤", 85);
scores.Add("鈴木", 78);
Console.WriteLine(scores["田中"]);
scores["佐藤"] = 95;
scores.Remove("鈴木");
foreach (var item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
if (scores.TryGetValue("山田", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("山田さんのデータはありません");
}
}
}
13. Dictionaryと関連コレクションの違い
13-1. Listとの違い
Listは、データを順番に管理するコレクションです。
C#List<string> names = new List<string>
{
"田中",
"佐藤",
"鈴木"
};
Dictionaryは、キーと値をセットで管理するコレクションです。
C#Dictionary<int, string> users = new Dictionary<int, string>
{
{ 1, "田中" },
{ 2, "佐藤" },
{ 3, "鈴木" }
};
Listは「一覧」を扱うのに向いています。Dictionaryは「キーから値を探す」のに向いています。
C#Console.WriteLine(users[1]);
このように、ユーザーIDから名前を取得したい場合はDictionaryが便利です。
13-2. Hashtableとの違い
Hashtableも、キーと値を管理できるコレクションです。
C#Hashtable table = new Hashtable();
table.Add("A001", "ノートパソコン");
ただし、Hashtableは古い書き方で、キーや値の型が明確ではありません。
Dictionaryでは、キーと値の型を指定できます。
C#Dictionary<string, string> products = new Dictionary<string, string>();
型が明確なため、間違った型のデータを入れにくく、コードも読みやすくなります。
初心者が新しく学ぶなら、基本的にはDictionary<TKey, TValue>を使うのがおすすめです。
13-3. SortedDictionaryとの違い
SortedDictionaryは、キーの順番で自動的に並べて管理するコレクションです。
C#SortedDictionary<string, int> scores = new SortedDictionary<string, int>
{
{ "Tanaka", 90 },
{ "Sato", 85 },
{ "Suzuki", 78 }
};
通常のDictionaryは、キーで値を取得することを主な目的としています。
一方、SortedDictionaryはキーの順序も意識したい場合に使います。
C#foreach (var item in scores)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
キー順で取り出したい処理が多い場合は、SortedDictionaryを検討するとよいでしょう。
13-4. ConcurrentDictionaryとの違い
ConcurrentDictionaryは、複数のスレッドから安全に使いやすいDictionaryです。
通常のDictionaryは、複数のスレッドが同時に追加・更新するような場面では注意が必要です。
一方、ConcurrentDictionaryは、並列処理や非同期処理で共有データを扱うときに使われます。
C#using System.Collections.Concurrent;
ConcurrentDictionary<string, int> counts = new ConcurrentDictionary<string, int>();
counts.TryAdd("apple", 1);
初心者が最初に覚えるべきなのは通常のDictionaryです。複数スレッドで同時に更新する必要が出てきたら、ConcurrentDictionaryを学ぶとよいでしょう。
13-5. 目的別にどれを選ぶべきか
目的別の選び方は次のとおりです。
| 目的 | おすすめ |
|---|---|
| データを順番に並べたい | List |
| キーと値で管理したい | Dictionary |
| キー順で管理したい | SortedDictionary |
| 複数スレッドで安全に使いたい | ConcurrentDictionary |
| 古いコードを読む必要がある | Hashtable |
通常のアプリケーション開発では、まずListとDictionaryを使い分けられるようになることが重要です。
「順番で扱うならList」「キーで探すならDictionary」と覚えるとわかりやすいです。
14. C# Dictionaryの使い方に関するFAQ
14-1. Dictionaryのキーに重複は使える?
Dictionaryのキーに重複は使えません。
同じキーをAddで追加しようとするとエラーになります。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 90);
scores.Add("田中", 95); // エラー
同じキーの値を変更したい場合は、インデクサーで上書きします。
C#scores["田中"] = 95;
14-2. Dictionaryの値は重複してもよい?
Dictionaryの値は重複しても問題ありません。
C#Dictionary<int, string> users = new Dictionary<int, string>();
users.Add(1, "田中");
users.Add(2, "田中");
このように、キーが違えば同じ値を登録できます。
キーは一意である必要がありますが、値は一意である必要はありません。
14-3. Dictionaryの順番は保証される?
Dictionaryは、基本的に順番を目的に使うコレクションではありません。
追加した順番で表示されるように見える場合もありますが、順序に依存したコードは避けるのが安全です。
順序が必要な場合は、表示時にOrderByで並び替えます。
C#foreach (var item in scores.OrderBy(item => item.Key))
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
キー順で常に管理したい場合は、SortedDictionaryも選択肢になります。
14-4. Dictionaryのキーを変更できる?
Dictionaryのキーは、直接変更できません。
キーを変更したい場合は、古いキーの要素を削除し、新しいキーで追加します。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "Tanaka", 90 }
};
int value = scores["Tanaka"];
scores.Remove("Tanaka");
scores.Add("TANAKA", value);
キーは値を探すための重要な情報なので、変更が多いデータには注意が必要です。
14-5. Dictionaryで部分一致検索はできる?
Dictionaryは、基本的にはキーの完全一致で値を取得します。
C#scores["田中"];
ただし、LINQを使えば部分一致検索もできます。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "田中太郎", 90 },
{ "田中花子", 85 },
{ "佐藤次郎", 78 }
};
var results = scores.Where(item => item.Key.Contains("田中"));
foreach (var item in results)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
実行結果は次のようになります。
C#田中太郎: 90
田中花子: 85
ただし、Dictionaryの得意な検索は完全一致です。部分一致検索が多い場合は、データ構造を見直すことも検討しましょう。
14-6. Dictionaryは初心者でも覚えるべき?
Dictionaryは、C#初心者でも早めに覚えておきたい重要なコレクションです。
特に、次のような処理をしたい場合に役立ちます。
| やりたいこと | Dictionaryの使い方 |
|---|---|
| IDから名前を取得する | IDをキー、名前を値にする |
| 商品コードから商品名を取得する | 商品コードをキー、商品名を値にする |
| 単語の出現回数を数える | 単語をキー、回数を値にする |
| 設定値を管理する | 設定名をキー、設定値を値にする |
配列やListに慣れてきたら、次のステップとしてDictionaryを学ぶと、書けるプログラムの幅が大きく広がります。
まとめ
C# Dictionaryは、キーと値をセットで管理できる便利なコレクションです。
基本的な宣言は次のように書きます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
要素を追加するにはAddやインデクサーを使います。
C#scores.Add("田中", 90);
scores["佐藤"] = 85;
値を取得するには、キーを指定します。
C#int score = scores["田中"];
ただし、存在しないキーを指定するとエラーになるため、安全に取得したい場合はTryGetValueを使います。
C#if (scores.TryGetValue("田中", out int score))
{
Console.WriteLine(score);
}
キーの存在確認にはContainsKey、削除にはRemove、全削除にはClear、要素数の取得にはCountを使います。
C#scores.ContainsKey("田中");
scores.Remove("田中");
scores.Clear();
scores.Count;
Dictionaryは、ID、コード、名前、設定名などをキーにしてデータを管理したい場合に非常に便利です。
一方で、順番を管理する目的にはあまり向いていません。順番が必要な場合は、ListやSortedDictionary、LINQのOrderByを使い分けましょう。
C# Dictionaryの基本を理解すれば、データの追加、取得、検索、更新、削除といった処理を効率よく書けるようになります。まずは簡単なサンプルから練習し、キーと値の関係に慣れていきましょう。

