it-swarm.com.de

Kann mir jemand IEnumerable und IEnumerator erklären?

Kann mir jemand IEnumerable und IEnumerator erklären? 

zum Beispiel, wenn es über foreach verwendet werden soll? Was ist der Unterschied zwischen IEnumerable und IEnumerator? Warum müssen wir es benutzen? 

224
prodev42

zum Beispiel, wenn es über foreach verwendet werden soll?

Sie verwenden IEnumerable nicht "über" foreach. Die Implementierung von IEnumerable macht die Verwendung von foreachmöglich.

Wenn Sie Code schreiben wie:

foreach (Foo bar in baz)
{
   ...
}

es ist funktional gleichbedeutend mit dem Schreiben:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current
   ...
}

Mit "funktional äquivalent" meine ich damit eigentlich den Code, in den der Compiler übersetzt. Sie können foreach nicht für baz in diesem Beispiel verwenden, es sei denn,baz implementiert IEnumerable

IEnumerable bedeutet, dass baz die Methode implementiert

IEnumerator GetEnumerator()

Das IEnumerator-Objekt, das diese Methode zurückgibt, muss die Methoden implementieren

bool MoveNext()

und

Object Current()

Die erste Methode wechselt zum nächsten Objekt im IEnumerable-Objekt, das den Enumerator erstellt hat, und gibt false zurück, wenn dies der Fall ist, und die zweite gibt das aktuelle Objekt zurück.

Alles in .NET, das Sie über die Implementierung von IEnumerable durchlaufen können. Wenn Sie Ihre eigene Klasse erstellen und diese nicht bereits von einer Klasse erbt, die IEnumerable implementiert, können Sie Ihre Klasse in foreach-Anweisungen verwendbar machen, indem Sie IEnumerable implementieren (und eine Enumeratorklasse erstellen, die von der neuen GetEnumerator-Methode zurückgegeben wird. .

228
Robert Rossney

Die IEnumerable- und IEnumerator-Schnittstellen

Um den Prozess der Implementierung vorhandener .NET-Schnittstellen zu untersuchen, betrachten wir zunächst die Rolle von IEnumerable und IEnumerator. Es sei daran erinnert, dass C # ein Schlüsselwort namens foreach unterstützt, mit dem Sie den Inhalt eines beliebigen Array-Typs durchlaufen können

// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
   Console.WriteLine(i);
}

Es mag den Anschein haben, dass nur Array-Typen dieses Konstrukt verwenden können, die Wahrheit ist jedoch __. Jeder Typ, der eine Methode namens GetEnumerator () unterstützt, kann mit dem foreach-Konstrukt ausgewertet werden.

Angenommen, wir haben eine Garage-Klasse:

// Garage contains a set of Car objects.
public class Garage
{
   private Car[] carArray = new Car[4];
   // Fill with some Car objects upon startup.
   public Garage()
   {
      carArray[0] = new Car("Rusty", 30);
      carArray[1] = new Car("Clunker", 55);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
}

Im Idealfall wäre es praktisch, die Unterelemente des Garage-Objekts mithilfe des foreach -Konstrukts wie bei einem Array von Datenwerten zu durchlaufen:

// This seems reasonable ...
public class Program
{
   static void Main(string[] args)
   {
      Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
      Garage carLot = new Garage();
      // Hand over each car in the collection?
      foreach (Car c in carLot)
      {
         Console.WriteLine("{0} is going {1} MPH",
         c.PetName, c.CurrentSpeed);
      }
      Console.ReadLine();
   }
}

Leider informiert Sie der Compiler, dass die Garage-Klasse keine Methode namens GetEnumerator () implementiert. Diese Methode wird durch die IEnumerable-Schnittstelle formalisiert, die im System.Collections-Namespace lauert . Klassen oder Strukturen, die dieses Verhalten unterstützen, weisen darauf hin, dass sie dem Aufrufer enthaltene das foreach-Schlüsselwort selbst). Hier ist die Definition dieser Standard-.NET-Schnittstelle:

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
   IEnumerator GetEnumerator();
}

