C#で自作のクラスをforeach文で呼び出したい場合はGetEnumuratorメソッドを実装すればforeach文で呼び出せるようになります*1。
次のforeach文は
foreach (int i in new Simplest()) { Console.WriteLine(i); }
以下のシンタックスシュガーです。
IEnumerator e = new Simplest().GetEnumerator(); while (e.MoveNext()) { Console.WriteLine(i); }
Java5で言うIteratorと拡張for文の関係と同じです。
実装方法
どうすればGetEnumuratorメソッドを実装できるでしょうか?
C#2.0以降では反復子ブロックという機能があり、比較的簡単な手順で実装することが出来ます。次にサンプルを示します。
using System; using System.Collections.Generic; using System.Data; using NUnit.Framework; using NUnit.Framework.SyntaxHelpers; namespace EnumrableSample { public class Simplest { public IEnumerator<int> GetEnumerator() { yield return 0; } [TestFixture] public class Test { [Test] public void ゼロがひとつだけ帰ってくる() { foreach (int i in new Simplest()) { Console.WriteLine(i); } } } } }
重要なのは「yield return」です。yield return で指定した値を元にコンパイラが GetEnumerator メソッドの実処理を実装します。この例では一つの値を返します。
次のように複数指定すれば、指定した分の値を列挙するGetEnumeratorメソッドが実装されます。
public IEnumerator<int> GetEnumerator() { yield return 0; yield return 1; }
yield returnを含む「メソッドのようなもの」を、反復子ブロックといいます。次回はこの反復子ブロックがどのように実際のGetEnumeratorメソッドとして実装されるか、反復子ブロックを使う上での注意点などを書きたいと思います。*2