Frage

Ich verwende den folgenden Code, damit MyClass foreach verwendet werden kann. Aber ich bin ziemlich neu im Programmieren und habe Schwierigkeiten, den folgenden Code zu verstehen. Ich habe meine Probleme in den Kommentaren beschrieben. Ich wäre dankbar für die Bereitstellung von Informationen.

    public class MyClass : IEnumerable<string> 
    {  
    //1) What is IEnumerator for?
        // Whats the difference between IEnumerator and IEnumerable
    public IEnumerator<string> GetEnumerator()     
    {
             yield return "first";         
             yield return "second";     
    }      
    //2) What is it for?  It just calls above method 
   IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator(); 
         } 
    }
   //3) Lastly what benefits I have from implementing genetic interface 
   //IEnumerable<string> instead of just IEnumerable
War es hilfreich?

Lösung

Was ist der Unterschied zwischen Ienumerator und Ienumerable?

Jasons Antwort ist gut, aber ich dachte, ich würde nur hinzufügen, wie ich darüber nachdenke. Stellen Sie sich vor, Sie haben eine Sequenz:

1, 1, 2, 3, 5, 8, 13, ...

Stellen Sie sich nun vor, Sie haben einen Pfeil, der auf eine Position dieser Sequenz zeigt:

1, 1, 2, 3, 5, 8, 13, ...
         ^

Ein "Pfeil" ist ein Objekt, das zwei Dinge tun kann. Erstens kann es Ihnen das geben, worauf es zeigt. Zweitens kann es sich auf die nächste Sache zeigen.

Ienumerator ist ein Pfeil. Es hat eine Eigenschaft, die Ihnen das gibt, worauf es zeigt. Es hat eine Methode, MoveNext (), die sich auf die nächste Sache zeigt.

Wie bekommt man überhaupt einen Pfeil? Sie brauchen eine Pfeilfabrik. Sie fragen die Fabrik um einen Pfeil, und es gibt Ihnen einen Pfeil, der auf das erste Element in der Sequenz hinweist.

Ienumerable ist eine Pfeilfabrik. Es hat eine Methode, Getenumerator, die Ihnen einen Pfeil zum ersten Element der Sequenz gibt.

Eine schöne Eigenschaft dieses Schemas ist, dass Sie mehrere Pfeile haben können, die auf verschiedene Orte in derselben Reihenfolge hinweisen.

Was sind die Vorteile der Implementierung der generischen Schnittstelle iEnumerable anstatt nur Ienumerable?

Angenommen, die Sequenz ist von Ganzzahlen. Wenn Sie implementieren IEnumerable Dann, wenn du sagst

foreach(int x in mysequence)

Dies wird tatsächlich tun, ist, die INT in der Sequenz in Objekt zu konvertieren, die Ganzzahl zu dopfen und dann das Objekt sofort wieder zu Ganzzahl zu entbinden und jeder einzelnen Operation eine völlig unnötige Speicherzuweisung hinzuzufügen. Wenn der Compiler weiß, dass die Sequenz von Ganzzahlen besteht, kann er den unnötigen Boxvorgang überspringen.

Angenommen, die Sequenz besteht aus Saiten. Wenn Sie implementieren IEnumerable<string> Dann können Sie sagen:

string first = mysequence.First();

Wenn Sie dies nicht tun, müssen Sie sagen

string first = (string)mysequence.First();

das ist unnötig und fehleranfällig. Anstatt den Compiler über eine Besetzung zu unterweisen, dass der Typ String ist, können Sie einfach Garantie dass der Typ anhand des Typsystems eine Zeichenfolge ist.

Andere Tipps

1) Was ist IEnumerator zum? Was ist der Unterschied zwischen IEnumerator und IEnumerable?

IEnumerator ist eine Schnittstelle, die Methoden darstellt, mit denen Sie eine Sequenz aufzählen können. Der Unterschied zwischen IEnumerator und IEnumerable ist, dass ersterer den Vertrag für Objekte darstellt, mit denen Sie eine Sequenz aufzählen können, und der letztere den Vertrag für Objekte darstellt, die eine Sequenz sind, die aufgezählt werden kann.

public IEnumerator<string> GetEnumerator() {
         yield return "first";         
         yield return "second";     
}      


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

2) Wofür ist es? Es werden nur die obige Methode aufgerufen.

Ersteres stellt eine Implementierung der Methode dar GetEnumerator auf den Vertrag IEnumerable<string>. Letzteres stellt eine explizite Implementierung der Methode dar GetEnumerator auf den Vertrag IEnumerable. Das Problem ist, dass beide Verträge eine Methode namens mit dem Namen haben GetEnumerator Aber mit unterschiedlichen Rückgabetypen, damit eine Methode beide Verträge nicht gleichzeitig erfüllen kann (jede Klasse implementieren IEnumerable<T> muss auch implementieren IEnumerable wie IEnumerable<T> : IEnumerable). Letzteres ruft die Implementierung von an IEnumerable<string>.GetEnumerator Da ist dies eine vernünftige Implementierung, die eine zurückgibt IEnumerator wie IEnumerator<string> : IEnumerator.

3) Schließlich, welche Vorteile ich durch die Implementierung der generischen Schnittstelle habe IEnumerable<string> statt gerecht IEnumerable?

Starke Typisierung. Sie wissen, dass die Elemente in einer Sequenz IEnumerable<string> sind alle Fälle von String Während Sie das nicht wissen für IEnumerable und könnte am Ende versuchen, ein Element des letzteren in einen Fall von zu werfen String wenn es nicht sein kann.

Dies ist die Erklärung für IEnumerable<T>:

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

Sie haben keine Wahl, Sie haben Um die nicht generische ienumerable Schnittstelle zu implementieren. Sie erhalten einen Kompilierfehler, wenn Sie die Implementierung von iEnumerable.getenumerator () weglassen. Dies ist ein Gepäck, das aus den .NET 1.x -Tagen übrig geblieben ist, an denen Generika noch nicht verfügbar waren, und die Übergangszeit für .NET 2.0, in der die Interop mit .NET 1.x -Baugruppen unterstützt werden musste. Wir bleiben dabei.

1) Wofür ist Ienumerator?

Ienumerator ist der eigentliche Arbeitsteil mit MoveNext () und aktuellen Mitgliedern.

Was ist der Unterschied zwischen Ienumerator und Ienumerable

IEnumerable ist die Schnittstelle für eine Sammlung, um zu signalisieren, dass es einen Getenumerator () hat.

2) [nicht generischer Getenumerator] Wofür ist es? Es werden nur die obige Methode aufgerufen

Die nicht generische Methode ist nur für die Rückwärtskompatibilität vorhanden. Beachten Sie, dass es durch die Verwendung der expliziten Implementierung so weit wie möglich außer Sichtweite bewegt wird. Implementieren Sie es, weil Sie es müssen und dann vergessen.

3) Schließlich habe ich Vorteile, die ich durch die Implementierung der genetischen Schnittstelle iEnumerable statt nur iEnumerable habe

Wenn mit verwendet foreach Der Adavantage ist klein, da Foreach die Schleifenvariable eintippt. Sie können Sie verwenden lassen var im foreach:

foreach (var s in myClassInstance)     // needs `IEnumerable<string>` 
foreach (string s in myClassInstance)  // works with  `IEnumerable` as well 

Aber mit IEnumerable<string> Sie haben auch eine Typ-Sicherheit-Schnittstelle zu anderen Bereichen, vor allem Linq:

MyClass mc = new MyClass ();
string s = mc.FirstOrDefault();

GetEnumerator Es gibt seit seiner Einführung von Generika in die Sprache, um den bereits bestehenden Code nicht zu brechen, die Standardmethode ruft zur generischen Implementierung auf.

Mit einer generischen Aufzählung muss der Verbraucher Ihrer Klasse nicht jedes Element beim Iterieren an die String geben.

In Bezug auf die 3. Frage (warum Generika verwenden?) Hier finden Sie einige Antworten:

Sollten wir eine generische Sammlung verwenden, um Sicherheit und Leistung zu verbessern?

Kurz gesagt, verwenden Sie jedes Mal generische Sammlungen, wenn Sie können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top