ここでは、これまでに解説していないその他のコレクションクラス、及びコレクションに関連する操作について解説します。

その他のコレクションクラス

(未整理)
以下は、ここまでで解説していないコレクションクラスの一部です。

コレクションクラス(抜粋)
クラス 類似するクラス 基底クラスまたは実装するインターフェイス(抜粋) 備考
System.Collections名前空間
ReadOnlyCollectionBase ReadOnlyCollection ICollection 読み取り専用コレクションを作成するための抽象クラス
DictionaryBase Dictionary IDictionary, ICollection ディクショナリを作成するための抽象クラス
System.Collections.Generic名前空間
KeyedByTypeCollection<TItem> KeyedCollection<Type, TItem> KeyedCollection<Type, TItem> System.Typeをキーとして使用するKeyedCollection
SynchronizedCollection<T> Collection<T> IList<T>, ICollection<T>, IList, ICollection スレッドセーフなコレクション
スレッドセーフなラッパーとして動作するのではなく、個別のコレクションとして動作する
SynchronizedReadOnlyCollection<T> ReadOnlyCollection<T> IList<T>, ICollection<T>, IList, ICollection スレッドセーフな読み取り専用コレクション
スレッドセーフなラッパーとして動作するのではなく、読み取り専用の個別のコレクションとして動作する
SynchronizedKeyedCollection<K, T> KeyedCollection<K, T> SynchronizedCollection<T> スレッドセーフなコレクション
キーとインデックス両方でのアクセスが出来る
スレッドセーフなラッパーとして動作するのではなく、個別のコレクションとして動作する
System.Collections.Concurrent名前空間
ConcurrentBag<T> List<T> IProducerConsumerCollection<T>, ICollection スレッドセーフなコレクション
インデックスや順序の概念は無く、コレクションへの追加のみができる
ConcurrentDictionary<TKey, TValue> Dictionary<TKey, TValue> IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection スレッドセーフなディクショナリ
ConcurrentQueue<T> Queue<T> IProducerConsumerCollection<T>, ICollection スレッドセーフなキュー
ConcurrentStack<T> Stack<T> IProducerConsumerCollection<T>, ICollection スレッドセーフなスタック
System.Collections.Specialized名前空間
ListDictionary Hashtable IDictionary, ICollection 単方向リストによるIDictionaryの実装
HybridDictionary Hashtable IDictionary, ICollection 要素数が少ない場合はListDictionaryを使い、多くなった場合はHashtableに切り替える
NameObjectCollectionBase KeyedCollection<String, TItem> ICollection 文字列をキーとして使用できるコレクション
NameValueCollection Dictionary<String, String[]> NameObjectCollectionBase 文字列をキーとして使用し、文字列の配列を格納できるコレクション
OrderedDictionary SortedList IOrderedDictionary, IDictionary, ICollection キーとインデックス両方でのアクセスが出来るが、要素のソートはされない
StringCollection List<String> IList, ICollection IComparerやIEqualityComparerは指定できない
大文字小文字の違いは区別される
StringDictionary Dictionary<String, String> IComparerやIEqualityComparerは指定できない
大文字小文字の違いは無視される
System.ComponentModel名前空間
BindingList<T> Collection Collection<T>, IBindingList, IList, ICollection BindingSourceなどと組み合わせて使用する
クラス 類似するクラス 基底クラスまたは実装するインターフェイス(抜粋) 備考

ArrayListとIList

(未整理)

読み取り専用・固定サイズのIList

ReadOnlyメソッドを用いることで読み取り専用のIListを作成出来ます。 読み取り専用のIListでは、要素の追加・削除・挿入・値の設定が出来なくなり、IList.IsReadOnlyプロパティはtrueを返すようになります。 また、FixedSizeメソッドを用いると固定サイズのIListを作成出来ます。 固定サイズのIListでは、追加・削除・挿入は出来なくなりますが、値の設定は出来、IList.IsFixedSizeプロパティはtrueを返すようになります。 読み取り専用もしくは固定サイズのArrayListに対して追加や削除などの操作を行おうとすると、例外NotSupportedExceptionがスローされます。 読み取り専用・固定サイズのIListは、配列などIList非ジェネリックインターフェイスを実装するコレクションから作成することが出来ます。

using System;
using System.Collections;

class Sample {
  static void Main()
  {
    int[] intArray = new int[] {1, 2, 3};

    // 読み取り専用のIListを作成する
    IList readOnlyArray = ArrayList.ReadOnly(intArray);

    Print(readOnlyArray);

    try {
      readOnlyArray.Add(4);
    }
    catch (NotSupportedException) {
      Console.WriteLine("Add => NotSupportedException");
    }

    try {
      readOnlyArray[1] = 5;
    }
    catch (NotSupportedException) {
      Console.WriteLine("Set => NotSupportedException");
    }
  }

  static void Print(IList arr)
  {
    for (int i = 0; i < arr.Count; i++) {
      Console.Write("{0}, ", arr[i]);
    }

    Console.WriteLine();
  }
}
実行結果
intArray.IsReadOnly: False
readOnlyArray.IsReadOnly: True
1, 2, 3, 
Add => NotSupportedException
Set => NotSupportedException
using System;
using System.Collections;

class Sample {
  static void Main()
  {
    ArrayList list = new ArrayList(new int[] {1, 2, 3});

    // 固定サイズのIListを作成する
    IList fixedSizeList = ArrayList.FixedSize((IList)list);

    Console.WriteLine("list.IsFixedSize: {0}", list.IsFixedSize);
    Console.WriteLine("fixedSizeList.IsFixedSize: {0}", fixedSizeList.IsFixedSize);

    Print(fixedSizeList);

    try {
      fixedSizeList.Add(4);
    }
    catch (NotSupportedException) {
      Console.WriteLine("Add => NotSupportedException");
    }

    fixedSizeList[1] = 5;

    Print(fixedSizeList);
  }

  static void Print(IList arr)
  {
    for (int i = 0; i < arr.Count; i++) {
      Console.Write("{0}, ", arr[i]);
    }

    Console.WriteLine();
  }
}
実行結果
list.IsFixedSize: False
fixedSizeList.IsFixedSize: True
1, 2, 3, 
Add => NotSupportedException
1, 5, 3, 

IListからのArrayListの作成

Adapterメソッドを用いることで、任意のIListをラップしたArrayListを作成することが出来ます。 これにより、IListを実装するコレクションのラッパーを作り、ArrayListとして操作することが出来ます。

例えば、System.ObjectModel.Collection<T>クラスはIListインターフェイスを実装しているものの、Sortメソッドは用意されていないので、ArrayListのラッパーを作ってからSortメソッドを呼び出すことでソートを行うことが出来ます。

using System;
using System.Collections;
using System.Collections.ObjectModel;

class Sample {
  static void Main()
  {
    Collection<int> col = new Collection<int>(new int[] {1, 4, 0, 2, 3});

    Print(col);

    // col.Sort(); // Collection<T>.Sortメソッドは存在しない

    // ArrayListのラッパーを作る
    ArrayList list = ArrayList.Adapter(col);

    list.Sort(); // ArrayList.Sortメソッドでソートする

    Print(col);
  }

  static void Print(IList arr)
  {
    for (int i = 0; i < arr.Count; i++) {
      Console.Write("{0}, ", arr[i]);
    }

    Console.WriteLine();
  }
}
実行結果
1, 4, 0, 2, 3, 
0, 1, 2, 3, 4,