この記事では、Visual C# でカスタム コレクションを実装する方法について説明します。 Microsoft .NET Framework 基本クラス ライブラリは、コレクション System.Collections.ICollection
インターフェイスの正式な定義を提供します。
元の製品バージョン: Visual C#
元の KB 番号: 307484
カスタム クラスに ICollection インターフェイスを実装する
ICollection
インターフェイスは IEnumerable
インターフェイスを継承します。 ICollection
インターフェイスは、CopyTo
メソッドと 3 つの読み取り専用プロパティ (IsSynchronized
、SyncRoot
、およびCount
) を定義します。 ICollection
は、IEnumerable
インターフェイスから GetEnumerator
メソッドを継承します。 カスタム コレクション クラスは、 ICollection
インターフェイスを実装する必要があります。
ICollection
インターフェイスを実装するには、次の手順に従います。
Visual C# .NET で、Windows アプリケーションを作成します。
ソリューション エクスプローラーでプロジェクト名を右クリックし、Add をポイントし、[クラスの追加] をクリックしてクラスモジュールCustomCollectionを追加します。
クラス モジュールの先頭に次のサンプル コードを追加して、
System.Collection
名前空間をインポートします。using System.Collections;
モジュール内の他のコードを次のサンプル コードに置き換えます。
public class CustomCollection : ICollection { private int[] intArr = {1,5,9}; private int Ct; public CustomCollection() { Ct=3; } }
わかりやすくするために、
CustomCollection
クラスは、3 つの整数項目と count 変数を持つ配列を保持します。整数配列とインデックスをパラメーターとして受け取る
CopyTo
メソッドを実装します。 このメソッドは、渡されたインデックスから始まる配列にコレクション内の項目をコピーします。 このメソッドを実装するには、パブリックCustomCollection
コンストラクターの後に次のコードを貼り付けます。void ICollection.CopyTo(Array myArr, int index) { foreach (int i in intArr) { myArr.SetValue(i,index); index = index+1; } }
IEnumerable
からICollection
インターフェイスによって継承されるGetEnumerator
メソッドを実装します。GetEnumerator
メソッドは、コレクションを反復処理できるEnumerator
オブジェクトを返します。CopyTo
メソッドの後に次のサンプル コードを貼り付けます。IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(intArr); }
3 つの読み取り専用プロパティを実装するには、
GetEnumerator
メソッドの後に次のコードを貼り付けます。// The IsSynchronized Boolean property returns True if the // collection is designed to be thread safe; otherwise, it returns False. bool ICollection.IsSynchronized { get { return false; } } // The SyncRoot property returns an object, which is used for synchronizing // the collection. This returns the instance of the object or returns the // SyncRoot of other collections if the collection contains other collections. object ICollection.SyncRoot { get { return this; } } // The Count read-only property returns the number // of items in the collection. int ICollection.Count { get { return Ct; } }
GetEnumerator メソッドの列挙子オブジェクトを実装する
このセクションでは、CustomCollection
を反復処理できるEnumerator
クラスを作成する方法について説明します。
クラス モジュールの end クラス ステートメントの後に、次のサンプル コードを貼り付けます。
public class Enumerator : IEnumerator { private int[] intArr; private int Cursor; }
GetEnumerator
メソッドが呼び出されたときに、CustomCollection
クラスの要素を保持するintArr
プライベート整数配列を宣言します。Cursor
フィールド メンバーは、列挙中に現在の位置を保持します。パラメーターとして
intArr
を持つコンストラクターを追加し、ローカルintArr
をこれに設定します。 メンバー フィールドの宣言の後に、次のサンプル コードを貼り付けます。public Enumerator(int[] intarr) { this.intArr = intarr; Cursor = -1; }
Reset
およびMoveNext
メソッドを実装します。 これを行うには、コンストラクターの後に次のコードを貼り付けます。void IEnumerator.Reset() { Cursor = -1; } bool IEnumerator.MoveNext() { if (Cursor < intArr.Length) Cursor++; return(!(Cursor == intArr.Length)); }
Reset
Cursor
を -1 に設定しMoveNext
Cursor
を次の要素に移動します。MoveNext
成功した場合はTrue を返します。Cursor
が指す項目を返すCurrent
読み取り専用プロパティを実装します。Cursor
が -1 の場合、InvalidOperationException
が生成されます。MoveNext
メソッドの後に次のコードを貼り付けます。object IEnumerator.Current { get { if((Cursor < 0) || (Cursor == intArr.Length)) throw new InvalidOperationException(); return intArr[Cursor]; } }
for each を使用してカスタム コレクションを反復処理する
Form1.csの Design タブで、ボタンをフォームにドラッグします。
ボタンをダブルクリックし、ボタンの
Click
イベントに次のサンプル コードを追加します。CustomCollection MyCol = new CustomCollection(); foreach (object MyObj in MyCol) MessageBox.Show(MyObj.ToString());
F5 キーを押してアプリケーションを実行し、ボタンをクリックします。
Note
メッセージ ボックスには、カスタム コレクション内の項目が表示されます。
この処理のしくみ 各呼び出しでは、 GetEnumerator
メソッドを呼び出して Enumerator
オブジェクトを作成し、 MoveNext
メソッドを呼び出して、 Cursor
を最初の項目に設定します。 その後、現在のプロパティにアクセスして、 MyObj
内の項目を取得します。 これは、 MoveNext
が False を返すまで繰り返されます。