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#には、複数のデータを扱うための仕組みとして、配列、ListDictionaryなどがあります。

配列は、要素数が決まっているデータを順番に管理するのに向いています。

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;

DictionarySystem.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では、TKeystringTValueintです。

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に追加した順番で処理できるように見える場合もありますが、順序に依存したコードは避けるのが安全です。

順番が重要な処理では、ListSortedDictionaryなど、目的に合ったコレクションを検討しましょう。

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); // エラー

重複を避けるには、ContainsKeyTryAddを使います。

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);

次の処理を書いてみましょう。

  1. "田中"の点数を表示する

  2. "佐藤"の点数を95に更新する

  3. "鈴木"のデータを削除する

  4. すべての名前と点数をforeachで表示する

  5. "山田"が存在するか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

通常のアプリケーション開発では、まずListDictionaryを使い分けられるようになることが重要です。

「順番で扱うなら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、コード、名前、設定名などをキーにしてデータを管理したい場合に非常に便利です。

一方で、順番を管理する目的にはあまり向いていません。順番が必要な場合は、ListSortedDictionary、LINQのOrderByを使い分けましょう。

C# Dictionaryの基本を理解すれば、データの追加、取得、検索、更新、削除といった処理を効率よく書けるようになります。まずは簡単なサンプルから練習し、キーと値の関係に慣れていきましょう。