ProgrammierungVB.NET Entwickler

Beschreiben Sie, wie die For...Each...Next-Schleife in Visual Basic mit benutzerdefinierten Sammlungen funktioniert. Wie erstellt man eine eigene Sammlung, um sie in For Each zu durchlaufen, und was muss dafür implementiert werden?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Geschichte der Frage:

Die Anweisung For Each...Next in Visual Basic ermöglicht es, Elemente von Sammlungen oder Arrays durchzugehen. Seit VB6 wurde der Durchlauf über Standardkollektionen unterstützt, und in VB.NET über alle Typen, die ein bestimmtes Interface implementieren. Wenn benutzerdefinierte Sammlungen für den eigenen Durchlauf erstellt werden müssen, ist es wichtig, die erforderliche Infrastruktur korrekt zu implementieren.

Problem

Es reicht nicht aus, die Speicherung von Elementen zu implementieren — For Each-Anweisungen erfordern die Unterstützung des speziellen Interfaces IEnumerable. Oft beschränkten sich die Ansammlungen benutzerdefinierter Sammlungen auf die Methoden Add/Get, das Objekt wurde zu einer "schwarzen Box" für die Iteration. Dies hinderte die Integration mit der Sprachstruktur des Durchlaufs und führte zu Fehlern.

Lösung

Damit For Each korrekt mit Ihrer Sammlung funktioniert, muss das Interface IEnumerable implementiert werden, und zur Unterstützung der Arbeit mit typisierten Elementen — IEnumerable(Of T). Es ist notwendig, einen eigenen Enumerator (Enumerator) zu erstellen, der das Interface IEnumerator (oder IEnumerator(Of T) in generischen Versionen) implementiert.

Beispiel:

Public Class IntCollection Implements IEnumerable(Of Integer) Private ReadOnly items As New List(Of Integer)() Public Sub Add(value As Integer) items.Add(value) End Sub Public Function GetEnumerator() As IEnumerator(Of Integer) _ Implements IEnumerable(Of Integer).GetEnumerator Return items.GetEnumerator() End Function Private Function IEnumerable_GetEnumerator() As IEnumerator _ Implements IEnumerable.GetEnumerator Return GetEnumerator() End Function End Class ' Verwendung: Dim col As New IntCollection() col.Add(10) col.Add(20) col.Add(30) For Each n As Integer In col Console.WriteLine(n) Next

Wichtige Merkmale:

  • Die Implementierung von GetEnumerator-Methoden und die Rückgabe von IEnumerator oder IEnumerator(Of T) sind erforderlich.
  • Unterstützung von generischen und nicht-generischen IEnumerable für die Kompatibilität mit verschiedenen Versionen der Umgebung.
  • Eine fertige Sammlung kann an LINQ teilnehmen, in For Each verwendet werden und mit der Standardinfrastruktur von .NET arbeiten.

Trickfragen.

Kann man For Each ohne das Interface IEnumerable implementieren, indem man einfach eine Methode GetEnumerator schreibt?

Nein, Visual Basic erfordert die offizielle Unterstützung des Interfaces IEnumerable/IEnumerable(Of T), damit der Compiler die Sammlung als mit For Each kompatibel erkennt.

Muss der Enumerator eine separate Klasse sein?

Nein, wenn die Elementdatenbank einen standardmäßigen Enumerator unterstützt (zum Beispiel, wenn Sie List(Of T) aggregieren), kann sein GetEnumerator zurückgegeben werden. Nur in komplexen Szenarien könnte eine eigene Implementierungsklasse IEnumerator erforderlich sein.

Ist es möglich, die Sammlung innerhalb der For Each-Schleife zu ändern?

Nein, Änderungen an der Sammlung während der Iteration führen zu einer InvalidOperationException. Für eine korrekte Verarbeitung sind spezielle Strategien erforderlich (zum Beispiel, eine Kopie der Liste vor der Iteration zu erstellen oder Indizes zu verwenden).

Typische Fehler und Anti-Pattern

  • Implementierung nur von Add/Remove ohne IEnumerable — kann For Each nicht verwendet werden.
  • Rückgabe nicht vorhandener oder inkorrekter Enumerator — führt zu Fehlern während der Iteration.
  • Änderung der Sammlung im Körper der For Each-Schleife.

Beispiel aus dem Leben

Negativer Fall

In einem Unternehmen wurde eine eigene Klasse MyCollection mit Hinzufügen und Entfernen über ein Array entwickelt, jedoch ohne Implementierung des Interfaces IEnumerable. For Each funktionierte nicht, es mussten normale Schleifen und ein öffentliches Feld mit Elementen verwendet werden.

Vorteile:

  • Schnelle Erstellung der Sammlung — minimales Code.

Nachteile:

  • For Each konnte nicht verwendet werden, LINQ nicht, und man konnte nicht wie mit Standardkollektionen damit arbeiten.
  • Duplicated Code für Iterationen an verschiedenen Stellen.

Positiver Fall

Die Klasse wurde umgerüstet, indem IEnumerable(Of T) implementiert wurde. Danach konnte die Sammlung leicht und standardmäßig in For Each verwendet werden und war auch mit LINQ kompatibel.

Vorteile:

  • Saubere, standardisierte Syntax.
  • Das Durchlaufen der Sammlung ist mit allen infrastrukturellen Möglichkeiten von VB.NET kompatibel.

Nachteile:

  • Es muss mehr Code hinzugefügt werden, um die Schnittstellen zu unterstützen.