IEnumeratorは列挙子を意味し、IEnumerableは列挙可能を意味します。どちらもインターフェースです
foreachは、列挙可能な要素に対するコードの反復を単純化するために使用される構文糖衣です。トラバースされたクラスは、IEnumerableインターフェイスと関連するIEnumerator列挙子を実装することによってトラバーサル関数を実装します。
public class MyList : IEnumerable
{
public int[] _data = new int[10] { 1, 5, 7, 9, 7, 8, 7, 8, 7, 4 };
public int this[int index]
{
get
{
return _data[index];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
Debug.Log("foreach调用 GetEnumerator");
return new MIEnumtor(this);
}
}
public class MIEnumtor : IEnumerator
{
private MyList myList;
private int index;
public MIEnumtor(MyList my)
{
index = -1;
myList = my;
}
public object Current
{
get
{
Debug.Log("foreach调用 Current");
return myList[index];
}
}
public bool MoveNext()
{
Debug.Log("foreach调用 MoveNext");
if (index < myList._data.Length - 1)
{
index++;
return true;
}
index = -1;
return false;
}
public void Reset()
{
}
}
GetIEnumerator()は、列挙子の取得を担当します。
MoveNext()は、Currentに次の値を取得させ、トラバーサルが終了したかどうかを判断する役割を果たします。
Currentは、現在指定されている値を返す責任があります。
Rest()は、列挙子の状態をリセットする役割を果たします(foreachでは使用されません)。
これらは、IEnumeratorの基本的な動作原理であるIEnumerableです。
MyList my = new MyList();
foreach (var item in my)
{
Debug.Log(item);
}
に相当
MyList my = new MyList();
MIEnumtor mIEnumtor = my.GetEnumerator();
while (mIEnumtor.MoveNext())
{
Debug.Log(mIEnumtor.Current);
}