Wie Sie sehen, gibt die GetEnumerator () - Methode einen Verweis auf eine weitere Schnittstelle mit dem Namen System.Collections.IEnumerator zurück. Diese Schnittstelle stellt die Infrastruktur bereit, die es dem Aufrufer ermöglicht, die internen Objekte zu durchsuchen, die im IEnumerable-kompatiblen Container enthalten sind:

// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
   bool MoveNext (); // Advance the internal position of the cursor.
   object Current { get;} // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.
}

Wenn Sie den Garage-Typ aktualisieren möchten, um diese Schnittstellen zu unterstützen, können Sie den langen Weg nehmen und Jede Methode manuell implementieren. Sie können zwar durchaus benutzerdefinierte Versionen von GetEnumerator (), MoveNext (), Current und Reset () bereitstellen, es gibt jedoch einen einfacheren Weg. Da der System.Array-Typ (wie auch viele andere Collection-Klassen) bereits IEnumerable und IEnumerator implementiert, können Sie die Anforderung einfach an das System.Array wie folgt delegieren:

using System.Collections;
...
public class Garage : IEnumerable
{
   // System.Array already implements IEnumerator!
   private Car[] carArray = new Car[4];
   public Garage()
   {
      carArray[0] = new Car("FeeFee", 200);
      carArray[1] = new Car("Clunker", 90);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
   public IEnumerator GetEnumerator()
   {
      // Return the array object's IEnumerator.
      return carArray.GetEnumerator();
   }
}

Nachdem Sie Ihren Garage-Typ aktualisiert haben, können Sie den Typ sicher im C # foreach-Konstrukt verwenden. Da die GetEnumerator () - Methode öffentlich definiert wurde, könnte der Objektbenutzer außerdem mit dem IEnumerator-Typ interagieren:

// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);

Wenn Sie jedoch die Funktionalität von IEnumerable auf der Objektebene ausblenden möchten, nehmen Sie einfach die Verwendung der expliziten Schnittstellenimplementierung vor:

IEnumerator IEnumerable.GetEnumerator()
{
  // Return the array object's IEnumerator.
  return carArray.GetEnumerator();
}

Auf diese Weise findet der Benutzer des Gelegenheitsobjekts die GetEnumerator () - Methode der Garage nicht, während das Konstrukt Foreach die Schnittstelle bei Bedarf im Hintergrund abruft.

Angepasst aus dem Pro C # 5.0 und dem .NET 4.5 Framework

125
Jahan

Die Implementierung von IEnumerable bedeutet, dass Ihre Klasse ein IEnumerator-Objekt zurückgibt:

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        // return a PeopleEnumerator
    }
}

Die Implementierung von IEnumerator bedeutet, dass Ihre Klasse die Methoden und Eigenschaften für die Iteration zurückgibt:

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}

Das ist sowieso der Unterschied.

56
core

Erklärung über Analogie + Code Walkthrough

Zuerst eine Erklärung ohne Code, dann füge ich sie später hinzu.

Nehmen wir an, Sie betreiben eine Fluggesellschaft. In jedem Flugzeug möchten Sie Informationen über die Passagiere erhalten, die im Flugzeug fliegen. Grundsätzlich möchten Sie die Ebene "durchqueren" können. Mit anderen Worten, Sie möchten in der Lage sein, auf dem Vordersitz zu beginnen und sich dann in Richtung Flugzeugrückseite zu arbeiten, um die Passagiere nach Informationen zu fragen: wer sie sind, woher sie kommen usw. Ein Flugzeug kann nur dies tun wenn es ist: 

  1. zählbar und
  2. wenn es einen Zähler hat.

Warum diese Anforderungen? Weil dies die Schnittstelle erfordert. 

Wenn es sich hierbei um eine Informationsüberflutung handelt, müssen Sie nur wissen, dass Sie jedem Passagier im Flugzeug einige Fragen stellen möchten, angefangen mit der ersten bis zur letzten.

Was bedeutet abzählbar?

