Historia pytania:
W VB.NET standardowym rozwiązaniem do asocjacyjnego przechowywania danych (klucz-wartość) stała się klasa Dictionary(Of TKey, TValue). W klasycznym VB6 częściej używano obiektu Scripting.Dictionary lub kolekcji Collection, a także typu Hashtable, który pojawił się w wczesnych wersjach .NET. Te struktury pozwalają na szybkie znajdowanie wartości na podstawie klucza i zastąpiły mniej typowo bezpieczne podejścia.
Problem
Niekonwencjonalna różnica między Dictionary a Hashtable — i możliwe błędy przy wyszukiwaniu z brakującym kluczem. Na przykład próba dostępu do klucza, którego nie ma, kończy się błędem w niektórych przypadkach i nie w innych. Różnice w typowej bezpieczeństwie i wydajności prowadzą do błędnego wyboru kolekcji.
Rozwiązanie
W nowoczesnych wersjach VB.NET najlepszą praktyką jest użycie Dictionary(Of TKey, TValue), gdzie TKey i TValue są ściśle typowane:
Dim dict As New Dictionary(Of String, Integer)() dict.Add("apple", 1) dict.Add("banana", 2) If dict.ContainsKey("banana") Then Console.WriteLine(dict("banana")) ' Wyświetli 2 End If ' Bezpieczne pobranie wartości Dim value As Integer If dict.TryGetValue("cherry", value) Then Console.WriteLine(value) Else Console.WriteLine("Brak takiego klucza!") End If
Kluczowe cechy:
Czy można użyć Object jako klucza bez ograniczeń w Dictionary?
Formalnie tak, ale wymagana jest prawidłowa implementacja metod GetHashCode i Equals w klasie, która służy jako klucz. W przeciwnym razie możliwe są kolizje i błędy wyszukiwania.
Co się stanie, jeśli odwołasz się do nieistniejącego klucza przez dict("foo")?
Zostanie rzucony wyjątek KeyNotFoundException. Bez wstępnej weryfikacji klucza (przez ContainsKey lub TryGetValue) program zakończy działanie.
Czy Dictionary i Hashtable wspierają tę samą kolejność elementów?
Nie. Obie klasy nie gwarantują kolejności dodawania elementów. Aby zachować porządek, użyj SortedDictionary, OrderedDictionary lub innych struktur.
Programista wybrał Hashtable do przechowywania dużych ilości danych użytkowników. Występowały trudno uchwytne błędy — ten sam klucz nie zawsze się zgadzał, w testach pojawiały się błędy Object.ReferenceEquals, wiązano niestabilny typ klucza.
Plusy:
Minusy:
Przeszliśmy na Dictionary(Of Guid, User): ścisła typizacja, wsparcie dla TryGetValue, wyeliminowano błędy kolizji. Wydajność wzrosła.
Plusy:
Minusy: