C#でデータを管理する際、特定の「キー(Key)」と「値(Value)」をペアにして保持できる Dictionary<TKey, TValue> は非常に強力なコレクションです。
IDから名前を検索したり、設定値を名前で管理したりと、開発のあらゆる場面で使用されます。
この記事では、C#におけるDictionaryへの要素追加について、基本的な書き方から複数一括追加のテクニック、重複を許可しない仕様への対策まで、実務で即戦力となる知識をサンプルコード付きで詳しく解説します。
![]() 執筆者:マヒロ |
|
- OS:Windows 11 / macOS Sequoia
- IDE:Visual Studio / VS Code / IntelliJ IDEA
- その他:Chrome DevTools / 各言語最新安定版
※本メディアでは、上記環境にてコードの動作と情報の正確性を検証済みです。
Dictionaryに要素を追加する基本操作
Dictionaryへデータを格納するアプローチには、主に「Addメソッド」を使う方法と「インデクサ([])」を使う方法の2種類があります。これらは似ているようで、「既に同じキーが存在する場合」の挙動が決定的に異なります。
それぞれの特徴と、最新のC#で使える便利な初期化記法について見ていきましょう。
Addメソッドを使った追加
最も標準的な追加方法が Add メソッドです。
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Dictionaryの生成
var userDict = new Dictionary<int, string>();
// Addメソッドで要素を追加
userDict.Add(1, "田中");
userDict.Add(2, "佐藤");
Console.WriteLine($"要素数: {userDict.Count}");
foreach (var pair in userDict)
{
Console.WriteLine($"ID: {pair.Key}, Name: {pair.Value}");
}
}
}
実行結果
要素数: 2
ID: 1, Name: 田中
ID: 2, Name: 佐藤
ソースコードの内容を紐解くと、まず int 型のキーと string 型の値を扱う userDict を作成しています。
userDict.Add(1, "田中") という記述によって、キー「1」に値「田中」が紐付いた状態で保存されます。
このメソッドを使用する際の注意点は、既に「1」というキーが存在している状態で再度 Add(1, "鈴木") を実行すると、ArgumentException(同一のキーが既に追加されています)というエラーが発生し、プログラムが停止してしまう点にあります。
追加しようとするデータが新規であることを確信している場合に使用するのが一般的です。
インデクサ([])を使った追加・更新(上書き)
配列のような角括弧 [] を使って値を代入する方法です。
var userDict = new Dictionary<int, string>();
// インデクサによる代入(新規追加)
userDict[1] = "田中";
// 同じキーに対して代入(上書き更新)
userDict[1] = "鈴木";
Console.WriteLine($"ID: 1 の値は {userDict[1]} です。");
実行結果
ID: 1 の値は 鈴木 です。
インデクサを使用した代入は、指定したキーが存在しない場合は「新規追加」として働き、既に存在する場合は「上書き(Valueの変更)」として機能します。
先ほどの Add メソッドと違い、同じキーを指定してもエラーにならないため、最新のデータに常に更新したいという要件に適しています。
非常に柔軟性が高いため、実務のロジック内ではこちらの書き方が好まれる傾向にあります。
コレクション初期化子と最新のコレクション式
宣言と同時に初期データを投入したい場合に便利な書き方です。
// 1. 従来のコレクション初期化子
var dict1 = new Dictionary<string, int>
{
{ "Apple", 100 },
{ "Banana", 200 }
};
// 2. 最新のコレクション式(C# 12以降)
Dictionary<string, int> dict2 = []; // 空で初期化
コレクション初期化子を使うと、波括弧の中にペアを羅列するだけで直感的にデータをセットできます。
また、最新のC#環境であれば、角括弧 [] を用いたコレクション式によって空のDictionaryをより簡潔に表現できるようになりました。
コードの可読性を高めるために、積極的に活用したい記法と言えます。
複数の要素を一括で追加・結合する方法
「別のDictionaryにあるデータをすべて統合したい」「リスト形式のデータを一気に流し込みたい」というニーズは非常に多いですが、実はDictionaryには Listクラスのような AddRange メソッドが標準では存在しません。
そのため、複数の要素を結合するには以下のテクニックを使い分けます。
ループ処理による複数追加
最も確実で制御しやすいのが、foreach 文を用いた追加です。
var mainDict = new Dictionary<string, string> { { "key1", "A" } };
var subDict = new Dictionary<string, string> { { "key2", "B" }, { "key3", "C" } };
// subDictの要素をすべてmainDictに追加する
foreach (var pair in subDict)
{
// 重複を避けて追加するならTryAddなどが便利
mainDict[pair.Key] = pair.Value;
}
このプログラムでは、追加元の subDict をループで回し、一つひとつのキーと値を mainDict に代入しています。
前述の通り、インデクサを使えば上書きしながらコピーできますが、もし既存のデータを壊したくない場合は、ループ内で ContainsKey によるチェックを行うか、後述する安全なメソッドを使用する必要があります。
Dictionary同士を結合する(LINQの活用)
LINQ(Language Integrated Query)を使用すると、宣言的な記述で結合が可能です。
using System.Linq;
var dictA = new Dictionary<int, string> { { 1, "A" } };
var dictB = new Dictionary<int, string> { { 2, "B" } };
// 2つのDictionaryを結合して新しいDictionaryを作る
var mergedDict = dictA.Concat(dictB).ToDictionary(x => x.Key, x => x.Value);
Concat メソッドは、2つのシーケンスを連結した列挙子を返します。
それを ToDictionary に渡すことで、再びDictionaryオブジェクトとして再構成しています。 ただし、結合する2つのDictionaryに同じキーが含まれている場合、ToDictionary の段階でエラーになるため注意してください。
重複がある場合は GroupBy などで整理してから変換する手間が必要になります。
重複キーやエラーを防ぐ安全な追加と取得
Dictionaryを扱う上で最も恐ろしいのが、実行時のエラー(例外)です。
プログラムをクラッシュさせずに、安全に要素を追加・取得するための鉄板メソッドを紹介します。
安全な取得と追加を同時に行う TryGetValue
データの「取得」において最も推奨されるのが TryGetValue メソッドです。
var dict = new Dictionary<string, int> { { "Score", 100 } };
// キーが存在するか確認しながら値を取得
if (dict.TryGetValue("Score", out int val))
{
Console.WriteLine($"取得成功: {val}");
}
else
{
Console.WriteLine("指定したキーは見つかりませんでした");
}
このコードの挙動は非常にスマートです。
通常、存在しないキーに dict["Unknown"] とアクセスするとエラーになりますが、TryGetValue は成否を bool で返しつつ、成功時のみ out 変数に値を格納してくれます。
「キーがあるか確認(ContainsKey)」してから「値を取得する([])」という2段階の処理を1回で完結させられるため、パフォーマンス面でも非常に有利な書き方となります。
重複を許可したい場合の代替案(Lookup, GroupBy)
Dictionaryは仕様上、重複するキーを許可することはできません。
もし、1つのキーに対して複数の値を保持したい(例:「果物」というキーに対して「りんご」「みかん」を紐付ける)場合は、値の型をリストにするか、別のデータ構造を検討します。
// キーに対してリストを値にする
var multiDict = new Dictionary<string, List<string>>();
string category = "果物";
if (!multiDict.ContainsKey(category))
{
multiDict[category] = new List<string>();
}
multiDict[category].Add("りんご");
このように、Dictionaryの「値(Value)」の部分を List<T> にすることで、擬似的に重複(1対多の管理)を許可する構造を構築できます。
読み取り専用でよければ、LINQの ToLookup メソッドを使って、最初からグループ化されたデータ構造を作るのも賢い選択です。
Dictionaryの追加順と並び替え
Dictionaryに要素を追加した際、その並び順はどうなるのでしょうか。
「追加した順番にデータを取り出したい」という要望への回答を整理します。
追加順が保持される仕様(.NET 以前との違い)
.NET Core 以降(.NET 5/6/7/8…)のモダンなC#環境では、Dictionaryの要素をループで回すと、基本的には「追加した順番」で取得されるようになっています。
以前の古い.NET Framework環境では順番は不定(保証されない)とされていましたが、内部構造の変更により現在は安定した順序でアクセス可能です。
ただし、要素を削除した後に再度追加したりすると順番が入れ替わることがあるため、厳密に「最初に入れたものを1番目に固定したい」という用途で頼りすぎるのは危険です。
順序を完全に保証する OrderedDictionary
もし削除や更新を含めて、順序の管理がアプリケーションの根幹に関わる場合は、OrderedDictionary クラス(System.Collections.Specialized 名前空間)の利用を検討してください。
このクラスは、インデックス(番号)によるアクセスとキーによるアクセスの両方をサポートしており、要素の並び順を確実に管理できます。
ただし、ジェネリクス(<TKey, TValue>)に対応していない古い型であるため、現代のC#開発では Dictionary を使いつつ、順序が必要な時だけ OrderBy などのLINQでソートして利用するのが一般的です。
C#のスキルを活かして年収を上げる方法
以上、C#でDictionaryに要素を追加する方法について解説してきました。
業務システム開発やアプリ開発、ゲーム開発において需要の高いC#を扱えるエンジニアは、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。
なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。
転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。
| 年収アップにこだわりたい方 (平均アップ額138万円の実績) | テックゴー |
| 未経験・経験者問わず幅広く探したい方 | ユニゾンキャリア |
| 業界に精通した担当者に相談したい方 | キッカケエージェント |
| ゲーム業界への転職を志望する方 | ファミキャリ |
| エンジニア未経験からキャリアを築く方 | イーチキャリア |



