IEnumerable и IEnumerator в одном классе, плохая идея?

Это плохая идея?

Private Class GH_DataStructureEnumerator(Of Q As Types.IGH_Goo)
  Implements IEnumerable(Of Q)
  Implements IEnumerator(Of Q)
  ....
  ....
  'Current, MoveNext, Reset etc.'
  ....
  ....

  Public Function GetEnumerator_Generic() As IEnumerator(Of Q) _
                  Implements IEnumerable(Of Q).GetEnumerator
    Return Me
  End Function
End Class

Этот класс виден только как свойство IEnumerable(Of T) только для чтения, и это избавляет меня от дополнительного класса, который обертывает IEnumerator(Of T). Но почему-то это кажется неправильным. Есть ли способ лучше?


person David Rutten    schedule 25.03.2010    source источник


Ответы (3)


Это плохая идея, потому что решение сломается, если кто-то попытается перечислить вашу коллекцию более одного раза одновременно.

Например: Это каким-то образом сломается

For Each cur1 in yourObj 
  For Each cur2 in yourObj
    Console.WriteLine("{0} - {1}", cur1,cur2)
  Next
Next
person JaredPar    schedule 25.03.2010
comment
Или даже не одновременно, вполне возможно :) - person Jon Skeet; 25.03.2010

Определенно плохая идея. В частности, это означает, что два вызова GetEnumerator будут возвращать ссылки на один и тот же объект, тогда как они должны возвращать независимые итераторы.

Сказав это, компилятор C# будет генерировать классы, которые реализуют оба типа, если вы используете блоки итераторов... но он делает все возможное, чтобы убедиться, что все сделано правильно. Я предлагаю вам не подвергать себя этой боли :)

person Jon Skeet    schedule 25.03.2010
comment
Джон, цель моей жизни - избежать боли, спасибо, что предупредил. - person David Rutten; 25.03.2010

Из реализации IEnumerable:

Предоставьте метод GetEnumerator(), который возвращает вложенную общедоступную структуру под названием "Enumerator".

Кстати, этот веб-сайт поддерживается Брэдом Абрамсом — одним из авторов Руководство по разработке фреймворка.

person Andrew Hare    schedule 25.03.2010
comment
Мне никогда не нравилось это конкретное предложение — оно поощряет изменчивые структуры, которые могут вести себя плохо. - person Jon Skeet; 25.03.2010
comment
@Jon - Это хороший момент, но я думаю, что в данном случае это не самая плохая идея. Это определенно компромисс между производительностью (меньшая нагрузка на память со структурой) и наличием изменяемой структуры, которая может внести странности в приложение. Я думаю, учитывая тот факт, что большинство разработчиков не работают с экземпляром перечислителя напрямую, использование изменяемой структуры является хорошим компромиссом в пользу повышения производительности. Но в целом я согласен с тем, что следует избегать изменяемых структур. - person Andrew Hare; 25.03.2010
comment
Брэд делает компромисс очень ясным: реализация этого шаблона требует наличия дополнительного общедоступного типа (перечислителя) и нескольких дополнительных общедоступных методов, которые на самом деле существуют только по причинам инфраструктуры. Эти типы увеличивают воспринимаемую сложность API и должны быть задокументированы, протестированы, версионированы и т. д. Таким образом, этому шаблону следует следовать только там, где производительность имеет первостепенное значение. Следовательно, это не должно не< /i> можно использовать в большинстве случаев, когда производительность не слишком критична. - person mmx; 25.03.2010
comment
@Mehrdad - достаточно справедливо, но я бы сказал, что тип, реализующий IEnumerator, на самом деле не создает такой большой сложности API. Хорошая мысль, однако :) - person Andrew Hare; 26.03.2010
comment
Я бы предложил, чтобы IEnumerable возвращал класс, а не структуру, хотя по соображениям производительности может быть полезно иметь метод GetEnumerator, не связанный с IEnumerable, который возвращает структуру. Если метод GetEnumerator существует и возвращает структуру, и VB.net, и C# будут использовать ее приглушенный тип, чтобы избежать упаковки; однако вызов GetEnumerator через IEnumerable потребует приведения перечислителя к упакованному IEnumerator, что устраняет любое преимущество в производительности, которое могла бы иметь структура. - person supercat; 03.03.2011