Wenn eine Fluggesellschaft "abzählbar" ist, MUSS ein Flugbegleiter im Flugzeug anwesend sein, dessen einzige Aufgabe darin besteht, zu zählen - und dieser Flugbegleiter MUSS auf eine ganz bestimmte Art und Weise zählen: 

  1. Die Schalter/Flugbegleiter MÜSSEN vor dem ersten Passagier beginnen (an der Vorderseite aller, wo sie Sicherheitsprüfungen durchführen, wie die Schwimmweste angelegt wird usw.).
  2. Er/sie (d. H. Der Flugbegleiter) MUSS den Gang "aufwärts" zum ersten Platz "weitergehen".
  3. Er/sie hat dann aufzuzeichnen: (i) wer die Person im Sitz ist, und (ii) ihren aktuellen Standort im Gang.

Zählverfahren

Der Kapitän der Fluggesellschaft möchte einen Bericht über jeden Passagier, wann und wann er untersucht oder gezählt wird. Nachdem er mit der Person auf dem ersten Sitzplatz gesprochen hat, meldet sich der Flugbegleiter dann dem Kapitän. Wenn der Bericht abgegeben wird, merkt sich der Schalter seine genaue Position im Gang und zählt dort weiter, wo er/sie aufgehört hat aus.

Auf diese Weise kann der Kapitän immer Informationen über die derzeit untersuchte Person haben. Wenn er herausfindet, dass diese Person Manchester City mag, kann er dem Passagier eine Vorzugsbehandlung geben.

  • Der Schalter läuft weiter, bis er das Ende des Flugzeugs erreicht.

Lass uns das mit den IEnumerables verknüpfen

  • Eine Zahl ist nur eine Ansammlung von Passagieren in einem Flugzeug. Das Zivilluftfahrtgesetz - dies sind im Grunde die Regeln, an die sich alle IEnumerables halten müssen. Jedes Mal, wenn der Flugbegleiter mit der Passeger-Information zum Kapitän geht, "geben" wir dem Passagier im Grunde den Kapitän. Der Kapitän kann mit dem Passagier grundsätzlich alles tun, was er will - außer die Passagiere im Flugzeug umzubauen. In diesem Fall werden sie bevorzugt behandelt, wenn sie Manchester City folgen (ugh!).

    foreach (Passenger passenger in Plane)
    // the airline hostess is now at the front of the plane
    // and slowly making her way towards the back
    // when she get to a particular passenger she gets some information
    // about the passenger and then immediately heads to the cabin
    // to let the captain decide what to do with it
    { // <---------- Note the curly bracket that is here.
        // we are now cockpit of the plane with the captain.
        // the captain wants to give the passenger free 
        // champaign if they support manchester city
        if (passenger.supports_mancestercity())
        {
            passenger.getFreeChampaign();
        } else
        {
            // you get nothing! GOOD DAY SIR!
        }
    } //  <---- Note the curly bracket that is here!
          the hostess has delivered the information 
          to the captain and goes to the next person
          on the plane (if she has not reached the 
          end of the plane)
    

Zusammenfassung

Mit anderen Worten, etwas ist abzählbar, wenn es hat einen Zähler. Und der Zähler muss (grundsätzlich): (i) sich an seinen Platz erinnern (state), (ii) in der Lage sein, weiter zu bewegen, (iii) und den aktuellen Person, mit der er zu tun hat. 

Enumerable ist nur ein schickes Wort für "Countable". Mit anderen Worten, ein Aufzählungszeichen ermöglicht das Aufzählen (d. H. Zählen).

43
BKSpurgeon

IEnumerable implementiert GetEnumerator. Beim Aufruf gibt diese Methode einen IEnumerator zurück, der MoveNext, Reset und Current implementiert.

Wenn Ihre Klasse IEnumerable implementiert, sagen Sie also, dass Sie eine Methode (GetEnumerator) aufrufen und ein neues Objekt zurückgeben können (ein IEnumerator), das Sie in einer Schleife wie foreach verwenden können.

22
DavGarcia

Durch die Implementierung von IEnumerable können Sie einen IEnumerator für eine Liste anfordern.

IEnumerator ermöglicht den sequenziellen Zugriff jedes Typs auf die Elemente in der Liste mit dem Schlüsselwort ertrag.

Vor der foreach-Implementierung (z. B. in Java 1.4) bestand die Möglichkeit zum Durchlaufen einer Liste darin, einen Enumerator aus der Liste abzurufen und ihn dann nach dem "nächsten" Element in der Liste zu fragen, solange der Wert als nächster zurückgegeben wird Artikel ist nicht null. Foreach tut dies einfach als Sprachfeature, genau wie Lock () die Monitor-Klasse im Hintergrund implementiert.

Ich erwarte, dass foreach mit Listen arbeitet, weil sie IEnumerable implementieren.

16
Neil Barnwell
  • Ein Objekt, das IEnumerable implementiert, ermöglicht anderen Benutzern, jedes seiner Elemente (durch einen Enumerator) zu besuchen.
  • Ein Objekt, das IEnumerator implementiert, führt die Iteration durch. Es ist eine Schleife über ein zahlbares Objekt. 

Stellen Sie sich zahllose Objekte als Listen, Stapel, Bäume vor.

15

IEnumerable und IEnumerator (und ihre generischen Gegenstücke IEnumerable <T> und IEnumerator <T>) sind Basisschnittstellen von Iterator -Implementierungen in . Net Framework Class Libray-Auflistungen .

IEnumerable ist die gebräuchlichste Schnittstelle, die Sie im größten Teil des Codes finden würden. Es aktiviert die foreach-Schleife, Generatoren (think yield ) und wird aufgrund seiner winzigen Schnittstelle verwendet, um enge Abstraktionen zu erstellen. IEnumerable hängt vom IEnumerator ab .

IEnumerator bietet dagegen eine etwas niedrigere Iterationsschnittstelle. Es wird als expliziter Iterator bezeichnet, wodurch der Programmierer mehr Kontrolle über den Iterationszyklus erhält.

IEnumerable

IEnumerable ist eine Standardschnittstelle, die das Iterieren über unterstützte Auflistungen ermöglicht (tatsächlich implementiert IEnumerable alle Auflistungstypen, die ich mir heute vorstellen kann). Die Compiler-Unterstützung ermöglicht Sprachfunktionen wie foreach. Im Allgemeinen wird dies aktiviert implizite Iterator-Implementierung .

foreach Schleife

foreach (var value in list)
  Console.WriteLine(value);

