2010-03-25 4 views
5

Ist das eine schlechte Idee?IEnumerable und IEnumerator in der gleichen Klasse, schlechte Idee?

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 

Diese Klasse ist nur sichtbar, als IEnumerable (Of T) Nur-Lese-Eigenschaft, und es spart mir eine zusätzliche Klasse, die IEnumerator (Of T) umschließt. Aber irgendwie scheint es einfach falsch zu sein. Gibt es einen besseren Weg?

Antwort

4

Dies ist eine schlechte Idee, weil die Lösung zusammenbrechen wird, wenn jemand versucht, Ihre Sammlung mehr als einmal zur gleichen Zeit aufzuzählen.

Zum Beispiel: Das in irgendeiner Weise brechen

For Each cur1 in yourObj 
    For Each cur2 in yourObj 
    Console.WriteLine("{0} - {1}", cur1,cur2) 
    Next 
Next 
+2

Oder sogar nicht zur gleichen Zeit, möglicherweise :) –

+0

@Jon sehr wahr! – JaredPar

5

Definitiv eine schlechte Idee. Insbesondere bedeutet dies, dass zwei Aufrufe an GetEnumerator Verweise auf dasselbe Objekt zurückgeben - wenn sie unabhängige Iteratoren zurückgeben sollen.

Nun gesagt, der C# -Compiler wird Klassen generieren, die beide Typen implementieren, wenn Sie Iteratorblöcke verwenden ... aber es geht um große Anstrengungen, um sicherzustellen, dass es richtig ankommt. Ich schlage vor, dass Sie sich nicht durch diesen Schmerz bringen :)

+0

Jon, mein Lebensziel ist es, Schmerzen zu vermeiden, danke für die Köpfe hoch. –

1

Von Implementing IEnumerable:

bieten Sie eine GetEnumerator() -Methode, die eine verschachtelte public struct „Enumerator“ genannt zurück .

By the way, ist diese Webseite von Brad Abrams gepflegt - einer der Autoren von Framework Design Guidelines.

+0

Ich habe diesen speziellen Vorschlag nie gemocht - er ermutigt veränderliche Strukturen, die sich auf böse Weise verhalten können. –

+1

@Jon - Das ist ein guter Punkt, aber ich denke, dass es in diesem Fall nicht die schlechteste Idee ist. Es ist definitiv ein Kompromiss zwischen Leistung (weniger Speicherdruck mit einer Struktur) und mit einer veränderlichen Struktur, die Gewissheit in der Anwendung einführen könnte. Ich denke angesichts der Tatsache, dass die meisten Entwickler nicht direkt mit der Enumerator-Instanz arbeiten, dass es eine gute Abwägung für den Leistungsvorteil ist, wenn sie eine veränderbare Struktur ist. Aber im Allgemeinen stimme ich zu, dass veränderbare Strukturen vermieden werden sollten. –

+0

Brad macht den Kompromiss sehr klar: Um dieses Muster zu implementieren, müssen Sie einen zusätzlichen öffentlichen Typ (den Enumerator) und einige zusätzliche öffentliche Methoden haben, die nur aus Gründen der Infrastruktur vorhanden sind. Diese Typen tragen zu der wahrgenommenen Komplexität der API bei und müssen dokumentiert, getestet, versioniert usw. werden. ** Daher sollte dieses Muster nur dann eingehalten werden, wenn die Leistung von größter Bedeutung ist. ** Folglich sollte dies * nicht * am meisten verwendet werden Zeit, in der die Leistung nicht zu kritisch ist. –