IEnumerable<T>, IEnumerator<T> インターフェイスを実装しforeachに対応したクラスを作成する - C#
IEnumerable<T>, IEnumerator<T>インターフェイスを実装した独自のクラスを作成し、foreachに対応します。
概要
こちらの記事ではIEnumeratorインターフェイスを実装しforeachに対応したクラスを作成するコードを紹介しました。
この記事では、ジェネリクスに対応した、IEnumerable<T>, IEnumerator<T> インターフェイスを実装するコードを紹介します。
プログラム例
Windows Formアプリケーションを作成します。
UI
下図のUIを作成します。ButtonとTextBoxを配置します。
コード
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomIEnumeratorT
{
public class MyClass : IEnumerable<string>
{
IEnumerator IEnumerable.GetEnumerator()
{
return new MyClassProc();
}
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return new MyClassProc();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomIEnumeratorT
{
public class MyClassProc : IEnumerator<string>
{
int index = 0;
public void Dispose()
{
}
public bool MoveNext()
{
index++;
if (5 < index)
{
return false;
}
else
{
return true;
}
}
public void Reset()
{
index = 0;
}
public string Current
{
get
{
switch (index)
{
case 1:
return "ぺんぎんクッキー";
case 2:
return "らくだキャラメル";
case 3:
return "しろくまアイス";
case 4:
return "かるがもサブレ";
case 5:
return "きつねカステラ";
default:
return "none";
}
}
}
object IEnumerator.Current
{
get
{
switch (index)
{
case 1:
return "ぺんぎんクッキー";
case 2:
return "らくだキャラメル";
case 3:
return "しろくまアイス";
case 4:
return "かるがもサブレ";
case 5:
return "きつねカステラ";
default:
return "none";
}
}
}
}
}
namespace CustomIEnumeratorT
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MyClass m = new MyClass();
foreach (string s in m)
{
textBox1.Text += s + "\r\n";
}
}
}
}
解説
MyClass
は
IEnumerable<T>
インターフェイスを継承します。MyClassには次のメソッドを実装します。
- IEnumerator IEnumerable.GetEnumerator()
- IEnumerator<string> IEnumerable<string>.GetEnumerator()
2つのメソッドは明示的なインターフェイスメンバーの実装でも動作します。
(明示的なインターフェイスメンバーの実装の詳細は
こちらの記事を参照してください。)
下記コードのように、
IEnumerator<string>
を返す
GetEnumerator()
メソッドをpublicにして実装しても動作します。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomIEnumeratorT
{
public class MyClass : IEnumerable<string>
{
IEnumerator IEnumerable.GetEnumerator()
{
return new MyClassProc();
}
public IEnumerator<string> GetEnumerator()
{
return new MyClassProc();
}
}
}
MyClassProc
クラスでは、
IEnumerator<T>
インターフェイスを実装します。
MyClassProcには次のメソッドを実装します。
- public void Dispose()
- public bool MoveNext()
- public void Reset()
- public <T> Current
- object IEnumerator.Current
なお、下記コードのように、明示的なインターフェイスメンバーの実装で記述しても動作します。
public class MyClassProc : IEnumerator<string>
{
int index = 0;
void IDisposable.Dispose()
{
}
bool IEnumerator.MoveNext()
{
/* 中略 */
}
void IEnumerator.Reset()
{
/* 中略 */
}
string IEnumerator<string>.Current
{
/* 中略 */
}
object IEnumerator.Current
{
/* 中略 */
}
}
フォームではMyClassのインスタンスを作成し、foreachループを実行します。ループ要素の値をテキストボックスに表示します。
private void button1_Click(object sender, EventArgs e)
{
MyClass m = new MyClass();
foreach (string s in m)
{
textBox1.Text += s + "\r\n";
}
}
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。foreach文でループし、MyClass の
IEnumerator<string>
を取得し、
IEnumeratorの要素をひとつづつ取得してテキストボックスに値を表示している動作が確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2011-02-05
改訂日: 2022-05-29