Ich denke, foreach Schleife ist einer der Hauptgründe für die Verwendung von IEnumerable Schnittstellen. foreach hat eine sehr prägnante Syntax und ist im Vergleich zum klassischen [~ # ~] c [~ # ~] - Stil für Schleifen, bei denen Sie überprüfen müssen, sehr einfach zu verstehen die verschiedenen Variablen, um zu sehen, was es tat.

ausbeute Keyword

Eine weniger bekannte Funktion ist wahrscheinlich, dass IEnumerable auch Generatoren in C # mit den Anweisungen yield return Und yield break Aktiviert .

IEnumerable<Thing> GetThings() {
   if (isNotReady) yield break;
   while (thereIsMore)
     yield return GetOneMoreThing();
}

Abstraktionen

Ein weiteres in der Praxis übliches Szenario ist die Verwendung von IEnumerable , um minimalistische Abstraktionen bereitzustellen. Da es sich um eine winzige und schreibgeschützte Schnittstelle handelt, sollten Sie Ihre Sammlungen als IEnumerable (anstelle von List verfügbar machen ). Auf diese Weise können Sie Ihre Implementierung ändern, ohne den Code Ihres Clients zu beschädigen (ändern Sie List in eine LinkedList zum Beispiel).

Erwischt

Beachten Sie, dass Sie bei Streaming-Implementierungen (z. B. zeilenweises Abrufen von Daten aus einer Datenbank, anstatt alle Ergebnisse zuerst in den Speicher zu laden) die Auflistung nicht durchlaufen können mehr als einmal. Dies steht im Gegensatz zu speicherinternen Auflistungen wie List , bei denen Sie problemlos mehrere Male iterieren können. ReSharper zum Beispiel hat eine Codeüberprüfung für Mögliche mehrfache Aufzählung von IEnumerable .

IEnumerator

IEnumerator hingegen ist die Schnittstelle hinter den Kulissen, mit der IEnumerble-foreach-magic funktioniert. Genau genommen ermöglicht es explizite Iteratoren.

var iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

Nach meiner Erfahrung wird IEnumerator aufgrund seiner ausführlicheren Syntax und der etwas verwirrenden Semantik in allgemeinen Szenarien selten verwendet (zumindest für mich; z. B. MoveNext () gibt ebenfalls einen Wert zurück, den der Name überhaupt nicht vorschlägt).

Anwendungsfall für IEnumerator

Ich habe nur IEnumerator in bestimmten (etwas niedrigeren) Bibliotheken und Frameworks verwendet, in denen ich IEnumerable Interfaces bereitgestellt habe. Ein Beispiel ist eine Datenstromverarbeitungsbibliothek, die eine Reihe von Objekten in einer foreach -Schleife bereitstellt, obwohl Daten hinter den Kulissen mithilfe verschiedener Dateistreams und Serialisierungen gesammelt wurden.

Client-Code

foreach(var item in feed.GetItems())
    Console.WriteLine(item);

Bibliothek

IEnumerable GetItems() {
    return new FeedIterator(_fileNames)
}

class FeedIterator: IEnumerable {
    IEnumerator GetEnumerator() {
        return new FeedExplicitIterator(_stream);
    }
}

class FeedExplicitIterator: IEnumerator {
    DataItem _current;

    bool MoveNext() {
        _current = ReadMoreFromStream();
        return _current != null;           
    }

    DataItem Current() {
        return _current;   
    }
}
11
ziya

Die Implementierung von IEnumerable bedeutet im Wesentlichen, dass das Objekt wiederholt werden kann. Dies bedeutet nicht notwendigerweise, dass es sich um ein Array handelt, da es bestimmte Listen gibt, die nicht indiziert werden können, aber Sie können sie auflisten.

IEnumerator ist das eigentliche Objekt, das zur Durchführung der Iterationen verwendet wird. Es steuert das Wechseln von einem Objekt zum nächsten in der Liste.

Meistens werden IEnumerable & IEnumerator transparent als Teil einer foreach-Schleife verwendet.

8
Dan Herbert

Unterschiede zwischen IEnumerable und IEnumerator:

  • IEnumerable verwendet intern IEnumerator.
  • IEnumerable weiß nicht, welches Element/Objekt ausgeführt wird. 
  • Immer wenn wir den IEnumerator an eine andere Funktion übergeben, kennt er die aktuelle Position des Elements/Objekts.
  • Immer, wenn wir die IEnumerable-Sammlung an eine andere Funktion übergeben, kennt sie die aktuelle Position des Elements/Objekts nicht (weiß nicht, welches Element ausgeführt wird).

    IEnumerable hat eine Methode GetEnumerator ()

public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

IEnumerator hat eine Eigenschaftsstrom und zwei Methoden Reset und MoveNext (was nützlich ist, um die aktuelle Position eines Elements in einer Liste zu ermitteln).

public interface IEnumerator
{
     object Current { get; }
     bool MoveNext();
     void Reset();
}
5
Ajay

Ein Verständnis des Iterator-Musters wird für Sie hilfreich sein. Ich empfehle, dasselbe zu lesen.

Iterator Pattern

Auf hoher Ebene kann das Iteratormuster verwendet werden, um eine Standardmethode für das Durchlaufen von Sammlungen eines beliebigen Typs bereitzustellen. Wir haben 3 Teilnehmer im Iterator-Pattern, der eigentlichen Sammlung (Client), dem Aggregator und dem Iterator. Das Aggregat ist eine Schnittstelle/abstrakte Klasse, die über eine Methode verfügt, die einen Iterator zurückgibt. Iterator ist eine Schnittstelle/abstrakte Klasse, die über Methoden verfügt, mit denen eine Sammlung durchlaufen werden kann. 

Um das Muster zu implementieren, müssen wir zuerst einen Iterator implementieren, um einen Beton zu erzeugen, der die betroffene Sammlung (Client) durchlaufen kann. Anschließend wird die Sammlung (Client) den Aggregator implementieren, um eine Instanz des obigen Iterators zurückzugeben.

Hier ist das UML-Diagramm  Iterator Pattern

Im Grunde ist in c # IEnumerable das abstrakte Aggregat und IEnumerator der abstrakte Iterator. IEnumerable hat eine einzelne Methode GetEnumerator, die für das Erstellen einer Instanz von IEnumerator des gewünschten Typs verantwortlich ist. Sammlungen wie Listen implementieren das IEnumerable. 

Beispiel . Nehmen wir an, wir haben eine Methode getPermutations(inputString), die alle Permutationen eines Strings zurückgibt und dass die Methode eine Instanz von IEnumerable<string> zurückgibt.

Um die Anzahl der Permutationen zu zählen, könnten wir etwas wie das Folgende tun.

 int count = 0;
        var permutations = perm.getPermutations(inputString);
        foreach (string permutation in permutations)
        {
            count++;
        }

Der c # -Compiler konvertiert das oben genannte mehr oder weniger

using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
        {
            while (permutationIterator.MoveNext())
            {
                count++;
            }
        }

Bei Fragen zögern Sie bitte nicht zu fragen.

4
lalatnayak

IEnumerable ist eine Box, die Ienumerator enthält. IEnumerable ist die Basisschnittstelle für alle Sammlungen. Die foreach-Schleife kann ausgeführt werden, wenn die Auflistung IEnumerable implementiert. Im folgenden Code wird erklärt, wie Sie einen eigenen Enumerator haben. Definieren wir zunächst unsere Klasse, aus der wir die Sammlung zusammenstellen werden.

public class Customer
{
    public String Name { get; set; }
    public String City { get; set; }
    public long Mobile { get; set; }
    public double Amount { get; set; }
}

Nun definieren wir die Klasse, die als Sammlung für unseren Klassenkunden fungiert. Beachten Sie, dass die Schnittstelle IEnumerable implementiert wird. Damit müssen wir die Methode GetEnumerator implementieren. Dies gibt unseren benutzerdefinierten Enumerator zurück.

public class CustomerList : IEnumerable
{
    Customer[] customers = new Customer[4];
    public CustomerList()
    {
        customers[0] = new Customer { Name = "Bijay Thapa", City = "LA", Mobile = 9841639665, Amount = 89.45 };
        customers[1] = new Customer { Name = "Jack", City = "NYC", Mobile = 9175869002, Amount = 426.00 };
        customers[2] = new Customer { Name = "Anil min", City = "Kathmandu", Mobile = 9173694005, Amount = 5896.20 };
        customers[3] = new Customer { Name = "Jim sin", City = "Delhi", Mobile = 64214556002, Amount = 596.20 };
    }

    public int Count()
    {
        return customers.Count();
    }
    public Customer this[int index]
    {
        get
        {
            return customers[index];
        }
    }
    public IEnumerator GetEnumerator()
    {
        return customers.GetEnumerator(); // we can do this but we are going to make our own Enumerator
        return new CustomerEnumerator(this);
    }
}

Jetzt erstellen wir unseren eigenen benutzerdefinierten Enumerator wie folgt. Also müssen wir die Methode MoveNext implementieren.

 public class CustomerEnumerator : IEnumerator
    {
        CustomerList coll;
        Customer CurrentCustomer;
        int currentIndex;
        public CustomerEnumerator(CustomerList customerList)
        {
            coll = customerList;
            currentIndex = -1;
        }

        public object Current => CurrentCustomer;

        public bool MoveNext()
        {
            if ((currentIndex++) >= coll.Count() - 1)
                return false;
            else
                CurrentCustomer = coll[currentIndex];
            return true;
        }

        public void Reset()
        {
            // we dont have to implement this method.
        }
    }

Jetzt können wir foreach loop über unserer Sammlung wie unten verwenden.

    class EnumeratorExample
    {
        static void Main(String[] args)
        {

            CustomerList custList = new CustomerList();
            foreach (Customer cust in custList)
            {
                Console.WriteLine("Customer Name:"+cust.Name + " City Name:" + cust.City + " Mobile Number:" + cust.Amount);
            }
            Console.Read();

        }
    }
3
Amir

Ein kleiner Beitrag.

Da viele von ihnen erklären, wann sie verwendet werden sollen und wann sie mit foreach verwendet werden sollen, dachte ich daran, Another States Difference hier hinzuzufügen, und zwar in der fraglichen Frage nach dem Unterschied zwischen IEnumerable und IEnumerator.

Ich habe das folgende Codebeispiel basierend auf den folgenden Diskussionsthreads erstellt.

IEnumerable, IEnumerator vs foreach, wann was verwendet wirdWas ist der Unterschied zwischen IEnumerator und IEnumerable?

Enumerator behält den Status (Iterationsposition) zwischen Funktionsaufrufen bei, Iterationen dagegen Enumerable nicht. 

Hier ist das getestete Beispiel mit Kommentaren zu verstehen. 

Experten bitte hinzufügen/korrigieren.

static void EnumerableVsEnumeratorStateTest()
{
    IList<int> numList = new List<int>();

    numList.Add(1);
    numList.Add(2);
    numList.Add(3);
    numList.Add(4);
    numList.Add(5);
    numList.Add(6);

    Console.WriteLine("Using Enumerator - Remembers the state");
    IterateFrom1to3(numList.GetEnumerator());

    Console.WriteLine("Using Enumerable - Does not Remembers the state");
    IterateFrom1to3Eb(numList);

    Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}

static void IterateFrom1to3(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());

        if (numColl.Current > 3)
        {
            // This method called 3 times for 3 items (4,5,6) in the collection. 
            // It remembers the state and displays the continued values.
            IterateFrom3to6(numColl);
        }
    }
}

static void IterateFrom3to6(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());
    }
}

static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());

        if (num>= 5)
        {
            // The below method invokes for the last 2 items.
            //Since it doesnot persists the state it will displays entire collection 2 times.
            IterateFrom3to6Eb(numColl);
        }
    }
}

static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
    Console.WriteLine();
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());
    }
}
2
Sai

Ich habe diese Unterschiede bemerkt:

A: Wir wiederholen die Liste auf unterschiedliche Weise, foreach kann für IEnumerable und while-Schleife für IEnumerator verwendet werden.

B. IEnumerator kann sich an den aktuellen Index erinnern, wenn wir von einer Methode zu einer anderen wechseln (er beginnt mit dem aktuellen Index zu arbeiten), IEnumerable kann sich jedoch nicht an den Index erinnern und setzt den Index auf den Anfang zurück. Mehr in diesem Video https://www.youtube.com/watch?v=jd3yUjGc9M0

2
RotatingWheel

IEnumerable und IEnumerator sind beide Schnittstellen in C #.

IEnumerable ist eine Schnittstelle, die eine einzelne Methode GetEnumerator() definiert, die eine IEnumerator-Schnittstelle zurückgibt.

Dies funktioniert für den schreibgeschützten Zugriff auf eine Sammlung, die implementiert, dass IEnumerable mit einer foreach-Anweisung verwendet werden kann.

IEnumerator hat zwei Methoden, MoveNext und Reset. Es hat auch eine Eigenschaft namens Current.

Das Folgende zeigt die Implementierung von IEnumerable und IEnumerator.

1
Jihed Jaoidi
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enudemo
{

    class Person
    {
        string name = "";
        int roll;

        public Person(string name, int roll)
        {
            this.name = name;
            this.roll = roll;
        }

        public override string ToString()
        {
            return string.Format("Name : " + name + "\t Roll : " + roll);
        }

    }


    class Demo : IEnumerable
    {
        ArrayList list1 = new ArrayList();

        public Demo()
        {
            list1.Add(new Person("Shahriar", 332));
            list1.Add(new Person("Sujon", 333));
            list1.Add(new Person("Sumona", 334));
            list1.Add(new Person("Shakil", 335));
            list1.Add(new Person("Shruti", 336));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
           return list1.GetEnumerator();
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            Demo d = new Demo();  // Notice here. it is simple object but for 
                                //IEnumerator you can get the collection data

            foreach (Person X in d)
            {
                Console.WriteLine(X);
            }

            Console.ReadKey();
        }
    }
}
/*
Output : 

Name : Shahriar  Roll : 332
Name : Sujon     Roll : 333
Name : Sumona    Roll : 334
Name : Shakil    Roll : 335
Name : Shruti    Roll : 336
  */
0
Md Shahriar