Еще один распространенный тип коллекции представляют словари. Словарь хранит объекты, которые представляют пару ключ-значение. Класс словаря Dictionary<K, V> типизируется двумя типами: параметр K представляет тип ключей, а параметр V предоставляет тип значений.
Класс Dictionary предоставляет ряд конструкторов для создания словаря. Например, мы можем создать пустой словарь:
Dictionary<int, string> people = new Dictionary<int, string>();
Здесь словарь people
в качестве ключей принимает значения типа int, а в качестве значений - строки.
При определении словаря его сразу же можно инициализировать значениями:
var people = new Dictionary<int, string>() { { 5, "Tom"}, { 3, "Sam"}, { 11, "Bob"} };
При инициализации применяется инициализитор - в фигурных скобках после вызова конструктора объекту передаются начальные данные. В случае со словаем мы можем передать в инициализаторе набор элементов, где каждый элемент заключается в фигурные скобки, например:
{ 5, "Tom"}
Каждый элемент представляет два значения: первое значение представляет ключ, а второе значение - собственно значение элемента.
Поскольку при объявлении словаря people для ключей указан тип int
, а для значений - тип string
, то в элементе словаря
сначала указывается число int, а затем строка. То есть в случае выше элемент имеет ключ 5, а значение - "Tom". Затем по ключу элемента мы сможем получить его значение.
Также мы можем применять другой способ инициализации:
var people = new Dictionary<int, string>() { [5] = "Tom", [6] = "Sam", [7] = "Bob" };
При таком способе инициализации в квадратных скобках указывается ключ и ему присваивается значение элемента. Но в целом этот способ инициализации будет равноценен предыдущему.
Стоит отметить, что каждый элемент в словаре представляет структуру KeyValuePair<TKey, TValue>, где параметр TKey представляет тип ключа,
а параметр TValue - тип значений элементов. Эта структура предоставляет свойства Key
и Value
,
с помощью которых можно получить соответственно ключ и значение элемента в словаре. И одна из версий конструктора Dictionary позволяет инициализировать
словарь коллекцией объектов KeyValuePair:
var mike = new KeyValuePair<int, string>(56, "Mike"); var employees = new List<KeyValuePair<int, string>>() { mike}; var people = new Dictionary<int, string>(employees);
Конструктор типа KeyValuePair
принимает два параметра - ключ элемента и его значения. То есть в данном случае создается один такой
элемент - mike
с ключом 56 и значением "Mike". И этот элемент добавляется в список employees, которым затем инициализируется словарь.
Можно совместить оба способа инициализации:
var mike = new KeyValuePair<int, string>(56, "Mike"); var employees = new List<KeyValuePair<int, string>>() { mike }; var people = new Dictionary<int, string>(employees) { [5] = "Tom", [6] = "Sam", [7] = "Bob", };
В данном случае в словаре people будет четыре элемента.
Для перебора словаря можно применять цикл foreach:
var people = new Dictionary<int, string>() { [5] = "Tom", [6] = "Sam", [7] = "Bob" }; foreach(var person in people) { Console.WriteLine($"key: {person.Key} value: {person.Value}"); }
При переборе каждый элемент будет помещаться в переменную, которая представляет тип KeyValuePair, соответственно с помощью свойств Key и Value мы сможем получить ключ и значение элемента. Консольный вывод программы:
key: 5 value: Tom key: 6 value: Sam key: 7 value: Bob
Для обращения к элементам из словаря применяется их ключ, который передается в квадратных скобках:
словарь[ключ]
Таким образом мы можем получить и изменить элементы словаря
var people = new Dictionary<int, string>() { [5] = "Tom", [6] = "Sam", [7] = "Bob", }; // получаем элемент по ключу 6 string sam = people[6]; // Sam Console.WriteLine(sam); // Sam // переустанавливаем значение по ключу 6 people[6] = "Mike"; Console.WriteLine(people[6]); // Mike // добавляем новый элемент по ключу 22 people[22] = "Eugene"; Console.WriteLine(people[22]); // Eugene
Более того, таким образом мы можем также добавить новый элемент в словарь. При установке значения по ключу, если элемент с таким ключом уже есть в словаре, то значение переустанавливается. Если же элемента с подобным ключом нет в словаре, то элемент добавляется.:
Среди методов класса Dictionary можно выделить следующие:
void Add(K key, V value): добавляет новый элемент в словарь
void Clear(): очищает словарь
bool ContainsKey(K key): проверяет наличие элемента с определенным ключом и возвращает true при его наличии в словаре
bool ContainsValue(V value): проверяет наличие элемента с определенным значением и возвращает true при его наличии в словаре
bool Remove(K key): удаляет по ключу элемент из словаря
Другая версия этого метода позволяет получить удленный элемент в выходной параметр: bool Remove(K key, out V value)
bool TryGetValue(K key, out V value): получает из словаря элемент по ключу key. При успешном получении передает значение элемента в выходной параметр value и возвращает true
bool TryAdd(K key, V value): добавляет в словарь элемент с ключом key и значением value. При успешном добавлении возвращает true
Из свойств следует отметить свойство Count, которое возвращает количество элементов в словаре.
Применение методов:
// условная телефонная книга var phoneBook = new Dictionary<string, string>(); // добавляем элемент: ключ - номер телефона, значение - имя абонента phoneBook.Add("+123456", "Tom"); // альтернативное добавление // phoneBook["+123456"] = "Tom"; // Проверка наличия var phoneExists1 = phoneBook.ContainsKey("+123456"); // true Console.WriteLine($"+123456: {phoneExists1}"); var phoneExists2 = phoneBook.ContainsKey("+567456"); // false Console.WriteLine($"+567456: {phoneExists2}"); var abonentExists1 = phoneBook.ContainsValue("Tom"); // true Console.WriteLine($"Tom: {abonentExists1}"); var abonentExists2 = phoneBook.ContainsValue("Bob"); // false Console.WriteLine($"Bob: {abonentExists2}"); // удаление элемента phoneBook.Remove("+123456"); // проверяем количество элементов после удаления Console.WriteLine($"Count: {phoneBook.Count}"); // Count: 0