Warum wurde GetEnumerator () in einer separaten Schnittstelle von IEnumerator gespeichert?

7

Ich habe mich gefragt, warum die Methode GetEnumerator () aus IEnumerator herausgerechnet und in IEnumerable platziert wurde. Es scheint mir, dass es sinnvoller wäre, alle Enumerator-Methoden in IEnumerator zu behalten.

Danke,

Scott

    
Scott Davies 02.01.2010, 22:43
quelle

6 Antworten

17

Fragen Sie sich: "Stellen Sie sich vor, wenn das stimmt".

Wenn alle Aufzählungsmethoden auf einer einzelnen Schnittstelle waren, wie könnten dann zwei Aufrufer die gleiche Liste gleichzeitig auflisten?

Es gibt zwei Schnittstellen, weil eine sagt: "Sie können mich aufzählen", während die andere sagt: "Hier ist ein Objekt, das eine bestimmte Aufzählungsaufgabe verfolgt."

Die Schnittstelle IEnumerable ist eine Factory, die so viele IEnumerator -Objekte erstellt, wie Sie möchten. Wie und wann diese Enumeratoren verwendet werden, hängt vom Konsumenten ab.

    
Eilon 02.01.2010, 22:51
quelle
7

IEnumerable impliziert, dass das Objekt eine Sammlung oder Quelle von Daten ist, die linear durchlaufen werden können. IEnumerator ist die Schnittstelle für die eigentliche Implementierung, die die Iteration durchführt.

    
Rob 02.01.2010 22:46
quelle
4

Weil "IEnumerable" sagt "Komm, zähle mich auf" (und dann sagst du - wie, gib mir den Enumerator), aber "IEnumerator" sagt "Ich kann deine Sammlung aufzählen!" und du hast es schon, du brauchst nicht mehr zu bekommen.

    
naivists 02.01.2010 22:47
quelle
2

Sie haben hier sehr gute Antworten. Nur ein wenig Betonung. Ein Enumerator behält den Zustand bei, er verfolgt das aktuelle Objekt in der Auflistung, die aufgezählt wird. Verfügbar über IEnumerator.Current. Und es weiß, wie man diesen Zustand ändert, IEnumerator.MoveNext (). Um den Status beizubehalten, ist ein separates Objekt erforderlich, das den Status speichert. Dieser Zustand kann nicht einfach im Sammlungsobjekt gespeichert werden, da es nur ein Sammlungsobjekt gibt, aber es kann mehrere Enumeratoren geben.

Ich habe den Ausdruck "leicht" verwendet, weil es für eine Sammlung tatsächlich möglich ist, ihre Enumeratoren im Auge zu behalten. Schließlich war es ein Aufruf der Methode GetEnumerator () der Auflistungsklasse, die den Iterator zurückgab. Es gibt eine Auflistungsklasse im .NET-Framework, die dies tut, Microsoft.VisualBasic.Collection. Es musste einen VB6-Vertrag für seine Collection-Klasse implementieren, und dieser Vertrag gibt an, dass das Ändern einer Sammlung während der Aufzählung zulässig ist. Dies bedeutet, dass bei Änderungen an der Collection einige der Iterator-Objekte, die erstellt wurden, sinnvoll sein müssen.

Sie hatten einen ziemlich guten Trick, WeakReference könnte davon inspiriert sein. Sehen Sie sich den Code von Reflector an. Inspirierende Sachen. Dig einige mehr und finde "Version" in den Sammelklassen. Super Trick.

    
Hans Passant 02.01.2010 23:51
quelle
0

Weil das Ding, das die Aufzählung macht, oft nur tangential (wenn überhaupt) mit dem Ding zusammenhängt, das aufgezählt wird. Wenn IEnumerable und IEnumerator dieselbe Schnittstelle waren, konnten sie nicht gemeinsam verwendet werden, oder Sie mussten ein nicht typisiertes Argument in GetEnumerator haben, mit dem Sie das aufzulistende Objekt übergeben konnten. Wenn Sie diese aufteilen, kann die Aufzählungsinfrastruktur möglicherweise für verschiedene Typen gemeinsam genutzt werden.

    
nitzmahone 02.01.2010 22:48
quelle
0

Nach dem Lesen von Bart De Smets Beitrag auf minlinq Ich bin nicht mehr überzeugt, dass das Teilen der beiden Schnittstellen unbedingt erforderlich ist.

Zum Beispiel - In der obigen Verknüpfung ist IEnumerable / IEnumerator auf eine einzige Methode Schnittstelle

zusammengefasst %Vor%

und einige grundlegende Implementierungen

%Vor%     
Scott Weinstein 02.01.2010 23:54
quelle