Why implement two versions of Current when implementing the IEnumerable interface?

I assume that the following example gives the best practice that we should follow when implementing the IEnumerable interface.

https://docs.microsoft.com/en-us/dotnet/api/system.collections.ienumerator.movenext

Here is the question:

  1. Why should we provide two versions of the Current method ?
  2. When is the ONE version used (IEnumerator.Current object)?
  3. When is the version of TWO (public Person Current) used?
  4. How to use PeopleEnum in a foreach expression. // updated
public class PeopleEnum : IEnumerator
{
    public Person[] _people;

    // Enumerators are positioned before the first element
    // until the first MoveNext() call.
    int position = -1;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }

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

    // explicit interface implementation
    object IEnumerator.Current /// **version ONE**
    {
        get
        {
            return Current;
        }
    }

    public Person Current     /// **version TWO**
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}
+5
source share
5 answers

, , , IEnumerator<T> - class PeopleEnum IEnumerator<T>, : IEnumerator<T> IEnumerator, IEnumerator<T>.

non-generic IEnumerator Current - IEnumerator<T> , Current T - .

+2

IEnumerator.Current - .

, IEnumerator ( foreach). .

, object , Person.

, object.

+7

IEnumerator :

public class PeopleEnum : IEnumerable
{
    public Person[] _people;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public IEnumerator GetEnumerator()
    {
        foreach (Person person in _people)
            yield return person;
    }
}

21- , - IEnumerable:

public class PeopleEnum : IEnumerable<Person>
{
    public Person[] _people;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public IEnumerator<Person> GetEnumerator()
    {
        foreach (Person person in _people)
            yield return person;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
+4

, . PeopleEnum.Current (p.MoveNext()), foreach.

But the only thing you need to do is implement the interface, you can do it implicitly if you want, but is there any reason for this? If I wanted to use MovePrevious in a class? Would it be great if I were to attach (delete) an object to Person?

If you think that a class can be extended with additional manipulation methods, then Person Current is a cool thing.

+2
source

Version 2 is not part of the interface. You must meet the interface requirements.

+1
source

All Articles