Broadroad Broadroad - 2 days ago 5
C# Question

Enumerator fails to return the first element

I implemented the

IEnumerator
interface in my class. It works fine apart from the fact that it never returns the first element in
MyListContainer
. Only the rest. So to try and fix this I used the following:

public void Reset(){ EnumeratorPosition = -1; }


But it didn't return the first result again.

Any suggestions on how to fix this? Or is the first element the foreach's share?

public bool MoveNext()
{
EnumeratorPosition++;
return (EnumeratorPosition < MyListContainer.Count);
}

public void Reset()
{ EnumeratorPosition = 0; }

public object Current
{
get { return MyListContainer[EnumeratorPosition]; }
}

public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}

Answer

Start EnumeratorPosition at -1, not 0. Then the first call to MoveNext() moves to the first item, not the second.

An enumerator that hasn't started enumerating yet is pointing at nothing -- at the whistling void prior to the first element.

In implementation terms, that's simple. Initialize it to -1 in its declaration, and set it to -1 in Reset():

private int _enumeratorPosition = -1;
public void Reset() { _enumeratorPosition = -1; }

public bool MoveNext()
{                
    _enumeratorPosition++;
    return (_enumeratorPosition < MyListContainer.Count);                
}

public object Current
{
    get { return MyListContainer[_enumeratorPosition]; }
}

...and while you're at it, since it is (or very much ought to be) a private field, let's rename it to _enumeratorPosition so anybody reading your code will know what it is immediately.

With all that said, you could just call MyListContainer.GetEnumerator() instead of writing your own. It's rare for most of us to implement IEnumerator other than as an exercise. But it's a good exercise, so I'd hate to discourage you.

Comments