W Visual Basic kolekcje (tablice, listy, słowniki itp.) wspierają dostęp zarówno przez indeks, jak i przy użyciu iteratorów (na przykład, przez For Each). W historii języka pierwszy element standardowej tablicy miał indeks 0, jednak ze względu na zgodność z VB6 zdarzają się tablice zadeklarowane z indeksem 1. To wpływa na sposób dostępu i potencjalne błędy. Również kolekcje typu Dictionary wspierają wyszukiwanie według klucza, ale próba uzyskania dostępu do nieistniejącego elementu może prowadzić do wyrzucenia wyjątku.
Problem z dostępem polega na różnicach w składni, cechach działania indeksatorów, a także na tym, że nie wszystkie kolekcje zwracają Null lub Nothing, gdy element nie istnieje — często prowadzi to do wyrzucenia wyjątku. Podczas korzystania z pętli ważne jest przestrzeganie zakresu indeksów oraz wcześniejsze sprawdzenie rozmiaru kolekcji.
Rozwiązanie dla bezpiecznego dostępu obejmuje sprawdzenie długości, korzystanie z metod ContainsKey lub TryGetValue dla słowników, a także enumerację elementów za pomocą For Each, dlatego odwołanie się odbywa do istniejących wartości bez ryzyka wystąpienia przekroczenia granic.
Przykład kodu:
Dim list As New List(Of String)({"a", "b", "c"}) For i As Integer = 0 To list.Count - 1 Console.WriteLine(list(i)) Next ' Iteracja przez iterator: For Each item In list Console.WriteLine(item) Next ' Bezpieczny dostęp w Dictionary Dim dict As New Dictionary(Of Integer, String) dict(1) = "one" If dict.ContainsKey(2) Then Console.WriteLine(dict(2)) End If
Kluczowe cechy:
Czy można uzyskać dostęp do Dictionary przez indeks, jak do tablicy?
Nie, Dictionary nie wspiera dostępu przez indeks numeryczny, tylko przez klucz. Aby iterować po kluczach w kolejności, należy uzyskać kolekcję kluczy:
For Each key In dict.Keys Console.WriteLine(dict(key)) Next
Co się stanie, jeśli spróbujesz uzyskać dostęp do List przez indeks poza zakresem?
Zostanie wyrzucony wyjątek ArgumentOutOfRangeException. Zawsze sprawdzaj, czy indeks jest mniejszy od Count i większy lub równy 0.
Czy For Each może pominąć elementy, jeśli kolekcja zmienia się podczas iteracji?
Tak, zmiana kolekcji wewnątrz For Each prowadzi do wyjątku InvalidOperationException. Unikaj dodawania lub usuwania elementów podczas iteracji:
' Przykład błędu For Each x In list list.Remove(x) ' Wyrzuci wyjątek Next
Nowicjusze dodawali elementy do List wewnątrz pętli For Each, w wyniku czego aplikacja padała z błędem InvalidOperationException.
Zalety:
Przed rozpoczęciem iteracji warto zapisać listę elementów w osobnej tablicy, pracować na kopii lub używać For z indeksem. Uzyskanie dostępu do Dictionary tylko po sprawdzeniu obecności klucza.
Zalety: