ここではIEnumeratorインターフェイスを実装し foreachに対応した自作クラスを作成するコードを紹介します。
IEnumerable インターフェイスを実装すると foreach文に対応できます。
IEnumerable インターフェイスをクラスに実装する場合は、IEnumerator.GetEnumerator()
メソッドをクラスに実装する必要があります。
GetEnumerator() メソッドは IEnumerator オブジェクトを返します。 IEnumerator オブジェクトインターフェイスを実装した
MyClassProcクラスでは、MoveNext
Reset
Current
IEnumerator.Current
を実装します。
フォームのコードは下記です。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CustomIEnumerator
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MyClass m = new MyClass();
foreach (int i in m) {
textBox1.Text += Convert.ToString(i)+"\r\n";
}
}
}
}
フォームから参照される MyClass クラスの実装です。
using System.Collections;
namespace CustomIEnumerator
{
class MyClass : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
return new MyClassProc();
}
}
}
IEnumeratorインターフェイスを実装した MyClassProc クラスのコードです。
using System.Collections;
namespace CustomIEnumerator
{
class MyClassProc : IEnumerator
{
int index;
public bool MoveNext()
{
index++;
if (10 < index)
{
return false;
}
else
{
return true;
}
}
public void Reset()
{
index = 0;
}
object IEnumerator.Current
{
get
{
return index;
}
}
}
}
IEnumerableインターフェイスの定義(規約)は下記コードです。
IEnumerableインターフェイスを実装したクラスでは、GetEnumerator()
メソッドの実装が必要です。
public interface IEnumerable
{
[Pure]
[DispId(-4)]
IEnumerator GetEnumerator();
}
IEnumerableインターフェイスを実装した、MyClass では、GetEnumerator() メソッドを実装します。
GetEnumerator() メソッドは、IEnumerator インターフェイスをを実装したオブジェクトを返します。
今回の例では、IEnumerator インターフェイスを実装した MyClassProc クラスを返します。
class MyClass : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
return new MyClassProc();
}
}
なお、次のコードでも問題ないです。
class MyClass : IEnumerable
{
public IEnumerator GetEnumerator()
{
return new MyClassProc();
}
}
MyClassProcクラスでは、MoveNext
Reset
Current
IEnumerator.Current
を実装します。
MoveNextメソッドでは、indexカウンタを増加します。カウンタの値が10以下であれば、false
を返し、次の要素があることを示します。
10以上の場合は、true
を返し要素がないことを示します。
MyClass を foreach文でループした場合、10までループして終了する動作になります。
public bool MoveNext()
{
index++;
if (10 < index)
{
return false;
}
else
{
return true;
}
}
Resetメソッドではカウンタの値を0に戻します。
public void Reset()
{
index = 0;
}
Currentプロパティでは現在のインデックスの値を返します。
public int Current
{
get
{
return index;
}
}
object IEnumerator.Current
{
get
{
return index;
}
}
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。テキストボックスに結果が表示されます。