Korrekte Verwendung von Iteratorblöcken

8

Ich habe etwas Code früher umgestaltet und bin auf eine Implementierung eines Iteratorblocks gestoßen, über den ich nicht so sicher war. In einer Integrationsschicht eines Systems, in dem der Client eine externe API für einige Daten aufruft, habe ich eine Gruppe von Übersetzern, die die von der API zurückgegebenen Daten in Sammlungen von Geschäftsentitäten übernehmen, die in der Logikschicht verwendet werden. Eine gängige Übersetzerklasse sieht dann so aus:

%Vor%

Heute bin ich auf den folgenden Code gestoßen. Auch hier handelt es sich um eine Übersetzerklasse, deren Zweck darin besteht, die Sammlung im Parameter in den Rückgabetyp der Methode zu übersetzen. Diesmal ist es jedoch ein Iteratorblock:

%Vor%

Meine Frage ist: Ist das eine gültige Verwendung eines Iteratorblocks? Ich kann nicht den Vorteil sehen, eine Übersetzerklasse auf diese Weise zu erstellen. Könnte dies zu unerwartetem Verhalten führen?

    
james lewis 10.02.2012, 17:05
quelle

5 Antworten

13

Ihre beiden Samples machen ziemlich genau dasselbe. Die Abfrageversion wird in einen Aufruf von Auswahl umgeschrieben, und Auswahl wird genau wie in Ihrem zweiten Beispiel geschrieben; Er iteriert über jedes Element in der Quellensammlung und gibt ein transformiertes Element zurück.

Dies ist eine vollkommen gültige Verwendung eines Iteratorblocks, obwohl es natürlich nicht mehr notwendig ist, eigene Iteratorblöcke wie diese zu schreiben, da Sie einfach Select verwenden können.

    
Eric Lippert 10.02.2012, 17:20
quelle
3

Ja, das ist gültig. Der foreach hat den Vorteil, debuggbar zu sein, daher bevorzuge ich dieses Design.

    
eouw0o83hf 10.02.2012 17:07
quelle
3

Das erste Beispiel ist kein Iterator. Es erstellt und gibt nur IEnumerable<MyBusinessEnt> zurück.

Der zweite ist ein Iterator und ich sehe nichts falsch daran. Jedes Mal, wenn der Aufrufer über den Rückgabewert dieser Methode iteriert, gibt yield ein neues Element zurück.

    
John Saunders 10.02.2012 17:08
quelle
3

Ja, das funktioniert gut und das Ergebnis ist sehr ähnlich.

Beide erstellen ein Objekt, das das Ergebnis zurückgeben kann. Beide verlassen sich auf die aufzählbare Quelle, um intakt zu bleiben, bis das Ergebnis abgeschlossen ist (oder abgeschnitten ist). Beide verwenden die verzögerte Ausführung, d. H., Die Objekte werden nacheinander erstellt, wenn Sie das Ergebnis iterieren.

Es besteht ein Unterschied darin, dass der erste einen Ausdruck zurückgibt, der Bibliotheksmethoden verwendet, um einen Aufzähler zu erzeugen, während der zweite einen benutzerdefinierten Aufzähler erstellt.

    
Guffa 10.02.2012 17:12
quelle
-1

Der Hauptunterschied ist , wenn jeder Code ausgeführt wird. Der erste wird verzögert, bis der Rückgabewert iteriert wird, während der zweite sofort ausgeführt wird. Ich meine, dass die for-Schleife die Ausführung der Iteration erzwingt. Die Tatsache, dass die Klasse ein IEnumerable<T> verfügbar macht und in diesem Fall verzögert ist, ist eine andere Sache.

Dies bietet keinen Vorteil gegenüber dem einfachen Select . yield 's wirkliche Macht ist, wenn eine bedingte beteiligt ist:

%Vor%     
Aliostad 10.02.2012 17:09
quelle

Tags und Links