Dictionary<TKey,TValue>クラス

実装しているインターフェイス

[SerializableAttribute]
[ComVisibleAttribute(false)]
public class Dictionary<TKey, TValue> :
    IDictionary<TKey, TValue>,
    IDictionary,
    ICollection<KeyValuePair<TKey, TValue>>,
    ICollection,
    IEnumerable<KeyValuePair<TKey, TValue>>,
    IEnumerable,
    IReadOnlyDictionary<TKey, TValue>,
    IReadOnlyCollection<KeyValuePair<TKey, TValue>>,
    ISerializable,
    IDeserializationCallback
構文 - Dictionary(TKey, TValue) クラス (System.Collections.Generic) | MSDN

コンストラクタ

キーが等しいかは、既定ではEqualityComparer<T>.Defaultで評価されます。これを変更するにはIEqualityComparer<TKey>を引数に取るコンストラクタで、それを指定します。Remarks - Dictionary<TKey,TValue> Class (System.Collections.Generic) | Microsoft Learn

コンストラクタ  
Dictionary<TKey,TValue>()  
Dictionary<TKey,TValue>(IDictionary<TKey,TValue>)  
Dictionary<TKey,TValue>(IDictionary<TKey,TValue>, IEqualityComparer<TKey>)  
Dictionary<TKey,TValue>(IEqualityComparer<TKey>)  
Dictionary<TKey,TValue>(Int32)  
Dictionary<TKey,TValue>(Int32, IEqualityComparer<TKey>)  
Dictionary<TKey,TValue>(SerializationInfo, StreamingContext)  

初期化

コレクション初期化子を用いて初期化できます。

Dictionary<int, string> dictionary1 = new Dictionary<int, string>
{
    [0] = "a",
    [3] = "b",
    [5] = "c",
};

C# 6以前ならば、次のようにも記述できます。コレクション初期化子 - オブジェクト初期化子とコレクション初期化子 - C# プログラミング ガイド | Microsoft Learn

Dictionary<int, string> dictionary2 = new Dictionary<int, string>
{
    { 0, "a" },
    { 3, "b" },
    { 5, "c" },
};

プロパティ

主要なプロパティ
プロパティ 内容
TValue Item[TKey] キーから要素へアクセスする
Dictionary<TKey,TValue>.KeyCollection Keys キーを格納しているコレクション
Dictionary<TKey,TValue>.ValueCollection Values 値を格納しているコレクション
     
プロパティ - Dictionary<TKey,TValue> クラス (System.Collections.Generic) | Microsoft Learn

Item[TKey]

指定のキーが見つからない場合、それぞれ次の結果となります。

  • get … KeyNotFoundExceptionが投げられる。キーが見つからないことが想定されるならば、TryGetValue()で取得する
  • set … 指定のキーを持つ、新しい要素が作成される

値を設定するときに上書きではなく確実に追加としたいならば、Add()を用います。

Keys

Dictionaryのすべての要素を操作するとき、foreachではそのコレクションを変更できません。

Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1, "A");
dictionary.Add(2, "B");

foreach (KeyValuePair<int, string> keyValuePair in dictionary)
{ // ループの2週目でInvalidOperationException「コレクションが変更されました。列挙操作は実行されない可能性があります。」となる
    dictionary[keyValuePair.Key] = "SAMPLE"; // ここでコレクションが変更される
}

