IEnumerator<T>, IEnumerable<T>

  • Allgemein

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

    IEnumerator<T>, IEnumerable<T>

    In letzter Zeit stoße ich des öfteren auf Ausdrücke wie
    • outputCallback As Action(Of IEnumerable(Of Integer))
    • chars As IEnumerable(Of Char)
    Ich habe schon mal ein bisschen auf den MSDN Seiten nachgeforscht, aber irgendwie keine Erklärung dafür gefunden, wieso diese Schnittstellen so oft auftauchen, bzw. was ihre Vorteile sind ?
    Ich habe mal testweise IEnumerable(of T) implementiert.
    Heraus kommen diese beiden Methoden.

    VB.NET-Quellcode

    1. Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
    2. Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator

    Alles schön und gut. Aber welche Vorteile bringt mir das nun ?
    Wofür und wann verwendet man IEnumerable ?

    Dann bin ich noch auf sowas hier gestoßen. (Quelle: de.wikipedia.org/wiki/Enumerator)

    C-Quellcode

    1. // explizite Version
    2. IEnumerator<MyType> iter = list.GetEnumerator();
    3. while (iter.MoveNext())
    4. Console.WriteLine(iter.Current);
    5. // implizite Version
    6. foreach (MyType value in list)
    7. Console.WriteLine(value);

    Was bringt es mir also nun IEnumerable oder IEnumerator zu implementieren ?
    Das Problem, das du hast, ist, dass du das anders kennst. ;)

    Die Schnittstelle IEnumerable macht eben die Methode 'GetEnumerator' verfügbar. Fast alle Collections implementieren dieses Interface, denn man kann damit die einzelnen Elemente durchlaufen bzw. sich durch iterieren.
    Du kennst das eher als For Each, dahinter steckt jedoch genau das. ;)
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Danke @Artentus:. Nun ist es viel klarer.
    Mir ist aber noch nicht ganz klar, wieso man das den jetzt verwendet ?

    Mal ein Beispiel. Ich habe diese Function hier. Quelle [VB.NET] Permutation ohne Rekursion

    VB.NET-Quellcode

    1. Public Shared Sub PermutateRecursive(chars As IEnumerable(Of Char), ByRef result As List(Of String))
    2. If chars.Count() = 1 Then
    3. result.Add(chars.First().ToString())
    4. Return
    5. End If
    6. For Each c In chars
    7. Dim buffer = New List(Of String)()
    8. PermutateRecursive(chars.Except({c}), buffer)
    9. For Each s In buffer
    10. result.Add(c & s)
    11. Next
    12. Next
    13. End Sub

    Er will hier mehrere Chars als Parameter. Wieso nehme ich IEnumerable(Of Char), und nicht List(of Char) ?
    Kla, wie ich jetzt weiß implementiert List(of T) auch IEnumerable(of T), und so kann ich auch eine Liste übergeben. Aber dann könnte ich ja auch direkt eine Liste nehmen, oder ? :)
    Wie gesagt, fast jede Collection bzw. Auflistung implementiert diese Schnittstelle, um sich mit dem Enumerator durchzuarbeiten. Es gibt 4 elementare Interfaces. IEnumerable für das iterieren bzw durchlaufen der Auflistung, ICollection, IList und IDictionary.
    Hierbei gibt es eine Hierarchie. Aus IEnumerable leiten sich alle anderen Interfaces ab.



    Die Schnittstelle ICollection implementiert die Methoden Count zum Zählen, die Property IsSynchronisized, um zu prüfen, ob ein Objekt in der Collection threadsicher ist und noch die Methode CopyTo, um alle Elemente in ein Array zu kopieren. Dann gibt's da noch was, aber das ist das wichtigste.

    Alle Auflistungen, die IList implementieren, geben auch eine Garantie alles über Indizien zu regeln.
    Das gewöhnt man sich schnell an, ohne drüber nachzudenken.
    Also, das macht die List(Of T), das Array usw, nur, dass das Array keine dynamische Liste ist, denn wenn ein Objekt in der Auflistung gelöscht wird, bleibt der Index weiter frei und unbesetzt, während bei der List(Of T) beispielsweise dieser Index wieder belegt wird, denn diese Auflistung passt sich der Änderung an.


    IList macht alle Methoden, wie Add, Remove, IndexOf etc. verfügbar. Die kennst du auch alle, denke ich und dahinter steckt die Implementierung dieses Interfaces.

    IDictionary ist das Gegenteil von IList, denn hier wird statt dem Indizes, ein Schlüsselwertepaar verwendet. Die Klasse HashTable implementiert diese Schnittstelle.
    Wenn man nach einem bestimmten Element sucht und dessen Position nicht kennt, muss man die Liste so lange durchlaufen, bis man eine Übereinstimmung findet. Enthält die Auflistung sehr viele Einträge, kann das sehr zeitaufwändig sein und kostet Rechenleistung. Das ist halt mit den Schlüsselwerteparen einfacher.


    Wichtig ist auch immer, drauf zu achten, Auflistungen zu nehmen, die Generika unterstützen. Das erkennst du am (Of T).
    List(Of T), Stack(Of T) etc. unterstützen also Generika und somit immer das nehmen, denn ohne Generika hat man dann Objects drinne und ich hoffe, du weißt, warum das nicht gut ist ;)

    ArrayList unterstützt kein Generika, drum sollte man diese meiden und die richtige Alternative List(Of T) nehmen.
    Es gibt auch die Auflistungen, wie List ohne Generika, diese einfach ignorieren und die anderen nehmen. Ein Array übrigens zeigt kein (Of T) an, ist aber in Ordnung, da die Deklarierung halt anders ist.

    Man gibt ja kein Object, sondern einen konkreten Datentypen an.

    Dim str As String() ist ja dann eine Auflistung von Strings.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Trade“ ()