Eine Interviewfrage für einen .NET 3.5-Job lautet "Was ist der Unterschied zwischen einem Iterator und einem Enumerator"?
Dies ist eine zentrale Unterscheidung, was mit LINQ usw. zu tun ist.
Was ist der Unterschied? Ich kann anscheinend keine solide Definition im Netz finden. Machen Sie keinen Fehler, ich kann die Bedeutung der beiden Begriffe finden, aber ich bekomme leicht unterschiedliche Antworten. Was wäre die beste Antwort für ein Interview?
IMO "iteriert" ein Iterator über eine Sammlung, und ein Enumerator bietet die Funktionalität zum Iterieren, dies muss jedoch aufgerufen werden.
Durch die Verwendung des Schlüsselwortsield wird auch der Status gespeichert. Was genau ist dieser Zustand? Gibt es ein Beispiel für diesen Vorteil?
yield
), und der Enumerator ist ein Objekt, das nacheinander Werte mitCurrent
und liefertMoveNext()
(siehe Pings Antwort ). Der Wortlaut unterscheidet sich in Python, wo ein Generator einem C # -Enumerator ähnelt (Werte, die im laufenden Betrieb mit erstellt werdenyield
), und der alte Iterator macht dasselbe, jedoch ohneyield
(also kein Pausenmechanismus, eine Schleife kann nicht verwendet werden).In C # 2+ sind Iteratoren eine Möglichkeit für den Compiler, die IEnumerable- und / oder IEnumerable <T> -Schnittstellen automatisch für Sie zu generieren.
Ohne Iteratoren müssten Sie eine Klasse erstellen , die IEnumerator implementiert , einschließlich Current, MoveNext und Reset. Dies erfordert einen angemessenen Arbeitsaufwand. Normalerweise würden Sie eine private Klasse erstellen, die IEnumerator <T> für Ihren Typ implementiert, dann würde yourClass.GetEnumerator () diese private Klasse erstellen und zurückgeben.
Iteratoren sind eine Möglichkeit für den Compiler, dies mithilfe einer einfachen Syntax (Yield) automatisch für Sie zu generieren. Auf diese Weise können Sie GetEnumerator () direkt in Ihrer Klasse implementieren, ohne dass eine zweite Klasse (The IEnumerator) von Ihnen angegeben wird. Der Aufbau dieser Klasse mit all ihren Mitgliedern ist für Sie erledigt.
Iteratoren sind sehr entwicklerfreundlich - die Dinge werden auf sehr effiziente Weise und mit viel weniger Aufwand erledigt.
Wenn Sie foreach verwenden, verhalten sich die beiden identisch (vorausgesetzt, Sie schreiben Ihren benutzerdefinierten IEnumerator korrekt). Iteratoren machen das Leben einfach viel einfacher.
quelle
Was C # einen Iterator nennt, wird häufiger (außerhalb der C # -Welt) als Generator oder Generatorfunktion bezeichnet (z. B. in Python). Eine Generatorfunktion ist ein Spezialfall von Coroutine . AC # Iterator (Generator) ist eine spezielle Form eines Enumerators (ein Datentyp, der die
IEnumerable
Schnittstelle implementiert ).Ich mag diese Verwendung des Begriffs Iterator für einen C # -Generator nicht, weil er genauso ein Enumerator wie ein Iterator ist. Für Microsoft ist es jedoch zu spät, um seine Meinung zu ändern.
Beachten Sie im Gegensatz dazu, dass in C ++ ein Iterator ein Wert ist, der hauptsächlich für den Zugriff auf sequentielle Elemente in einer Sammlung verwendet wird. Es kann erweitert, abgeleitet, um einen Wert abzurufen, und getestet werden, um festzustellen, ob das Ende der Sammlung erreicht wurde.
quelle
"Während eine foreach-Anweisung der Verbraucher des Enumerators ist, ist ein Iterator der Produzent des Enumerators."
Das Obige erklärt es wie "C # 5.0 In A NutShell" und war für mich hilfreich.
Mit anderen Worten, die foreach-Anweisung verwendet MoveNext () und die Current-Eigenschaft des IEnumerator, um eine Sequenz zu durchlaufen, während der Iterator verwendet wird, um die Implementierung des IEnumerator zu erstellen, die von der foreach-Anweisung verwendet wird. Wenn Sie in C # eine Iteratormethode schreiben, die eine Yield-Anweisung enthält, generiert der Compiler einen privaten Enumerator für Sie. Wenn Sie die Elemente in der Sequenz durchlaufen, werden die Eigenschaften MoveNext () und Current des privaten Enumerators aufgerufen. Diese Methoden / Eigenschaften werden von Ihrem Code in der Iterator-Methode implementiert, die wiederholt aufgerufen wird, um Werte zu erhalten, bis keine Werte mehr zu ergeben sind.
Dies ist mein Verständnis davon, wie C # Enumeratoren und Iteratoren definiert.
quelle
Um Iteratoren zu verstehen, müssen wir zuerst Enumeratoren verstehen.
Enumeratoren sind Spezialobjekte, die es einem ermöglichen, sich einzeln durch eine geordnete Liste von Elementen zu bewegen (das Gleiche wird manchmal als "Cursor" bezeichnet). Das .NET Framework bietet zwei wichtige Schnittstellen für Enumeratoren: IEnumerator und IEnumerable. Objekte, die IEnumerator implementieren, sind selbst Enumeratoren. Sie unterstützen die folgenden Mitglieder:
die Eigenschaft Current, die auf eine Position in der Liste verweist
die Methode MoveNext, mit der das aktuelle Element um eins in der Liste verschoben wird
die Methode Zurücksetzen, mit der das aktuelle Element an seine Ausgangsposition (vor dem ersten Element) verschoben wird.
Auf der anderen Seite implementieren Iteratoren das Aufzählungsmuster. In .NET 2.0 wurde der Iterator eingeführt, der ein vom Compiler manipulierter Enumerator ist. Wenn das Aufzählungsobjekt GetEnumerAtor entweder direkt oder indirekt aufruft, generiert der Compiler ein geeignetes Iteratorobjekt und gibt es zurück. Optional kann der Iterator ein kombiniertes Aufzählungs- und Aufzählungsobjekt sein.
Der wesentliche Bestandteil eines Iteratorblocks ist die Ertragsangabe. Es gibt einen großen Unterschied zwischen Iteratoren und Enumeratoren: Iterateure implementieren die Reset-Methode nicht. Das Ausführen der Reset-Methode auf einem Iterator kann eine Ausnahme darstellen.
Der Zweck von Iteratoren besteht darin, die einfache Implementierung von Enumeratoren zu ermöglichen. Wenn eine Methode entweder einen Enumerator oder eine Enumerable-Klasse für eine geordnete Liste von Elementen zurückgeben muss, wird sie so geschrieben, dass jedes Element in der richtigen Reihenfolge mit der Anweisung'ield 'zurückgegeben wird.
quelle
Da keine Beispiele angegeben wurden, ist hier eines, das mir hilfreich war.
Ein Enumerator ist ein Objekt, das Sie erhalten, wenn Sie .GetEnumerator () für eine Klasse oder einen Typ aufrufen, der die IEnumerator-Schnittstelle implementiert. Wenn diese Schnittstelle implementiert ist, haben Sie den gesamten Code erstellt, der für den Compiler erforderlich ist, damit Sie
foreach
Ihre Sammlung "iterieren" können.Verwechseln Sie das Wort "iterieren" nicht mit dem Iterator. Sowohl mit dem Enumerator als auch mit dem Iterator können Sie "iterieren". Aufzählung und Iteration sind im Grunde der gleiche Prozess, werden jedoch unterschiedlich implementiert. Aufzählung bedeutet, dass Sie die IEnumerator-Schnittstelle implementiert haben Iterieren bedeutet, dass Sie das Iterator-Konstrukt in Ihrer Klasse erstellt haben (siehe unten) und
foreach
Ihre Klasse aufrufen. Zu diesem Zeitpunkt erstellt der Compiler automatisch die Enumerator-Funktionalität für Sie.Beachten Sie auch, dass Sie nicht mit Ihrem Enumerator in die Hocke gehen müssen. Sie können den
MyClass.GetEnumerator()
ganzen Tag anrufen und nichts damit anfangen (Beispiel:IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator()
).Beachten Sie auch, dass Ihr Iterator-Konstrukt in Ihrer Klasse nur dann wirklich verwendet wird, wenn Sie es tatsächlich verwenden, dh Sie haben
foreach
Ihre Klasse aufgerufen .Hier ist ein Iterator-Beispiel von msdn :
public class DaysOfTheWeek : System.Collections.IEnumerable { string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; //This is the iterator!!! public System.Collections.IEnumerator GetEnumerator() { for (int i = 0; i < days.Length; i++) { yield return days[i]; } } } class TestDaysOfTheWeek { static void Main() { // Create an instance of the collection class DaysOfTheWeek week = new DaysOfTheWeek(); // Iterate with foreach - this is using the iterator!!! When the compiler //detects your iterator, it will automatically generate the Current, //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface foreach (string day in week) { System.Console.Write(day + " "); } } } // Output: Sun Mon Tue Wed Thr Fri Sat
quelle
"Iteratoren sind eine neue Funktion in C # 2.0. Ein Iterator ist eine Methode, ein Accessor oder ein Operator, mit der Sie jede Iteration in einer Klasse oder Struktur unterstützen können, ohne die gesamte IEnumerable-Schnittstelle implementieren zu müssen. Stattdessen stellen Sie nur einen Iterator bereit Durchläuft einfach die Datenstrukturen in Ihrer Klasse. Wenn der Compiler Ihren Iterator erkennt, generiert er automatisch die Methoden Current, MoveNext und Dispose der IEnumerable- oder IEnumerable-Schnittstelle. " - msdn
quelle
Die Aufzählung behandelt Objekte, während die Iteration nur Werte behandelt. Die Aufzählung wird verwendet, wenn wir die Vektor-Hashtabelle usw. verwenden, während die Iteration in der while-Schleife für die Schleife usw. verwendet wird. Ich habe das Schlüsselwort yield nie verwendet, daher konnte ich es Ihnen nicht sagen.
quelle
Die Iteration befasst sich mit Arrays und Strings, während sich die Iteration mit Objekten befasst
In JavaScript können Sie ein Array oder eine Zeichenfolge iterieren mit:
Und Sie können ein Objekt aufzählen mit:
quelle