0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NET 9から、OrderedDictionary<TKey, TValue>クラスが加わった

Last updated at Posted at 2025-01-18

.NET 9から、要素(キーとバリュー)の追加順序を保持するジェネリックなDictionary、OrderedDictionary<TKey, TValue>が追加されました。

このOrderedDictionary<TKey, TValue>クラスは、「キーによる高速な検索」と「順序を維持したコレクション」の両方を実現したいという時に嬉しいクラスです。

実は、.NET Frameworkには昔から、非ジェネリックなOrderedDictionaryがあったのですが、ジェネリックな順序を保持するDictionaryなクラスはなかなか公式ライブラリに登場しませんでした。


従来のSortedDictionary<TKey, TValue>と違い・

// もともとあったSortedDictionary<TKey, TValue>だと・・・
SortedDictionary<string, string> dictionary = new();
dictionary.Add("KeyC", "ValueC");
dictionary.Add("KeyA", "ValueA");
dictionary.Add("KeyB", "ValueB");

// 従来のSortedDictionary<TKey, TValue>だと、追加順序は保持されず次のように表示される。
// [KeyA, ValueA]
// [KeyB, ValueB]
// [KeyC, ValueC]
foreach (var keyValuePair in dictionary)
{
    Console.WriteLine(keyValuePair);
}

OrderedDictionary<TKey, TValue>を列挙すると、追加した順序を保持します。

// .NET 9から追加されたOrderedDictionary<TKey, TValue>だと・・・
OrderedDictionary<string, string> dictionary = new();
dictionary.Add("KeyC", "ValueC");
dictionary.Add("KeyA", "ValueA");
dictionary.Add("KeyB", "ValueB");

// 従来のOrderedDictionary<TKey, TValue>だと、追加順序が保持されて次のように表示される。
// [KeyC, ValueA]
// [KeyA, ValueC]
// [KeyB, ValueB]
foreach (var keyValuePair in dictionary)
{
    Console.WriteLine(keyValuePair);
}

なお、コレクション初期化子は内部でAddメソッドを読んでいるので、↑と↓は等価です。

OrderedDictionary<string, string> dictionary = new()
{
    { "KeyC", "ValueC" },
    { "KeyA", "ValueA" },
    { "KeyB", "ValueB" }
};

foreach (var keyValuePair in dictionary)
{
    Console.WriteLine(keyValuePair);
}

「キーによる高速な検索」と「順序を維持したコレクション」の両方を実現したい場合は、OrderedDictionary<TKey, TValue>が便利です。


以下に、OrderedDictionary<TKey, TValue>の特徴的なメソッドの利用例を示します。

GetAtで、指定したインデックスのKeyValuePair<TKey, TValue>を取得できます。

OrderedDictionary<string, string> dictionary = new()
{
    { "Key0", "Value0" },
    { "Key1", "Value1" },
    { "Key2", "Value2" }
};

var index1KeyValuePair = dictionary.GetAt(1);

// [Key1, Value1]と表示される。(インデックス0始まりで1個目のKeyValuePair要素)
Console.WriteLine(index1KeyValuePair);

RemoveAtで、指定したインデックスのKeyValuePair<TKey, TValue>を取り除けます。

OrderedDictionary<string, string> dictionary = new()
{
    { "Key0", "Value0" },
    { "Key1", "Value1" },
    { "Key2", "Value2" }
};

// インデックス1の要素を削除
dictionary.RemoveAt(1);

// 次のように表示される。
// [Key0, Value0]
// [Key2, Value2]
foreach (var keyValuePair in dictionary)
{
    Console.WriteLine(keyValuePair);
}

InsertAtで、指定したインデックスにキーとバリューの要素を挿入できます。

OrderedDictionary<string, string> dictionary = new()
{
    { "Key0", "Value0" },
    { "Key1", "Value1" },
    { "Key2", "Value2" }
};

// インデックス1に、要素をインサート
dictionary.Insert(1, "InsertedKey", "InsertedValue");

// [Key0, Value0]
// [InsertedKey, InsertedValue]
// [Key1, Value1]
// [Key2, Value2]
foreach (var keyValuePair in dictionary)
{
    Console.WriteLine(keyValuePair);
}

SetAtで指定したインデックスにキーとバリュー、もしくはバリューを上書きできます。

OrderedDictionary<string, string> dictionary = new()
{
    { "Key0", "Value0" },
    { "Key1", "Value1" },
    { "Key2", "Value2" }
};

// インデックス0のキーとバリューをセット
dictionary.SetAt(0, "KeyReplaced0", "ValueReplaced0");

// インデックス2のバリューだけセット
dictionary.SetAt(2, "ValueReplaced2");

// [KeyReplaced0, ValueReplaced0]
// [Key1, Value1]
// [Key2, ValueReplaced2]
foreach (var keyValuePair in dictionary)
{
    Console.WriteLine(keyValuePair);
}

IndexOfで指定したキーのインデックスを探索できます。

OrderedDictionary<string, string> dictionary = new()
{
    { "Key0", "Value0" },
    { "Key1", "Value1" },
    { "Key2", "Value2" }
};

// "Key0"のインデックスを探索
var indexOfKey0 = dictionary.IndexOf("Key0");

// 0
Console.WriteLine(indexOfKey0);

ちなみに、OrderedDictionary<TKey, TValue>は、IList<KeyValuePair<TKey, TValue>>を実装しています。

OrderedDictionary<string, string> orderedDictionary = new OrderedDictionary<string, string>
{
    { "KeyA", "ValueA" },
    { "KeyB", "ValueB" },
    { "KeyC", "ValueC" }
};

// OrderedDictionary<TKey, TValue>は、IList<KeyValuePair<TKey, TValue>>を実装している
// だから当然、これはOK
IList<KeyValuePair<string, string>> list = orderedDictionary;

// IList<KeyValuePair<string, string>>、intでの[]アクセスができる
KeyValuePair<string, string> elementIndex0 = list[1];

// OrderedDictionary<string, string>だと、TKeyであるstringでの[]アクセス
string valueWithKeyA = orderedDictionary["KeyA"];

普通のDictionary<TKey, TValue>は、当然IList<KeyValuePair<TKey, TValue>>を実装していません。それはそう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?