- •А.А. Волосевич
- •2. Базовые технологии платформы .Net 5
- •2. Базовые технологии платформы .Net 4
- •2. Базовые технологии платформы .Net
- •2.1. Работа с Числами
- •2.2. Дата и время
- •2.3. Работа со строками и текстом
- •2.4. Преобразование информации
- •2.5. Отношения равенства и порядка
- •Сравнение для выяснения равенства
- •Сравнение для выяснения порядка
- •2.6. Жизненный цикл объектов
- •Алгоритм «сборки мусора»
- •Финализаторы и интерфейс iDisposable
- •2.7. Перечислители и итераторы
- •2.8. Интерфейсы стандартных коллекций
- •2.9. Массивы и класс system.Array
- •2.10. Типы для работы с коллекциями-списками
- •2.11. Типы для работы с коллекциями-множествами
- •2.12. Типы для работы с коллекциями-словарями
- •2.13. Типы для создания пользовательских коллекций
- •2.14. Технология linq to objects
- •1. Оператор условия Where().
- •2. Операторы проекций.
- •3. Операторы упорядочивания.
- •4. Оператор группировки GroupBy().
- •5. Операторы соединения.
- •6. Операторы работы с множествами.
- •7. Операторы агрегирования.
- •8. Операторы генерирования.
- •9. Операторы кванторов и сравнения.
- •10. Операторы разбиения.
- •11. Операторы элемента.
- •12. Операторы преобразования.
- •2.15. Работа с объектами файЛовой системы
- •2.16. Ввод и вывод информации
- •Потоки данных и декораторы потоков
- •2. Классы для работы с потоками, связанными с хранилищами.
- •3. Декораторы потоков.
- •4. Адаптеры потоков.
- •Адаптеры потоков
- •2.17. Основы xml
- •2.18. Технология linq to xml
- •Создание, сохранение, загрузка xml
- •Запросы, модификация и трансформация xml
- •Пространства имен xml
- •2.19. ДОполнительные возможности обработки xml
- •2.20. Сериализация
- •Сериализация времени выполнения
- •Сериализация контрактов данных
- •2.21. Состав и взаимодействие сборок
- •2.22. Метаданные и получение информации о типах
- •2.23. Позднее связывание и кодогенерация
- •2.24. Динамические типы
- •2.25. Атрибуты
- •2.26. Файлы конфигуРации
- •2.27. Основы мНогопоточноГо программирования
- •2.28. Синхронизация потоков
- •2.29. Библиотека параллельных расширений
- •Параллелизм на уровне задач
- •Параллелизм при императивной обработке данных
- •Параллелизм при декларативной обработке данных
- •Обработка исключений и отмена выполнения задач
- •Коллекции, поддерживающие параллелизм
- •2.30. Асинхронный вызов методов
- •2.31. Процессы и домены
- •2.32. Безопасность
- •Разрешения на доступ
- •Изолированные хранилища
- •Криптография
- •2.33. Диагностика
2.11. Типы для работы с коллекциями-множествами
В библиотеке базовых классов платформы .NET имеются два класса для представления множеств (то есть коллекций, которые не содержат повторяющихся элементов) ‑ HashSet<T> и SortedSet<T>. Оба класса реализуют интерфейс ISet<T>.
Класс HashSet<T> описывает множество, в котором вхождение элемента проверяется на основе хэш-кода. Конструкторы класса HashSet<T> позволяют создать множество на основе коллекции, а также указать объект, реализующий интерфейс IEqualityComparer<T> для проверки равенства элементов множества. Кроме реализации интерфейса ISet<T>, класс HashSet<T> содержит экземплярный метод RemoveWhere() для удаления элементов, удовлетворяющих заданному предикату. Статический метод CreateSetComparer() возвращает экземпляр класса, реализующего IEqualityComparer<HashSet<T>>. Следующий пример показывает использование HashSet<T>:
var setOne = new HashSet<char>("the quick brown fox");
var setTwo = new HashSet<char>("jumps over the lazy dog");
setOne.IntersectWith(setTwo); // the uro
Console.WriteLine(setOne.Contains('t')); // True
Console.WriteLine(setOne.Contains('j')); // False
setTwo.RemoveWhere(c => c < 'k');
Класс SortedSet<T> ‑ это множество, поддерживающее набор элементов в отсортированном порядке. Конструкторы класса SortedSet<T> позволяют создать множество на основе коллекции, а также указать объект, реализующий интерфейс IComparer<T> для проверки порядка элементов множества. Набор методов SortedSet<T> схож с набором методов класса HashSet<T>. Экземплярный метод Reverse() изменяет порядок элементов на противоположный, а метод GetViewBetween() возвращает фрагмент («окно») исходного множества между двумя элементами.
var setOne = new SortedSet<char>("А роза упала на лапу Азора");
// setOne = Аазлнопру
var setTwo = setOne.GetViewBetween('б', 'р');
setTwo.Add('в'); // успешно, setTwo = взлнопр
setTwo.Add('ф'); // исключение, так как символ не принадлежит окну
2.12. Типы для работы с коллекциями-словарями
Под термином словарь будем понимать коллекцию, которая хранит пары «ключ-значение» с возможностью доступа к элементам по ключу. Базовая библиотека платформы .NET предлагает набор коллекций-словарей, как классических, так и с различными дополнительными возможностями.
Универсальный класс Dictionary<TKey, TValue> – это классический словарь с возможностью указать тип для ключа и тип для значения1. Данный класс является одним из наиболее часто используемых классов-коллекций (наряду с классом List<T>). Класс Dictionary<TKey, TValue> реализует обе версии интерфейса IDictionary (как обычную, так и универсальную). Пример использования класса приведён ниже.
// конструируем словарь и помещаем в него один элемент
var d = new Dictionary<string, int> {{"One", 1}};
d["Two"] = 2; // помещаем ещё один элемент, используя индексатор
d["Two"] = 22; // обновляем существующий элемент
d["Three"] = 3;
Console.WriteLine(d["Two"]); // печатает "22"
Console.WriteLine(d.ContainsKey("One")); // True (быстрая операция)
Console.WriteLine(d.ContainsValue(3)); // True (медленная операция)
int val;
if (!d.TryGetValue("onE", out val))
Console.WriteLine("No val");
// Различные способы перечисления словаря
foreach (var kv in d)
{
Console.WriteLine(kv.Key + "; " + kv.Value);
}
foreach (string s in d.Keys) { Console.WriteLine(s); }
foreach (int i in d.Values) { Console.WriteLine(i); }
Словарь может работать с элементами любого типа, так как у любого объекта можно получить хэш-код и сравнить объекты на равенство, используя методы GetHashCode() и Equals(). Пользовательские типы могут переопределять данные методы, предоставляя их эффективную реализацию. Кроме этого, конструктору словаря можно передать объект, реализующий интерфейс IEqualityComparer<TKey>. Типичным примером использования такого подхода является конструирование словаря, обеспечивающего сравнение строк-ключей независимо от их регистра:
var d = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
Класс OrderedDictionary – это слаботипизированный класс, запоминающий порядок добавления элементов в словарь. В некотором смысле, данный класс является комбинацией классов Hashtable и ArrayList. Для доступа к элементам в OrderedDictionary можно использовать как ключ, так и целочисленный индекс.
Класс ListDictionary использует для хранения элементов словаря не хэш-таблицу, а односвязный список. Это делает данный класс неэффективным при работе с большими наборами данных. ListDictionary рекомендуется использовать, если количество хранимых элементов не превышает десяти. Класс HybridDictionary – это форма словаря, использующая список для хранения при малом количестве элементов, и переключающаяся на применение хэш-функции, когда количество элементов превышает определённый порог. Оба класса ListDictionary и HybridDictionary являются слаботипизированными и находятся в пространстве имен System.Collections.Specialized.
Платформа .NET предоставляет три класса-словаря, организованных так, что их элементы всегда отсортированы по ключу:
-
SortedDictionary<TKey,TValue>;
-
SortedList;
-
SortedList<TKey,TValue> (универсальная версия SortedList).
Данные классы используют разные внутренние структуры для хранения элементов словаря. Класс SortedDictionary<TKey,TValue> быстрее классов SortedList и SortedList<TKey,TValue> при выполнении вставки элементов. Но классы SortedList и SortedList<TKey,TValue> могут предоставить возможность, которой нет у SortedDictionary<TKey,TValue> ‑ доступ к элементу не только по ключу, а и с использованием целочисленного индекса.