チュートリアル: Visual Basic での IEnumerable(Of T) の実装
この記事の内容
IEnumerable<T> インターフェイスは、クラスに実装し、一連の値を一度に 1 項目ずつ返すことができるようにします。 データを一度に 1 項目ずつ返す利点は、データを処理するために、データ全体のセットをメモリに読み込む必要がないことです。 単一の項目をデータから読み込むために必要なメモリしか使用する必要がありません。 IEnumerable(T) インターフェイスを実装するクラスは、For Each ループまたは LINQ クエリで使用できます。
例として、大きなテキスト ファイルを読み込み、特定の検索条件と一致する各行をファイルから返すアプリケーションを考えます。 このアプリケーションでは、指定した条件と一致する行をファイルから返すために、LINQ クエリを使用します。 LINQ クエリを使用してファイルの内容を照会するために、アプリケーションはファイルの内容を配列またはコレクションに読み込みます。 しかし、ファイル全体を配列またはコレクションに読み込むと、必要なメモリ量よりはるかに多く消費することになります。 そうする代わりに、LINQ クエリでは、列挙可能なクラスを使用することで、検索条件と一致する値のみを返すようにファイルの内容を照会できます。 何件かの一致する値のみを返すクエリであれば、消費するメモリ量は格段に少なくて済みます。
IEnumerable<T> インターフェイスを実装するクラスを作成し、ソース データを列挙可能なデータとして公開できます。 この IEnumerable(T) インターフェイスを実装するクラスは、ソース データ全体を反復処理するために、IEnumerator<T> インターフェイスを実装する別のクラスを必要とします。 これら 2 つのクラスを使用することで、データ項目を特定の型として順次返すことができます。
このチュートリアルでは、テキスト ファイルを一度に 1 行ずつ読み取るための、IEnumerable(Of String) インターフェイスを実装するクラスと、IEnumerator(Of String) インターフェイスを実装するクラスを作成します。
注意
お使いのマシンで、Visual Studio ユーザー インターフェイスの一部の要素の名前や場所が、次の手順とは異なる場合があります。 これらの要素は、使用している Visual Studio のエディションや独自の設定によって決まります。 詳細については、「Visual Studio の設定 」を参照してください。
列挙可能なクラスの作成
列挙可能なクラス プロジェクトを作成するには
Visual Basic で、[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
[新しいプロジェクト] ダイアログ ボックスの [プロジェクトの種類] ペインで、[Windows] が選択されていることを確認します。 [テンプレート] ペインで [クラス ライブラリ] をクリックします。 [プロジェクト名] ボックスに「StreamReaderEnumerable」と入力し、[OK] をクリックします。 新しいプロジェクトが表示されます。
ソリューション エクスプローラー で、Class1.vb ファイルを右クリックし、[名前の変更] をクリックします。 ファイルの名前を StreamReaderEnumerable.vb に変更し、Enter キーを押します。 ファイルの名前を変更すると、クラスの名前も StreamReaderEnumerable に変更されます。 このクラスは、IEnumerable(Of String) インターフェイスを実装します。
StreamReaderEnumerable プロジェクト ノードを右クリックし、[追加] をポイントして、[新しい項目] をクリックします。 [クラス] テンプレートを選択します。 [プロジェクト名] ボックスに「StreamReaderEnumerator.vb」と入力し、[OK] をクリックします。
このプロジェクトの最初のクラスは列挙可能なクラスであり、IEnumerable(Of String) インターフェイスを実装します。 このジェネリック インターフェイスが IEnumerable インターフェイスを実装し、このクラスのコンシューマーが String 型に設定された値にアクセスできることを保証します。
IEnumerable を実装するコードを追加するには
StreamReaderEnumerable.vb ファイルを開きます。
Public Class StreamReaderEnumerable の後の行に次のように入力し、Enter キーを押します。
Visual Basic により、クラスに IEnumerable(Of String) インターフェイスで必要なメンバーが自動的に設定されます。
この列挙可能なクラスは、テキスト ファイルから一度に 1 行ずつ読み取ります。 ファイルのパスを入力パラメーターとして取得するパブリック コンストラクターを公開するため、次のコードをクラスに追加します。
IEnumerable(Of String) インターフェイスの GetEnumerator メソッドの実装は、StreamReaderEnumerator クラスの新しいインスタンスを返します。 IEnumerable インターフェイスの GetEnumerator メソッドの実装は、IEnumerable(Of String) インターフェイスのメンバーのみを公開すればよいため、Private にすることができます。 GetEnumerator メソッドに対して Visual Basic で生成されたコードを、次のコードに置き換えます。
IEnumerator を実装するコードを追加するには
StreamReaderEnumerator.vb ファイルを開きます。
Public Class StreamReaderEnumerator の後の行に次のように入力し、Enter キーを押します。
Visual Basic により、クラスに IEnumerator(Of String) インターフェイスで必要なメンバーが自動的に設定されます。
列挙子クラスがテキスト ファイルを開き、ファイル I/O を実行してファイルの行を読み取ります。 ファイルのパスを入力パラメーターとして取得し、読み取りのためにテキスト ファイルを開くパブリック コンストラクターを公開するため、次のコードをクラスに追加します。
IEnumerator(Of String) インターフェイスおよび IEnumerator インターフェイスの両方の Current プロパティは、テキスト ファイルから現在の項目を String として返します。 IEnumerator インターフェイスの Current プロパティの実装は、IEnumerator(Of String) インターフェイスのメンバーのみを公開すればよいため、Private にすることができます。 Current プロパティに対して Visual Basic で生成されたコードを、次のコードに置き換えます。
IEnumerator インターフェイスの MoveNext メソッドはテキスト ファイル内の次の項目に移動し、Current プロパティで返される値を更新します。 読み取る項目がなくなった場合、MoveNext メソッドは False を返し、それ以外の場合、MoveNext メソッドは True を返します。 MoveNext メソッドに次のコードを追加します。
IEnumerator インターフェイスの Reset メソッドは、テキスト ファイルの最初をポイントするように反復子を移動し、現在の項目の値を消去します。 Reset メソッドに次のコードを追加します。
IEnumerator インターフェイスの Dispose メソッドは、反復子が破棄される前に、すべてのアンマネージ リソースがリリースされることを保証します。 StreamReader オブジェクトで使用されるファイル ハンドルはアンマネージ リソースであり、反復子インスタンスが破棄される前に閉じる必要があります。 Dispose メソッドに対して Visual Basic で生成されたコードを、次のコードに置き換えます。
サンプル反復子の使用
列挙可能なクラスは、For Next ループや LINQ クエリなどの IEnumerable を実装するオブジェクトを必要とするコントロール構造体と一緒にコード内で使用することができます。 次の例は、LINQ クエリ内の StreamReaderEnumerable を示しています。
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()
参照
参照
For Each...Next ステートメント (Visual Basic)
概念
Visual Basic における LINQ の概要
ループ構造 (Visual Basic)
その他の技術情報
Visual Basic における制御フロー