Следуя двум методам (один использует IEnumerator<int>
, а другой использует List<int>.Enumerator
), хотя выглядит одинаково, дает разные результаты.
static void M1()
{
var list = new List<int>() { 1, 2, 3, 4 };
IEnumerator<int> iterator = list.GetEnumerator();
while (iterator.MoveNext())
{
Console.Write(iterator.Current);
}
iterator.Reset();
while (iterator.MoveNext())
{
Console.Write(iterator.Current);
}
}
static void M2()
{
var list = new List<int>() { 1, 2, 3, 4 };
//Here the iterator will be List<int>.Enumerator (which is a struct)
var iterator = list.GetEnumerator();
while (iterator.MoveNext())
{
Console.Write(iterator.Current);
}
//This will not work, as Reset method was implemented explicitly
//iterator.Reset();
//So casting it to IEnumerator is required
//which will lead to boxing and other issues of struct and interface
((IEnumerator<int>)iterator).Reset();
//Following loop will NOT work
while (iterator.MoveNext())
{
Console.Write(iterator.Current);
}
}
Есть несколько вопросов, которые ясно объясняют это поведение, вы можете проверить здесь здесь, здесь, и здесь.
У меня все еще есть два сомнения
- Почему List.Enumerator не выбрасывает "NotSupportedException" для Reset?
- Почему Reset был реализован явно и неявно, как MoveNext и Current?