Munish Goyal
Munish Goyal

Reputation: 1409

Relation between IEnumerator<T>.Current and IEnumerator.Current and Why IEnumerator<T> implements IDisposable

I am implementing ICollection< T > and there are problems doing enumerator implementation.

I understand that IEnumerator< T > has to implement IEnumerator for back-compatibility (.NET 1.0)

But If i am implementing IEnumerator< T >, then there are 2 Current Properties.

I have 2 questions:

  1. What should be their relation ? Is following code correct ?

    T IEnumerator<T>.Current 
    { 
        get 
        {
            if (_cursor < 0 || _cursor >= _array.Length)
                throw new InvalidOperationException("Iterator position invalid");
            else 
                return _array[_cursor];
        } 
    }
    
    
    object IEnumerator.Current
    {
        get
        {
            return IEnumerator<T>.Current;
        }
    }
    

I get this error: An object reference is required for the non-static field, method, or property 'System.Collections.Generic.IEnumerator.Current.get'

(2). Why IEnumerator< T > has to implement IDisposable. Dispose is for unmanaged resources, but in what scenario in-general would Enumerator use unmanaged resources ?

Upvotes: 2

Views: 598

Answers (2)

CodesInChaos
CodesInChaos

Reputation: 108790

There are several cases where it's useful that IEnumerator<T> inherits from IDisposable.

For example take File.ReadLines() which needs to keep open a FileStream, which is an unmanaged resource.

Or if you think about an iterator using the yield syntax you need IDisposable to make finally clauses work correctly:

IEnumerator<int> MyIt()
{
  try
  {
    yield return 1;
  }
  finally
  {
    //Do Something
  }
}

Typically you'd implement Current like this:

T Current//Implicit interface implementation
{
  get
  {
    return something;
  }
}

object IEnumerator.Current{get{return Current;}}

Your original code doesn't work since you try to get a static property on the interface itself. You probably wanted to to ((IEnumerator<T>)this).Current. But if you implement T Current{...} implicitly you don't need that cast at all.

Upvotes: 3

max
max

Reputation: 34407

  1. return ((IEnumerator<T>)this).Current;

  2. Dispose() is used to tell enumerator that it is not needed anymore (so you can, for example, disconnect from some data source, or do something else).

Upvotes: 1

Related Questions