История вопроса:
В VB.NET для ассоциативного хранения данных (ключ-значение) видным стандартом стал класс Dictionary(Of TKey, TValue). В классическом VB6 чаще использовался объект Scripting.Dictionary или коллекция Collection, а также тип Hashtable, появившийся в ранних версиях .NET. Эти структуры позволяют быстро находить значения по ключу и заменили менее типобезопасные подходы.
Проблема
Неочевидная разница между Dictionary и Hashtable — и возможные ошибки при поиске по отсутствующему ключу. Например, попытка обращения к ключу, которого нет, выдаёт ошибку в одних случаях и не в других. Также различия в типобезопасности и производительности приводят к неверному выбору коллекции.
Решение
В современных версиях VB.NET Лучшей практикой считается использование Dictionary(Of TKey, TValue), где TKey и TValue — строго типизированы:
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")) ' Выведет 2 End If ' Безопасное получение значения Dim value As Integer If dict.TryGetValue("cherry", value) Then Console.WriteLine(value) Else Console.WriteLine("Нет такого ключа!") End If
Ключевые особенности:
Можно ли использовать Object в качестве ключа без ограничений в Dictionary?
Формально да, но требуется корректная реализация методов GetHashCode и Equals у класса, который служит ключом. Иначе возможны коллизии и ошибки поиска.
Что произойдет, если обратиться к несуществующему ключу через dict("foo")?
Будет выброшено исключение KeyNotFoundException. Без предварительной проверки ключа (через ContainsKey или TryGetValue) программа упадёт.
Поддерживают ли Dictionary и Hashtable одинаковую упорядоченность элементов?
Нет. Оба класса не гарантируют порядок добавления элементов. Для сохранения порядка используйте SortedDictionary, OrderedDictionary или другие структуры.
Разработчик выбрал Hashtable для хранения больших объёмов пользовательских данных. Возникали трудноуловимые ошибки — один и тот же ключ не всегда совпадал, в тестах всплывали Object.ReferenceEquals ошибки, привязывался нестабильный тип ключа.
Плюсы:
Минусы:
Перешли на Dictionary(Of Guid, User): строгая типизация, саппорт TryGetValue, исключили ошибки коллизий. Производительность выросла.
Плюсы:
Минусы: