Geschichte der Frage
Iteratoren sind seit dem Aufkommen von Sammlungen, die durchlaufen werden müssen, ein wichtiger Bestandteil von Programmiersprachen. In Visual Basic wurde mit .NET Unterstützung für IEnumerable/IEnumerator eingeführt, die es ermöglicht, eigene durchlaufbare Sammlungen zu implementieren und die For Each-Schleife für einen bequemen und prägnanten Zugriff auf den Inhalt von Sammlungen zu nutzen.
Problem
Viele Entwickler beschränken sich auf die Verwendung nur der eingebauten Sammlungen oder implementieren das IEnumerable-Interface nicht korrekt, was eine Durchlauf von Objekten über For Each unmöglich macht. Zudem bereitet die Implementierung und der Zustand des Iterators durch Current und MoveNext Schwierigkeiten.
Lösung
Um Iterationen zu unterstützen, implementiert der Typ das IEnumerable-Interface (oder das generische IEnumerable(Of T)). Implementieren Sie die Funktion GetEnumerator, die ein Objekt zurückgibt, das das IEnumerator implementiert. In VB.NET können auch Iteratormethoden mit dem Schlüsselwort Yield (ab VB 2015) verwendet werden, was die Implementierung des Durchlaufens erheblich vereinfacht.
Beispielcode:
Imports System.Collections Public Class SimpleCollection Implements IEnumerable Private arr() As Integer = {1, 2, 3} Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator For Each i In arr Yield i ' für VB 2015+ Next End Function End Class ' Verwendung: For Each n As Integer In New SimpleCollection() Console.WriteLine(n) Next
Wichtige Eigenschaften:
Ist es unbedingt notwendig, beide Schnittstellen: IEnumerable und IEnumerator, zu implementieren, um For Each zu unterstützen?
Nein, es genügt, IEnumerable zu implementieren und einen kompatiblen Iterator zurückzugeben. Wenn Sie eine Durchlaufimplementierung wünschen, können Sie den vorhandenen IEnumerator der eingebetteten Sammlung verwenden. Für eine vollständige Anpassung ist jedoch die Implementierung beider Teile erforderlich.
Beispielcode:
Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return arr.GetEnumerator() ' Verwendung des eingebauten Array-Iterators End Function
Kann IEnumerable in Visual Basic nur explizit (Explicit Interface Implementation) implementiert werden?
Ja, es ist möglich, das Interface explizit zu implementieren, besonders wenn Ihre Sammlung bereits einen eigenen GetEnumerator hat und Sie die Implementierung des Interfaces verbergen möchten. Sie können diesen GetEnumerator nicht direkt aufrufen, aber For Each wird funktionieren.
Beispielcode:
Public Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator ' ...Methodenkörper End Function
Was passiert, wenn GetEnumerator Nothing zurückgibt?
Es wird eine Ausnahme ausgelöst, beim ersten Versuch, die Sammlung zu durchlaufen, da For Each einen gültigen Iterator erwartet.
Die Sammlungsklasse hat IEnumerable nicht implementiert, und eine separate Methode Next wurde erstellt, um die Elemente durchzulaufen. Infolgedessen kann sie nicht in allgemeinen Methoden oder For Each verwendet werden, zusätzliche Methoden müssen geschrieben werden.
Vorteile:
Nachteile:
Der Entwickler hat IEnumerable und GetEnumerator implementiert, die Sammlung funktioniert jetzt mit For Each und integriert sich in LINQ.
Vorteile:
Nachteile: