イテレーター 実装方法とその中身

基本文法

イテレーター

イテレーターとは反復子ともいわれ、集合の個々の要素に対して繰り返し処理を行うためのものです。
C#言語においては、主にforeachで使われるためのものであり、以下のように定義されます。

戻りの型は以下の4つのうちのいずれかのインタフェースとなる。
System.Collections.IEnumerable
System.Collections.IEnumerator
System.Collections.Generic.IEnumerable
System.Collections.Generic.IEnumerator
各要素を返却するにはyield returnを用いる

メソッドGetterプロパティ、またはクラスとして実装される。
    public class Program
    {
        public void Test()
        {
            // メソッド
            foreach (var str in GetDayOfWeekNames())
                Console.WriteLine(str);

            GetDayOfWeekNames().ToList().ForEach(str => Console.WriteLine(str));

            // プロパティ
            foreach (var str in DayOfWeekNames)
                Console.WriteLine(str);

            DayOfWeekNames.ToList().ForEach(str => Console.WriteLine(str));

            // クラス
            var weekNames = new DayOfWeekNameCollection();
            foreach(var str in weekNames)
                Console.WriteLine(str);

            weekNames.ToList().ForEach(str => Console.WriteLine(str));
        }

        // イテレータメソッド
        IEnumerable<string> GetDayOfWeekNames()
        {
            var array = Enum.GetValues(typeof(DayOfWeek));

            for (int n = 0; n < array.Length; n++)
                yield return array.GetValue(n).ToString();
            
        }

        // イテレータプロパティ
        IEnumerable<string> DayOfWeekNames
        {
            get
            {
                var array = Enum.GetValues(typeof(DayOfWeek));

                for (int n = 0; n < array.Length; n++)
                    yield return array.GetValue(n).ToString();
            }
        }
    }

    // イテレータクラス
    public class DayOfWeekNameCollection : IEnumerable<string>
    {
        public IEnumerator<string> GetEnumerator()
        {
            var array = Enum.GetValues(typeof(DayOfWeek));

            for (int n = 0; n < array.Length; n++)
                yield return array.GetValue(n).ToString();
        }

        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }

イテレータに関係するインタフェース

System.Collections.IEnumerator

メンバは以下の3つが定義されています
object Current { get; }
bool MoveNext ();
void Reset ();

現在の値と、次の値へ移動するのと、最初に戻る3つですね。一方向への逐次処理であることがよくわかります。

System.Collections.IEnumerable

これはメンバが一つだけ定義されています
IEnumerator GetEnumerator();
反復処理の実処理側を担うIEnumeratorインタフェースが戻り型だけとなります。
ジェネリクスの方は金本的にはこれらと同じです。たとえばIEnumerableは以下のように定義されています。

IEnumerable : IEnumerable
{
new IEnumerator GetEnumerator();
}