День 1189. #ЗаметкиНаПолях #AsyncTips
Неизменяемые словари
Задача: Нужна коллекция «ключ/значение», которая не слишком часто изменяется и допускает безопасные обращения из нескольких потоков. Например, в этой коллекции могут храниться данные состояния приложения в подстановочной (lookup) таблице; данные состояния редко изменяются, но они должны быть доступны для разных потоков.
Решение
Есть два типа неизменяемых словарей: ImmutableDictionary<TKey, TValue> и ImmutableSortedDictionary<TKey, TValue> из пространства имён System.Collections.Immutable, которые имеют очень похожие члены:
var d = ImmutableDictionary<int, string>.Empty;
d = d.Add(10, "Ten");
d = d.Add(21, "Twenty-One");
d = d.SetItem(10, "Diez");
// Выводит "10Diez" и "21Twenty-One" в непредсказуемом порядке.
foreach (var item in d)
Console.WriteLine(item.Key + item.Value);
string ten = d[10];
// ten == "Diez"
d = d.Remove(21);
Обратите внимание на использование SetItem. В изменяемом словаре можно было бы использовать конструкцию вида dictionary[key] = item, но неизменяемые словари должны возвращать обновлённый неизменяемый словарь, поэтому вместо этого они должны использовать метод SetItem.
Несортированные и отсортированные словари обладают сходным быстродействием - O(log N) для всех типов операций, но рекомендуется использовать неупорядоченные словари, если только не требуется, чтобы элементы были отсортированы (они могут работать в целом немного быстрее). Кроме того, несортированные словари могут использоваться с любыми типами ключей, тогда как отсортированные словари требуют, чтобы тип ключей был сравнимым (например, int или реализующий IComparable).
Словари являются полезным и общепринятым инструментом при работе с состоянием приложения. Они могут использоваться в любых сценариях, связанных с ключами/значениями или подстановками.
Неизменяемые словари, как и другие неизменяемые коллекции, поддерживают механизм для эффективного построения экземпляров, содержащих большое количество элементов. Например, если исходные данные загружаются в начале работы программы, вы сможете воспользоваться механизмом построителей для конструирования исходного неизменяемого словаря. С другой стороны, если данные строятся постепенно во время выполнения, вероятно, можно будет воспользоваться обычным методом Add неизменяемых словарей.
См. также:
- Неизменяемые стеки и очереди
- Неизменяемые списки
- Неизменяемые множества
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.