История вопроса:
Коллекции типа SortedList и SortedDictionary появились в .NET для удобного хранения пар ключ–значение в отсортированном по ключу виде. Они используются, когда важен быстрый доступ по ключу с одновременной поддержкой сортировки.
Проблема:
Частые ошибки связаны с неправильным выбором между этими коллекциями, использованием ключей неподходимого типа (без поддержки IComparable), а также неверным ожиданием поведения при вставке дублирующихся ключей.
Решение:
В Visual Basic используются классы SortedList(Of TKey, TValue) и SortedDictionary(Of TKey, TValue) для хранения отсортированных данных.
Пример кода:
Dim sortedList As New SortedList(Of String, Integer)() sortedList.Add("Alex", 27) sortedList.Add("Mike", 34) Dim age As Integer = sortedList("Alex") ' 27 Dim sortedDict As New SortedDictionary(Of Integer, String)() sortedDict.Add(3, "Three") sortedDict.Add(1, "One") For Each pair In sortedDict Console.WriteLine(pair.Key & ": " & pair.Value) Next
Ключевые особенности:
1. Можно ли изменять ключи у существующих элементов в SortedList или SortedDictionary?
Нет, изменить ключ у существующего элемента невозможно. Чтобы "изменить" ключ, нужно удалить исходную пару и добавить новую со скорректированным ключом.
2. Какое исключение возникает при попытке добавить уже существующий ключ?
Выбрасывается ArgumentException.
Dim sl As New SortedList(Of Integer, String)() sl.Add(1, "One") sl.Add(1, "Repeat") ' ArgumentException
3. Что произойдет, если в ключах использовать тип, не реализующий IComparable?
Компилятор позволит создать коллекцию, но при попытке добавить первый элемент будет выброшено InvalidOperationException.
Class MyObj End Class Dim sd As New SortedDictionary(Of MyObj, String)() sd.Add(New MyObj(), "test") ' Exception
Реализовали реестр пользователей по идентификатору (userId — ключ) и возрасту (значение) на SortedList. Ключом выбрали свой тип объекта (User), который не реализует IComparable. При добавлении пользователей возникают неожиданные исключения.
Плюсы:
Минусы:
Используют SortedDictionary(Of Integer, User), где ключ — простой тип Integer (userId), который поддерживает сравнение. Всё работает корректно, сортировка по идентификатору пользователей есть.
Плюсы:
Минусы: