C# コレクションクラスを自作してみる(1/2)

   

C# でカスタム(自作)のコレクションクラスを実装する方法を試してみます。
.NET Framework の基本クラス ライブラリは、System.Collections.ICollection インターフェイスというクラスを用いて作成します。

ただ、カスタムのコレクションクラスを作るには、コレクションクラスそのもの以外にも必要なものがあります。

まずは準備です。

 

コレクションで管理するクラスの作成

実際にコレクションに追加・アクセス・取得などを行うためのクラスを作成します。
今回は、Nameプロパティ1つしかないとても単純なクラスにしておきます。

 

 カスタムのコレクションクラス本体の作成

コレクションクラス本体を作成しますが、ここがコレクションクラスを自作するときに悩ませてくれる部分です。

ICollectionインターフェースクラスの派生クラスとしてコレクションクラスを作成すると、下記のものを実装する必要があります。

  • int ICollection.Countプロパティ
  • object ICollection.SyncRootプロパティ
  • bool ICollection.IsSynchronizedプロパティ
  • void ICollection.CopyTo(Array list, int index)メソッド
  • IEnumerator IEnumerable.GetEnumerator()メソッド

 

が必要となります(インターフェースクラスなのでこれは必須です)。

この中で一番困るのが”IEnumerator IEnumerable.GetEnumerator()メソッド”です。

最初は、「ICollectionの派生クラスは作るんだけど、この”IEnumerator”とか”IEnumerable”ってなんだ?」となります。
ですが、これはコレクションを使う上でとても大事なものなんです。

MSDNの説明には、

IEnumerableインターフェース 非ジェネリック コレクションに対する単純な反復処理をサポートする列挙子を公開します。
IEnumerator インターフェイス 非ジェネリック コレクションに対する単純な反復処理をサポートするためのインターフェース。

 

とあります。「単純な反復処理」って何?と思うかもしれませんが、一番見慣れている反復処理は「foreach文」があります。

IEnumerableクラスは、実はICollectionクラスの基本クラスなんです。
ですのでICollectionクラスを継承するクラスは、”IEnumerator IEnumerable.GetEnumerator()”も実装しなければいけません。

ここでさらに1つ疑問がおきます。

 

IEnumerable.GetEnumerator()の戻り値”IEnumerator”って何を返せばいいの?

IEnumeratorはインターフェースクラスです。

インターフェースは提供しますが、そのままのクラスでインスタンスを生成したりはできません。
ICollectionを派生してコレクションを作るときには、もれなくこの「“IEnumeratorクラス”の派生クラス」も作らなくてはいけないんです。

 

IEnumeratorインターフェースの派生クラスを作る

IEnumeratorインターフェースの派生クラスでは

  • object IEnumerator.Currentプロパティ
  • void IEnumerator.Reset()メソッド
  • bool IEnumerator.MoveNext()メソッド

を実装しなくてはいけません。

IEnumeratorインターフェースの派生クラスとして”Enumerator”クラスを実装すると下記のようになります。

 

次回は、これらのクラスを使ってコレクションクラスを実装して、動かしてみます。

 

 - 未分類