Связь между IEnumerator <T>.Current и IEnumerator.Current и почему IEnumerator <T>реализует IDisposable - PullRequest
2 голосов
/ 30 мая 2011

Я реализую ICollection , и есть проблемы с реализацией перечислителя.

Я понимаю, что IEnumerator должен реализовать IEnumerator для обратной совместимости (.NET 1.0)

Но если я реализую IEnumerator , то есть 2 текущих свойства.

У меня есть 2 вопроса:

  1. Каким должно быть их отношение?Правильный ли следующий код?

    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;
        }
    }
    

Я получаю эту ошибку: Требуется ссылка на объект для нестатического поля, метода или свойства 'System.Collections.Generic.IEnumerator.Current.get '

(2).Почему IEnumerator должен реализовывать IDisposable.Утилизация предназначена для неуправляемых ресурсов, но в каком случае в общем случае Enumerator будет использовать неуправляемые ресурсы?

Ответы [ 2 ]

3 голосов
/ 30 мая 2011

В некоторых случаях полезно, чтобы IEnumerator<T> наследовал от IDisposable.

Например, возьмите File.ReadLines(), который должен оставаться открытым FileStream, который является неуправляемым ресурсом.

Или, если вы думаете об итераторе, использующем yield syntax, вам нужно IDisposable, чтобы пункты finally работали правильно:

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

Обычно вы реализуете Current следующим образом:

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

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

Ваш исходный код не работает, так как вы пытаетесь получить статическое свойство на самом интерфейсе.Вы, вероятно, хотели ((IEnumerator<T>)this).Current.Но если вы имплицируете T Current{...} неявно, то вам вообще не нужно это приведение.

1 голос
/ 30 мая 2011
  1. return ((IEnumerator<T>)this).Current;

  2. Dispose() используется, чтобы сообщить счетчику, что он больше не нужен (например, вы можете отключиться от какого-либо источника данных или сделать что-то еще).

...