そのためKeysのコピーを作成した上で、それを用いて操作します。Dictionaryのキー/値をforeachで簡単に扱うには?[C#/VB]:.NET TIPS - @IT 山本康彦 (2018/02/21)

Dictionary<int, string>.KeyCollection keyCollection = dictionary.Keys;

int[] keyArray = new int[keyCollection.Count];
keyCollection.CopyTo(keyArray, 0);

foreach (int key in keyArray)
{
    dictionary[key] = "SAMPLE";
}

このときKeysのコレクションは、Listクラスのコンストラクタを用いて、

List<int> keyArray = new List<int>(dictionary.Keys);

としたり、Linqの拡張メソッドでも作成できます。

int[] keyArray = dictionary.Keys.ToArray();

Enumerator.Current

SyncRoot

ICollectionへキャストすればSyncRootを取得できますが、より安全には同期用のオブジェクトを別に定義します。c# - Hashtable to Dictionary<> syncroot . - Stack Overflow

Dictionary<int, string> dictionary = new Dictionary<int, string>();
lock (((System.Collections.ICollection)dictionary).SyncRoot)
{
}

メソッド

主要なメソッド
メソッド 機能
Add(TKey, TValue) キーと値を追加する
TryGetValue(TKey, TValue) キーから値の取得を試みる
Remove(TKey) キーと値を削除する
Clear()  
ContainsKey(TKey)  
ContainsValue(TValue)  
   
メソッド - Dictionary<TKey,TValue> クラス (System.Collections.Generic) | Microsoft Learn

Add()

public void Add (TKey key, TValue value);
Dictionary<TKey,TValue>.Add(TKey, TValue) メソッド (System.Collections.Generic) | Microsoft Learn

すでに存在するキーを追加しようとすると、ArgumentExceptionが投げられます。キーが存在することが想定されるならばItem[TKey]プロパティへ書き込むことで、内容を書き換えられます。

TKeyが参照型であってもkeyにnullを指定できず、指定するとArgumentNullExceptionが投げられます。

このメソッドの計算量はO(1)ですが、容量を増加させる必要があるときは、CountプロパティをnとしてO(n)です。

TryGetValue()

指定のキーに関連付けられた値を取得できます。

public bool TryGetValue (TKey key, out TValue value);
Dictionary<TKey,TValue>.TryGetValue(TKey, TValue) メソッド (System.Collections.Generic) | Microsoft Learn

キーに関連付けられた値が見つからなかった場合はfalseが返され、valueにはその型の既定値が設定されます。

サンプルコード

Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("A", "1");
dictionary.Add("B", "2");
dictionary.Add("C", "3");
try
{
    // すでに存在するキーに追加する
    dictionary.Add("A", "10");
}
catch (ArgumentException e)
{
    Console.Write(e.Message); // "同一のキーを含む項目が既に追加されています。"
}

// キーを指定して要素を読み込む
string x = dictionary["A"]; // "1"

// すでに存在するキーに書き込む
dictionary["A"] = "X";
x = dictionary["A"]; // 内容が書き換わる "X"

// 存在しないキーに書き込む
dictionary["D"] = "4"; // 追加される

try
{
    // 存在しないキーから読み込む
    string tmp = dictionary["Y"];
}
catch (KeyNotFoundException e)
{
    Console.Write(e.Message); // "指定されたキーはディレクトリ内に存在しませんでした。"
}

// キーの存在を確認して読み込む
string value = "";
if (dictionary.TryGetValue("D", out value))
{
    Console.Write(value); // "4"
}

// キーが存在するか確認する
if (dictionary.ContainsKey("D"))
{
    Console.Write(dictionary["D"]); // "4"
}

// キーと値の一対を削除する
dictionary.Remove("D");
// すべての要素へのアクセス
foreach (KeyValuePair<string, string> keyValuePair in dictionary)
{
    Console.Write(keyValuePair.Key);
    Console.Write(keyValuePair.Value);
}
// すべての要素のキーを取得する
Dictionary<string, string>.KeyCollection keyCollection = dictionary.Keys;
foreach (string item in keyCollection)
{
    Console.Write(item); // "A","B","C"
}

// すべての要素の値を取得する
Dictionary<string, string>.ValueCollection valueCollection = dictionary.Values;
foreach (string item in valueCollection)
{
    Console.Write(item); // "1","2","3"
}
例 - Dictionary<TKey,TValue> クラス (System.Collections.Generic) | Microsoft Learn
Microsoft Learnから検索