Auflistungen (Visual Basic)
Für eine Vielzahl von Anwendungen sollten Sie Gruppen von miteinander verwandten Objekten erstellen und verwalten. Zum Gruppieren von Objekten gibt es zwei Möglichkeiten: das Erstellen von Objektarrays und das Erstellen von Auflistungen von Objekten.
Arrays eignen sich bestens zum Erstellen und Arbeiten mit einer festen Anzahl von Objekten mit starkem Typ. Weitere Informationen zu Arrays finden Sie unter Arrays.
Auflistungen ermöglichen ein flexibleres Arbeiten mit Objektgruppen. Im Gegensatz zu Arrays kann sich die Gruppe von Objekten, mit denen Sie arbeiten, in Abhängigkeit von den sich ändernden Anforderungen der Anwendung dynamisch vergrößern bzw. verkleinern. Bei einigen Auflistungen können Sie jedem Objekt, das Sie in die Auflistung einfügen, einen Schlüssel zuweisen, sodass das Objekt anhand des Schlüssels schnell abgerufen werden kann.
Eine Auflistung ist eine Klasse. Daher müssen Sie eine Instanzen der Klasse deklarieren, bevor Sie dieser Auflistung Elemente hinzufügen können.
Wenn die Auflistung Elemente eines Datentyps enthält, können Sie eine der Klassen im System.Collections.Generic-Namespace verwenden. Eine generische Auflistung erzwingt Typsicherheit, sodass der Auflistung kein anderer Datentyp hinzugefügt werden kann. Wenn Sie ein Element aus einer generischen Auflistung abrufen, brauchen Sie dessen Datentyp nicht zu bestimmen oder zu konvertieren.
Hinweis
Die Beispiele in diesem Thema enthalten Imports-Anweisungen für die Namespaces System.Collections.Generic
und System.Linq
.
Verwenden einer einfachen Auflistung
In den Beispielen in diesem Abschnitt wird die generische Klasse List<T> verwendet, die es Ihnen ermöglicht, mit einer stark typisierten Liste von Objekten zu arbeiten.
Das folgende Beispiel erstellt eine Liste von Zeichenfolgen und durchläuft diese dann mithilfe einer For Each…Next-Anweisung.
' Create a list of strings.
Dim salmons As New List(Of String)
salmons.Add("chinook")
salmons.Add("coho")
salmons.Add("pink")
salmons.Add("sockeye")
' Iterate through the list.
For Each salmon As String In salmons
Console.Write(salmon & " ")
Next
'Output: chinook coho pink sockeye
Wenn der Inhalt einer Auflistung im Voraus bekannt ist, können Sie einen Auflistungsinitialisierer verwenden, um die Auflistung zu initialisieren. Weitere Informationen finden Sie unter Auflistungsinitialisierer.
Das folgende Beispiel entspricht dem vorherigen Beispiel, außer dass ein Auflistungsinitialisierer verwendet wird, um der Auflistung Elemente hinzuzufügen.
' Create a list of strings by using a
' collection initializer.
Dim salmons As New List(Of String) From
{"chinook", "coho", "pink", "sockeye"}
For Each salmon As String In salmons
Console.Write(salmon & " ")
Next
'Output: chinook coho pink sockeye
Sie können anstelle einer For…Next-Anweisung auch eine For Each
-Anweisung verwenden, um eine Auflistung zu durchlaufen. Sie erreichen dies, indem Sie durch die Indexposition auf die Auflistungselemente zugreifen. Der Index der Elemente beginnt mit 0 und endet an der Elementanzahl minus 1.
Im folgenden Beispiel werden die Elemente einer Auflistung unter Verwendung von For…Next
anstelle von For Each
durchlaufen.
Dim salmons As New List(Of String) From
{"chinook", "coho", "pink", "sockeye"}
For index = 0 To salmons.Count - 1
Console.Write(salmons(index) & " ")
Next
'Output: chinook coho pink sockeye
Im folgenden Beispiel wird ein Element aus der Auflistung entfernt, indem das zu entfernende Objekt angegeben wird.
' Create a list of strings by using a
' collection initializer.
Dim salmons As New List(Of String) From
{"chinook", "coho", "pink", "sockeye"}
' Remove an element in the list by specifying
' the object.
salmons.Remove("coho")
For Each salmon As String In salmons
Console.Write(salmon & " ")
Next
'Output: chinook pink sockeye
Im folgenden Beispiel werden alle Elemente aus einer generischen Liste entfernt. Anstelle einer For Each
-Anweisung wird eine For…Next-Anweisung verwendet, die die Elemente in absteigender Reihenfolge durchläuft. Dies liegt daran, dass die RemoveAt-Methode dazu führt, dass Elemente nach einem entfernten Element einen niedrigeren Indexwert haben.
Dim numbers As New List(Of Integer) From
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
' Remove odd numbers.
For index As Integer = numbers.Count - 1 To 0 Step -1
If numbers(index) Mod 2 = 1 Then
' Remove the element by specifying
' the zero-based index in the list.
numbers.RemoveAt(index)
End If
Next
' Iterate through the list.
' A lambda expression is placed in the ForEach method
' of the List(T) object.
numbers.ForEach(
Sub(number) Console.Write(number & " "))
' Output: 0 2 4 6 8
Für den Typ der Elemente in List<T> können Sie auch eine eigene Klasse definieren. Im folgenden Beispiel wird die Galaxy
-Klasse, die von List<T> verwendet wird, im Code definiert.
Private Sub IterateThroughList()
Dim theGalaxies As New List(Of Galaxy) From
{
New Galaxy With {.Name = "Tadpole", .MegaLightYears = 400},
New Galaxy With {.Name = "Pinwheel", .MegaLightYears = 25},
New Galaxy With {.Name = "Milky Way", .MegaLightYears = 0},
New Galaxy With {.Name = "Andromeda", .MegaLightYears = 3}
}
For Each theGalaxy In theGalaxies
With theGalaxy
Console.WriteLine(.Name & " " & .MegaLightYears)
End With
Next
' Output:
' Tadpole 400
' Pinwheel 25
' Milky Way 0
' Andromeda 3
End Sub
Public Class Galaxy
Public Property Name As String
Public Property MegaLightYears As Integer
End Class
Arten von Auflistungen
Viele allgemeine Auflistungen werden von .NET Framework bereitgestellt. Jeder Auflistungstyp ist für einen speziellen Zweck ausgelegt.
Einige der häufig verwendeten Auflistungsklassen werden in diesem Abschnitt beschrieben:
System.Collections.Generic-Klassen
System.Collections.Concurrent-Klassen
System.Collections-Klassen
Visual Basic-
Collection
sklasse
System.Collections.Generic-Klassen
Zum Erstellen einer generischen Auflistung verwenden Sie eine der Klassen im System.Collections.Generic-Namespace. Eine generische Auflistung ist sinnvoll, wenn jedes Element der Auflistung zum gleichen Datentyp gehört. Eine generische Auflistung erzwingt eine starke Typisierung, da ihr nur Elemente des gewünschten Datentyps hinzugefügt werden können.
In der folgenden Tabelle werden einige der häufig verwendeten Klassen des System.Collections.Generic-Namespace aufgelistet:
Klasse | Beschreibung |
---|---|
Dictionary<TKey,TValue> | Stellt eine Auflistung von Schlüssel-Wert-Paaren dar, deren Reihenfolge anhand des Schlüssels bestimmt wird. |
List<T> | Stellt eine Liste von Objekten dar, auf die über einen Index zugegriffen werden kann. Stellt Methoden zum Durchsuchen, Sortieren und Bearbeiten von Listen bereit. |
Queue<T> | Stellt eine FIFO-Auflistung (First In, First Out) von Objekten dar. |
SortedList<TKey,TValue> | Stellt eine Auflistung von Schlüssel-Wert-Paaren dar, die auf Grundlage der zugeordneten IComparer<T>-Implementierung nach den Schlüsseln sortiert sind. |
Stack<T> | Stellt eine LIFO-Auflistung (Last In, First Out) von Objekten dar. |
Weitere Informationen finden Sie unter Häufig verwendete Auflistungstypen, Auswählen einer Auflistungsklasse und System.Collections.Generic.
System.Collections.Concurrent-Klassen
In .NET Framework 4 oder höher stellen die Auflistungen im Namespace System.Collections.Concurrent effiziente threadsichere Vorgänge für den Zugriff auf Auflistungselemente aus mehreren Threads bereit.
Die Klassen im System.Collections.Concurrent-Namespace sollten anstelle von entsprechenden Typen in System.Collections.Generic- und System.Collections-Namespaces verwendet werden, wenn mehrere Threads gleichzeitig auf die Auflistung zugreifen. Weitere Informationen finden Sie unter Threadsichere Auflistungen und System.Collections.Concurrent.
Einige der in die System.Collections.Concurrent-Namespaces aufgenommenen Klassen sind BlockingCollection<T>, ConcurrentDictionary<TKey,TValue>, ConcurrentQueue<T> und ConcurrentStack<T>.
System.Collections-Klassen
Bei den Klassen im System.Collections-Namespace werden Elemente nicht als speziell typisierte Objekte, sondern als Objekte vom Typ Object
gespeichert.
Sofern möglich sollten die generischen Auflistungen im System.Collections.Generic-Namespace oder System.Collections.Concurrent-Namespace anstelle der älteren Typen im System.Collections
-Namespace verwendet werden.
In der folgenden Tabelle werden einige der häufig verwendeten Klassen im System.Collections
-Namespace aufgelistet:
Klasse | Beschreibung |
---|---|
ArrayList | Stellt ein Array von Objekten dar, das je nach Bedarf dynamisch vergrößert wird. |
Hashtable | Stellt eine Auflistung von Schlüssel-Wert-Paaren dar, die auf Grundlage des Hashcodes des Schlüssels geordnet sind. |
Queue | Stellt eine FIFO-Auflistung (First In, First Out) von Objekten dar. |
Stack | Stellt eine LIFO-Auflistung (Last In, First Out) von Objekten dar. |
Der System.Collections.Specialized-Namespace bietet spezialisierte und stark typisierte Auflistungsklassen, beispielsweise für Zeichenfolgenauflistungen sowie für Wörterbücher mit verketteten Listen und Hybridwörterbücher.
Visual Basic-Auflistungsklasse
Sie können die Visual Basic-Klasse Collection verwenden, um auf ein Auflistungselement zuzugreifen, indem Sie entweder einen numerischen Index oder einen String
schlüssel verwenden. Sie können einem Auflistungsobjekt Elemente entweder mit oder ohne Angabe eines Schlüssels hinzufügen. Wenn Sie ein Element ohne einen Schlüssel hinzufügen, müssen Sie seinen numerischen Index verwenden, um darauf zuzugreifen.
Die Visual Basic-Klasse Collection
speichert alle Elemente als Object
-Typ, damit Elemente eines beliebigen Datentyps hinzugefügt werden können. Es gibt keine Vorkehrung, die das Hinzufügen ungeeigneter Datentypen verhindert.
Wenn Sie die Visual Basic-Klasse Collection
verwenden, hat das erste Element in einer Auflistung einen Index von 1. Dies unterscheidet sich von den .NET Framework-Auflistungsklassen, deren Startindex 0 ist.
Sofern möglich sollten die generischen Auflistungen im System.Collections.Generic-Namespace oder im System.Collections.Concurrent-Namespace anstelle der Visual Basic-Klasse Collection
verwendet werden.
Weitere Informationen finden Sie unter Collection.
Implementieren einer Auflistung von Schlüssel/Wert-Paaren
Die generische Auflistung Dictionary<TKey,TValue> ermöglicht es Ihnen, unter Verwendung des Schlüssels der einzelnen Elemente auf die Elemente einer Auflistung zuzugreifen. Jede Hinzufügung zum Wörterbuch besteht aus einem Wert und dem zugeordneten Schlüssel. Ein Wert kann anhand des zugehörigen Schlüssels schnell abgerufen werden, da die Dictionary
-Klasse in Form einer Hashtabelle implementiert ist.
Das folgende Beispiel erstellt eine Dictionary
-Auflistung und durchläuft das Wörterbuch unter Verwendung einer For Each
-Anweisung.
Private Sub IterateThroughDictionary()
Dim elements As Dictionary(Of String, Element) = BuildDictionary()
For Each kvp As KeyValuePair(Of String, Element) In elements
Dim theElement As Element = kvp.Value
Console.WriteLine("key: " & kvp.Key)
With theElement
Console.WriteLine("values: " & .Symbol & " " &
.Name & " " & .AtomicNumber)
End With
Next
End Sub
Private Function BuildDictionary() As Dictionary(Of String, Element)
Dim elements As New Dictionary(Of String, Element)
AddToDictionary(elements, "K", "Potassium", 19)
AddToDictionary(elements, "Ca", "Calcium", 20)
AddToDictionary(elements, "Sc", "Scandium", 21)
AddToDictionary(elements, "Ti", "Titanium", 22)
Return elements
End Function
Private Sub AddToDictionary(ByVal elements As Dictionary(Of String, Element),
ByVal symbol As String, ByVal name As String, ByVal atomicNumber As Integer)
Dim theElement As New Element
theElement.Symbol = symbol
theElement.Name = name
theElement.AtomicNumber = atomicNumber
elements.Add(Key:=theElement.Symbol, value:=theElement)
End Sub
Public Class Element
Public Property Symbol As String
Public Property Name As String
Public Property AtomicNumber As Integer
End Class
Wenn stattdessen ein Auflistungsinitialisierer zum Erstellen der Dictionary
-Auflistung verwendet werden soll, können Sie die BuildDictionary
- und AddToDictionary
-Methoden durch die folgende Methode ersetzen.
Private Function BuildDictionary2() As Dictionary(Of String, Element)
Return New Dictionary(Of String, Element) From
{
{"K", New Element With
{.Symbol = "K", .Name = "Potassium", .AtomicNumber = 19}},
{"Ca", New Element With
{.Symbol = "Ca", .Name = "Calcium", .AtomicNumber = 20}},
{"Sc", New Element With
{.Symbol = "Sc", .Name = "Scandium", .AtomicNumber = 21}},
{"Ti", New Element With
{.Symbol = "Ti", .Name = "Titanium", .AtomicNumber = 22}}
}
End Function
Im folgenden Beispiel werden die ContainsKey-Methode und die Item[]-Eigenschaft von Dictionary
verwendet, um anhand des Schlüssels schnell nach einem Element zu suchen. Die Item
-Eigenschaft ermöglicht den Zugriff auf ein Element in der elements
-Auflistung unter Verwendung des elements(symbol)
-Codes in Visual Basic.
Private Sub FindInDictionary(ByVal symbol As String)
Dim elements As Dictionary(Of String, Element) = BuildDictionary()
If elements.ContainsKey(symbol) = False Then
Console.WriteLine(symbol & " not found")
Else
Dim theElement = elements(symbol)
Console.WriteLine("found: " & theElement.Name)
End If
End Sub
Im folgenden Beispiel wird stattdessen die TryGetValue-Methode verwendet, um anhand des Schlüssels schnell nach einem Element zu suchen.
Private Sub FindInDictionary2(ByVal symbol As String)
Dim elements As Dictionary(Of String, Element) = BuildDictionary()
Dim theElement As Element = Nothing
If elements.TryGetValue(symbol, theElement) = False Then
Console.WriteLine(symbol & " not found")
Else
Console.WriteLine("found: " & theElement.Name)
End If
End Sub
Verwenden von LINQ zum Zugriff auf eine Auflistung
LINQ (Language-Integrated Query) kann verwendet werden, um auf Auflistungen zuzugreifen. LINQ-Abfragen stellen Filter-, Sortier- und Gruppierungsfunktionen bereit. Weitere Informationen finden Sie unter Erste Schritte mit LINQ in Visual Basic.
Im folgenden Beispiel wird eine LINQ-Abfrage für eine generische List
ausgeführt. Die LINQ-Abfrage gibt eine andere Auflistung zurück, die die Ergebnisse enthält.
Private Sub ShowLINQ()
Dim elements As List(Of Element) = BuildList()
' LINQ Query.
Dim subset = From theElement In elements
Where theElement.AtomicNumber < 22
Order By theElement.Name
For Each theElement In subset
Console.WriteLine(theElement.Name & " " & theElement.AtomicNumber)
Next
' Output:
' Calcium 20
' Potassium 19
' Scandium 21
End Sub
Private Function BuildList() As List(Of Element)
Return New List(Of Element) From
{
{New Element With
{.Symbol = "K", .Name = "Potassium", .AtomicNumber = 19}},
{New Element With
{.Symbol = "Ca", .Name = "Calcium", .AtomicNumber = 20}},
{New Element With
{.Symbol = "Sc", .Name = "Scandium", .AtomicNumber = 21}},
{New Element With
{.Symbol = "Ti", .Name = "Titanium", .AtomicNumber = 22}}
}
End Function
Public Class Element
Public Property Symbol As String
Public Property Name As String
Public Property AtomicNumber As Integer
End Class
Sortieren einer Auflistung
Das folgende Beispiel zeigt ein Verfahren zum Sortieren einer Auflistung. In dem Beispiel werden Instanzen der Car
-Klasse sortiert, die in List<T> gespeichert sind. Die Car
-Klasse implementiert die IComparable<T>-Schnittstelle, die die Implementierung der CompareTo-Methode erfordert.
Jeder Aufruf der CompareTo-Methode führt einen einzelnen Vergleich aus, der für die Sortierung verwendet wird. Vom Benutzer erstellter Code in der CompareTo
-Methode gibt einen Wert für jeden Vergleich des aktuellen Objekts mit einem anderen Objekt zurück. Der zurückgegebene Wert ist kleiner als Null, wenn das aktuelle Objekt kleiner ist als das andere Objekt, größer als Null, wenn das aktuelle Objekt größer als das andere Objekt ist und Null, wenn beide Objekt gleich groß sind. Dies ermöglicht es Ihnen, in dem Code die Kriterien für größer als, kleiner als und gleich zu definieren.
In der ListCars
-Methode sortiert die cars.Sort()
-Anweisung die Liste. Dieser Aufruf der Sort-Methode von List<T> führt dazu, dass die CompareTo
-Methode für die Car
-Objekte in der List
automatisch aufgerufen wird.
Public Sub ListCars()
' Create some new cars.
Dim cars As New List(Of Car) From
{
New Car With {.Name = "car1", .Color = "blue", .Speed = 20},
New Car With {.Name = "car2", .Color = "red", .Speed = 50},
New Car With {.Name = "car3", .Color = "green", .Speed = 10},
New Car With {.Name = "car4", .Color = "blue", .Speed = 50},
New Car With {.Name = "car5", .Color = "blue", .Speed = 30},
New Car With {.Name = "car6", .Color = "red", .Speed = 60},
New Car With {.Name = "car7", .Color = "green", .Speed = 50}
}
' Sort the cars by color alphabetically, and then by speed
' in descending order.
cars.Sort()
' View all of the cars.
For Each thisCar As Car In cars
Console.Write(thisCar.Color.PadRight(5) & " ")
Console.Write(thisCar.Speed.ToString & " ")
Console.Write(thisCar.Name)
Console.WriteLine()
Next
' Output:
' blue 50 car4
' blue 30 car5
' blue 20 car1
' green 50 car7
' green 10 car3
' red 60 car6
' red 50 car2
End Sub
Public Class Car
Implements IComparable(Of Car)
Public Property Name As String
Public Property Speed As Integer
Public Property Color As String
Public Function CompareTo(ByVal other As Car) As Integer _
Implements System.IComparable(Of Car).CompareTo
' A call to this method makes a single comparison that is
' used for sorting.
' Determine the relative order of the objects being compared.
' Sort by color alphabetically, and then by speed in
' descending order.
' Compare the colors.
Dim compare As Integer
compare = String.Compare(Me.Color, other.Color, True)
' If the colors are the same, compare the speeds.
If compare = 0 Then
compare = Me.Speed.CompareTo(other.Speed)
' Use descending order for speed.
compare = -compare
End If
Return compare
End Function
End Class
Definieren einer benutzerdefinierten Auflistung
Sie können eine Auflistung definieren, indem Sie die IEnumerable<T>- oder IEnumerable-Schnittstelle implementieren. Weitere Informationen finden Sie unter Enumerieren einer Auflistung.
Sie können zwar eine benutzerdefinierte Auflistung definieren, in der Regel ist es aber besser, die in .NET Framework enthaltenen Auflistungen zu verwenden. Diese werden unter Arten von Auflistungen weiter oben in diesem Thema beschrieben.
Im folgenden Beispiel wird die benutzerdefinierte Auflistungsklasse AllColors
definiert. Diese Klasse implementiert die IEnumerable-Schnittstelle, die die Implementierung der GetEnumerator-Methode erfordert.
Die GetEnumerator
-Methode gibt eine Instanz der ColorEnumerator
-Klasse zurück. ColorEnumerator
implementiert die IEnumerator-Schnittstelle, die die Implementierung der Current-Eigenschaft, der MoveNext-Methode und der Reset-Methode erfordert.
Public Sub ListColors()
Dim colors As New AllColors()
For Each theColor As Color In colors
Console.Write(theColor.Name & " ")
Next
Console.WriteLine()
' Output: red blue green
End Sub
' Collection class.
Public Class AllColors
Implements System.Collections.IEnumerable
Private _colors() As Color =
{
New Color With {.Name = "red"},
New Color With {.Name = "blue"},
New Color With {.Name = "green"}
}
Public Function GetEnumerator() As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return New ColorEnumerator(_colors)
' Instead of creating a custom enumerator, you could
' use the GetEnumerator of the array.
'Return _colors.GetEnumerator
End Function
' Custom enumerator.
Private Class ColorEnumerator
Implements System.Collections.IEnumerator
Private _colors() As Color
Private _position As Integer = -1
Public Sub New(ByVal colors() As Color)
_colors = colors
End Sub
Public ReadOnly Property Current() As Object _
Implements System.Collections.IEnumerator.Current
Get
Return _colors(_position)
End Get
End Property
Public Function MoveNext() As Boolean _
Implements System.Collections.IEnumerator.MoveNext
_position += 1
Return (_position < _colors.Length)
End Function
Public Sub Reset() Implements System.Collections.IEnumerator.Reset
_position = -1
End Sub
End Class
End Class
' Element class.
Public Class Color
Public Property Name As String
End Class
Iterators
Ein Iterator wird verwendet, um eine benutzerdefinierte Iteration durch eine Auflistung auszuführen. Ein Iterator kann eine Methode oder ein get
-Accessor sein. Ein Iterator verwendet eine Yield-Anweisung, um jedes Element der Auflistung separat zurückzugeben.
Sie rufen einen Iterator mithilfe einer For Each…Next-Anweisung auf. Jede Iteration der For Each
-Schleife ruft den Iterator auf. Wenn eine Yield
-Anweisung im Iterator erreicht ist, wird ein Ausdruck zurückgegeben, und die aktuelle Position im Code wird beibehalten. Wenn der Iterator das nächste Mal aufgerufen wird, wird die Ausführung von dieser Position neu gestartet.
Weitere Informationen finden Sie unter Iteratoren (Visual Basic).
Im folgenden Beispiel wird eine Iteratormethode verwendet. Die Iteratormethode verfügt über eine Yield
-Anweisung in einer For…Next-Schleife. In der ListEvenNumbers
-Methode erstellt jede Iteration des For Each
-Anweisungstexts einen Aufruf der Iteratormethode, der zur nächsten Yield
-Anweisung übergeht.
Public Sub ListEvenNumbers()
For Each number As Integer In EvenSequence(5, 18)
Console.Write(number & " ")
Next
Console.WriteLine()
' Output: 6 8 10 12 14 16 18
End Sub
Private Iterator Function EvenSequence(
ByVal firstNumber As Integer, ByVal lastNumber As Integer) _
As IEnumerable(Of Integer)
' Yield even numbers in the range.
For number = firstNumber To lastNumber
If number Mod 2 = 0 Then
Yield number
End If
Next
End Function
Siehe auch
- Auflistungsinitialisierer
- Programming Concepts (Visual Basic) (Programmierkonzepte (Visual Basic))
- Option Strict-Anweisung
- LINQ to Objects (Visual Basic)
- Parallel LINQ (PLINQ) (Paralleles LINQ (PLINQ))
- Sammlungen und Datenstrukturen
- Auswählen einer Auflistungsklasse
- Vergleiche und Sortierungen innerhalb von Auflistungen
- Verwenden von generischen Auflistungen