*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

C# にて、yield return を使わないでIEnumeratorとIEnumerableを実装<ジェネリック コレクション>


*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*


「C# にて、反復子を作成する方法<インターフェイス版>」における一連の説明(知恵ノート)において、ここでは、「yield return を使わないでIEnumeratorとIEnumerableを実装<ジェネリック コレクション>」について説明します。






総合の目次


本ページを含めた関連事項の総合目次です。

「C# にて、反復子を作成する方法<インターフェイス版>」
http://note.chiebukuro.yahoo.co.jp/detail/n130200






関連サンプル


本サンプルと関連性のあるサンプルです。
すなわち、前回のサンプルです。

<ステップ1>
「yield return を使わないforeach 文対応クラスの作成<非ジェネリック コレクション>」


http://note.chiebukuro.yahoo.co.jp/detail/n136220

<ステップ2>
「yield return を使わないforeach 文対応クラスの作成<ジェネリック コレクション>」

http://note.chiebukuro.yahoo.co.jp/detail/n136221

<ステップ3>
「yield return を使わないでIEnumeratorとIEnumerableを実装<非ジェネリック コレクション>」
前回のサンプルです。

http://note.chiebukuro.yahoo.co.jp/detail/n136222

<ステップ4>
「yield return を使わないでIEnumeratorとIEnumerableを実装<ジェネリック コレクション>」

 

今回のサンプルです。

<ステップ5以降>
その他にも関連サンプルは続きます。
(後程改めて紹介します))




はじめに


<IEnumeratorインターフェイス>
IEnumeratorインターフェイスは、反復処理をサポートするためのインターフェイスです。
すなわち、反復処理を行なうコレクションその物を定義するためのインターフェイスです。
よって、このインターフェイスを実装したクラスを作るには、カレント要素(現在の要素位置)を示すプロパティや、カレント要素を次の要素に移動するメソッド等を用意します。

 

<IEnumerableインターフェイス>
上記のIEnumeratorインターフェイスを実装したクラスは、foreach文に対応していません。
foreach文に対応しているのは、IEnumerableインターフェイスです。
すなわち、IEnumerableインターフェイスは、反復処理をサポートする列挙子を公開するインターフェイスです。

<本サンプル>
本サンプルでは、上記におけるIEnumeratorジェネリック版インターフェイスと、IEnumerableジェネリック版インターフェイスを実装するクラスを作ります。






C# 言語仕様へのyield return 文の追加について


反復処理の関連サンプルでの、最初のほうから出て来た yield return 文や yield break 文は、C# 2.0 から追加された機能です(Visual C# のバージョンで言えば、Visual C#2005 から追加された機能。.NET Framework のバージョンで言えば、.NET Framework 2.0 から追加された機能)。
すなわち、それ以前のバージョンでは、yield return 等は、使えませんでした。
ところで、Python と言う言語にも、C# の yield return 文に該当する yield 文があります。
また、C# の「反復子ブロック」は、Python では、「ジェネレータ関数」と言います。
Python でも最初からあった機能ではなく、Python 2.3 から追加された機能です。
なお、Python 2.3 は、C# 2.0 よりも古いので、おそらくC# のyield return 文関係の機能(反復子ブロック関係の機能)は、Python から影響したものです。
yield return 文関係の機能(反復子ブロック関係の機能)は、関連サンプルの最初のほうでわかる通り、反復処理の定義(foreach 文に対応させるための定義)を簡単にします。
そして、今回のサンプルでは、その yield return 文を使わない場合のサンプルを用意しています。
よって、今回のサンプルを見て、yield return 文を使っていた今までのサンプルが、いかに簡単であったのかを実感して下さい。

と言いましても、今までのサンプルを見ていれば、今回のサンプルの内容は、十分に理解することが可能なレベルです。
よって、「今まで手順を踏んで関連サンプルを見てきたから、今回のサンプルは良くわかるが、ストレートに本サンプルを見たら、わかり辛い人もいるだろうな」と言う程度に解釈して下さい。




関連サンプルと比べた特徴


一連の関連サンプルでは、foreach文に対応する反復子クラスの作成方法を紹介しています。
具体的内容は、下記の通りです。

<ステップ1>
「yield return を使わないforeach 文対応クラスの作成<非ジェネリック コレクション>」

反復子関係の機能を搭載したものです。
また、反復子用のインターフェイスIEnumerableを実装しています。
なお、yield return 文は、使いません。

<ステップ2>
「yield return を使わないforeach 文対応クラスの作成<ジェネリック コレクション>」

上記「ステップ1」と同様に、反復子関係の機能を搭載したものです。
すなわち、IEnumerableインターフェイスを実装したクラスを作ります。
ただし、上記「ステップ1」は、非ジェネリック のインターフェイスを実装しています。
これに対して本件「ステップ2」は、ジェネリック のインターフェイスを実装しています。
なお、yield return 文は、使いません。

<ステップ3>
「yield return を使わないでIEnumeratorとIEnumerableを実装<非ジェネリック コレクション>」

反復処理を行なうクラスを作ります。
具体的には、反復処理サポートクラス用のインターフェイスIEnumeratorを実装したクラスを作ります。
しかし、上記のIEnumeratorインターフェイスは、foreach文に対応していません。
ちなみに、foreach文に対応しているのは、IEnumerableインターフェイスです。
よって、IEnumeratorインターフェイスを使う場合は、foreach文に対応させるために、IEnumerableインターフェイスも共に実装する場合が多いです。
本件「ステップ3」は、そのように、IEnumeratorインターフェイスとIEnumerableインターフェイスを実装したクラスを作ります。
なお、yield return 文は、使いません。

<ステップ4>
「yield return を使わないでIEnumeratorとIEnumerableを実装<ジェネリック コレクション>」

上記「ステップ3」と同様に、IEnumeratorインターフェイスとIEnumerableインターフェイスを実装したクラスを作ります。
ただし、上記「ステップ3」は、非ジェネリック のインターフェイスを実装しています。
これに対して本件「ステップ4」は、ジェネリック のインターフェイスを実装しています。
なお、yield return 文は、使いません。

<ステップ5以降>
その他にも反復子の関連サンプルは続きます。
しかし、ステップ5以降のサンプルの概要を、ここで説明すると混乱するだけです。
よって、ステップ5以降の概要は、後のステップ5で説明します。





サンプルコード


ここで取り上げるサンプルは、なるべく複雑にならない範囲で、反復処理をサポートするクラスを確かめられるものとします。






本サンプの仕様概要


ただ単純に、foreach 文で人の名前を並べるだけの仕様とします。



フォームデザイン等の前準備


コードを記述する前に、フォームのデザイン作成などの、以下の前準備を行なって下さい。

<プロジェクトの作成>
本サンプルの確認用に、新規にプロジェクトを作成して下さい。
プロジェクトの種類は、「Windowsフォームアプリケーション」です。

<フォームのデザイン>
デザイン画面で、テキストボックス(TextBox)を1個と、ボタン(button)を1個貼り付けて下さい。


デザイン画面

 





<テキストボックスの複数行化>
テキストボックスは、デフォルトでは1行用になっています。
しかし、本サンプルでは、複数行の文字を扱いたいので、以下の操作で、テキストボックスを複数行対応にして下さい。
まず、先程貼り付けたテキストボックス textBox1 を選択状態にして下さい(すなわち、デザイン画面上のテキストボックス textBox1 をクリックする)。
そうすると、テキストボックスの右上に、小さな三角形のマークが表示されます。
それをクリックすると Multiline と言う表記のチェックボックスが表示されます。
そのチェックボックスにチェックを入れると、複数行対応になります。
あとは、デザイン画面のチェックボックスをマウス操作で、縦幅を広げて下さい。



テキストボックス三角

<イベントプロシージャの作成>
デザイン画面のフォーム(無地の部分)をダブルクリックして、Form1_Load() メソッド を作って下さい。
また、デザイン画面で先ほど貼り付けたボタン1(button1)をダブルクリックして、button1_Click() メソッドを作って下さい。


<クラスを書くためのソースファイルの作成>
[プロジェクト] - [クラスの追加] で、「新しい項目の追加」画面を表示する。
その画面の [ファイル名]欄に任意のファイル名(クラス用ソースファイルのファイル名)を記入する。
[追加]ボタンをクリックする。

なお、ここで作成されたソースファイルには、後述しますクラスのコード(「カウンタークラスのコード」のコード)を記述します。。







製品列挙クラスのコード


http://note.chiebukuro.yahoo.co.jp/detail/n141885


(記述量上限の制限で、別のページに記述しています)


Formクラスのコード


http://note.chiebukuro.yahoo.co.jp/detail/n141886

(記述量上限の制限で、別のページに記述しています)




コードの解説


今までのサンプルで解説して来た通りです。
ただし、今回は、IEnumerable インターフェイスを実装しています。
それ以外は、今までのサンプルで解説した通りです。





実行結果


ボタンをクリックすると、foreach 文で人の名前が並べられます。



実行結果

 






さいごに


今まで取り上げてきたサンプルを、インターフェイス実装の形式にしただけです。
よって、特に最後に述べることはありません。