System.Collections.Specialized.OrderedDictionaryクラスはインデックスによるアクセスとキーによるアクセスの両方をサポートするディクショナリ(ハッシュテーブル)です。 OrderedDictionaryに類似したディクショナリを構成するクラスとしてHashtableやDictionary<TKey, TValue>、SortedDictionary<TKey, TValue>がありますが、これらのクラスと比較するとOrderedDictionaryには次のような違いがあります。
特徴 | OrderedDictionary | Hashtable | Dictionary | SortedDictionary |
---|---|---|---|---|
インデックスによるアクセス | できる | できない | できない | できる |
列挙したときの順序 | 要素を追加した順 | (不定) | (不定) | ソートされた順序 |
ジェネリック | 非ジェネリック型 | ジェネリック型 | ||
キー/値のペアを格納する型 | DictionaryEntry | KeyValuePair |
OrderedDictionaryは、インデックスによるアクセスができるディクショナリが必要な場合、特に追加した順序を維持するようなディクショナリが必要な場合に有用なコレクションクラスです。 ただし、OrderedDictionaryは非ジェネリックなコレクションクラスであるため、安全に扱うには注意を要します。
追加したときの順序が維持されることが重要で、キーによるアクセスが不要なのであればList<KeyValuePair<TKey, TValue>>
、インデックスによるアクセスができれば列挙した時の順序は特に意識しないのであればSortedDictionary<TKey, TValue>
によって代用することができます。
OrderedDictionary
OrderedDictionaryはインデックスによるアクセスが可能なディクショナリです。 名前の通り順序を持ったディクショナリで、要素を追加すると個々の要素に追加した順でインデックスが割り振られます。 OrderedDictionaryに格納される値は、キーとインデックスの両方で参照できるとも言えます。
インデックス | キー | 値 |
---|---|---|
0 | "foo" | 36 |
1 | "bar" | 7 |
2 | "foo" | 42 |
: : |
: : |
: : |
OrderedDictionaryへの要素の追加・設定はHashtableクラスやDictionaryクラスと同様に、インデクサあるいはAddメソッドによって行います。 一方、キーだけでなくインデックスによって対応する値にアクセスできる点、foreachなどによって列挙した場合にインデックスの順(=追加された順)で列挙されることがクラスの動作として保証されている点が、HashtableやDictionaryとは異なります。
Dictionaryクラスでは、列挙される際の順序は未定義とされていて、要素が追加された順序になるとは限らない旨が記載されています。 詳しくはジェネリックコレクション(2) Dictionary §.要素の列挙と順序を参照してください。
インデックスを指定した挿入・削除
OrderedDictionaryでは個々の要素がインデックスを持つことから、インデックスを指定することによって位置を指定した挿入・削除を行うことができます。
挿入 (Insert)
Insertメソッドを使うと、インデックスで指定した位置へ要素を挿入することができます。 この操作はインデックスを割り当てた上での追加と見ることもできます。 インデックスとして現在の要素数(=最後のインデックス+1)を指定すれば、末尾へと挿入することができます。 それを超える範囲に追加しようとした場合は例外ArgumentOutOfRangeExceptionがスローされます。
削除 (RemoveAt)
RemoveAtメソッドを使うと、インデックスで指定した位置にある要素を削除することができます。 要素の削除を行うと、それに伴い要素に割り当てられるインデックスも変わります。 削除を行っても追加された際の前後関係は維持されますが、インデックスは変化します。
インデックスに対応するキーの取得
OrderedDictionary.KeysプロパティはICollectionとなっているため、このプロパティを使ってインデックスに対応するキーを取得するといったことができません。
こういった操作を行う場合は、Keysプロパティの内容をCopyToメソッドによっていったん配列へとコピーしてから行う必要があります。
IOrderedDictionaryインターフェイス
OrderedDictionaryはIOrderedDictionaryインターフェイスを実装しています。 このインターフェイスはIDictionaryインターフェイスを継承しています。
IOrderedDictionaryには、IDictionaryの持つ機能に加えて、インデックスおよびキーを指定することができるインデクサ、Insertメソッド、RemoveAtメソッドの定義が追加されています。
.NET Frameworkのクラスライブラリでは、IOrderedDictionaryインターフェイスが実装されているクラスはOrderedDictionary以外に存在せず、System.Web.dllの一部で戻り値や引数として周辺でIOrderedDictionaryが使われている程度です。
ジェネリックバージョンのOrderedDictionary
Hashtableのジェネリック版として対応するDictionary<TKey, TValue>のように、OrderedDictionaryのジェネリック版として対応するようなOrderedDictionary<TKey, TValue>といったクラスは.NET Framework 4.6時点でも存在しません。 必要な場合は独自に実装する必要があります。
このようなジェネリックバージョンのOrderedDictionaryを実装した具体例をジェネリック版OrderedDictionaryにて掲載しています。