Рубрики: C#Программирование

<span style="color: #28A84C">C#</span> Dictionary<TKey, TValue> - класс

6 804 просмотров
<span style="color: #28A84C">C#</span> Dictionary<TKey, TValue> - класс
<span style="color: #28A84C">C#</span> Dictionary<TKey, TValue> - класс

Параметры типа
TKey
Тип ключей в словаре.
TValue
Тип значений в словаре.

Заметки

Универсальный класс Dictionary обеспечивает отображение множества ключей в множество значений. Каждый элемент, добавляемый в словарь, состоит из значения и связанного с ним ключа. Извлечение значения по его ключу происходит очень быстро, со скоростью, близкой к O(1), поскольку класс Dictionary реализован как хэш-таблица.

Пока объект используется в качестве ключа в словаре Dictionary, он не должен изменяться так, чтобы это отражалось на его хэш-коде. Каждый ключ в словаре Dictionary должен быть уникальным в соответствии с компаратором словаря, проверяющим на равенство. Ключ не может быть пустым (null), а значение может, если тип значения TValue является ссылочным типом.

Dictionary требует реализации проверки равенства, что позволит определять, совпадают ли ключи. Можно задать реализацию универсального интерфейса IEqualityComparer, используя конструктор, принимающий параметр comparer; если реализация не задана, используется универсальный компаратор по умолчанию, проверяющий на равенство (EqualityComparer.Default). Если тип TKey реализует универсальный интерфейс System.IEquatable, компаратор по умолчанию, проверяющий на равенство, использует эту реализацию.

Емкость коллекции Dictionary — это количество элементов, которое может вместить Dictionary. При добавлении элементов в коллекцию Dictionary ее емкость автоматически увеличивается нужным образом за счет перераспределения внутреннего массива.

Для очень больших объектов Dictionary, можно увеличить максимальную емкость до 2 миллиардов элементы на 64 разрядной системе, установив атрибут enabled элемента конфигурации gcAllowVeryLargeObjects на true среды выполнения.

Для оператора foreach языка C# (for each в C++, For Each в Visual Basic) необходимо указывать тип каждого элемента коллекции. Поскольку Dictionary представляет собой совокупность ключей и значений, здесь тип элемента — это не тип ключа и не тип значения. Эти элементы относятся к типу KeyValuePair, представляющему пару из типа ключа и типа значения. Например:

foreach( KeyValuePair kvp in myDictionary )
{
    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}

Оператор foreach является оболочкой перечислителя, допускающей только чтение из коллекции, но не запись в нее.

Пример

В следующем примере кода создается пустой объект Dictionary строк со строковыми ключами и используется метод Add для добавления нескольких элементов. Как видно из примера, метод Add выдает исключение ArgumentException при попытке добавить дубликат ключа.

В примере для извлечения значений используется свойство Item (индексатор в C#); при отсутствии запрашиваемого ключа выдается исключение KeyNotFoundException, причем значение, связанное с ключом, можно заменить.

В примере показано использование метода TryGetValue как более эффективный способ извлечения значений в программе, часто пытающейся использовать значения ключей, отсутствующие в словаре, а также демонстрируется применение метода ContainsKey для проверки существования ключа перед вызовом метода Add.

И в заключение в примере демонстрируется использование метода Remove.

using System;
using System.Collections.Generic;

public class Example
{
    public static void Main()
    {
        // Create a new dictionary of strings, with string keys.
        //
        Dictionary<string, string> openWith = 
            new Dictionary<string, string>();

        // Add some elements to the dictionary. There are no 
        // duplicate keys, but some of the values are duplicates.
        openWith.Add("txt", "notepad.exe");
        openWith.Add("bmp", "paint.exe");
        openWith.Add("dib", "paint.exe");
        openWith.Add("rtf", "wordpad.exe");

        // The Add method throws an exception if the new key is 
        // already in the dictionary.
        try
        {
            // Добавление элемента
            openWith.Add("txt", "winword.exe");
        }
        catch (ArgumentException)
        {
            Console.WriteLine("An element with Key = \"txt\" already exists.");
        }

        // The Item property is another name for the indexer, so you 
        // can omit its name when accessing elements. 
        Console.WriteLine("For key = \"rtf\", value = {0}.", 
            openWith["rtf"]);

        // The indexer can be used to change the value associated
        // with a key.
        openWith["rtf"] = "winword.exe";
        Console.WriteLine("For key = \"rtf\", value = {0}.", 
            openWith["rtf"]);

        // If a key does not exist, setting the indexer for that key
        // adds a new key/value pair.
        openWith["doc"] = "winword.exe";

        // The indexer throws an exception if the requested key is
        // not in the dictionary.
        try
        {
            Console.WriteLine("For key = \"tif\", value = {0}.", 
                openWith["tif"]);
        }
        catch (KeyNotFoundException)
        {
            Console.WriteLine("Key = \"tif\" is not found.");
        }

        // When a program often has to try keys that turn out not to
        // be in the dictionary, TryGetValue can be a more efficient 
        // way to retrieve values.
        string value = "";
        if (openWith.TryGetValue("tif", out value))
        {
            Console.WriteLine("For key = \"tif\", value = {0}.", value);
        }
        else
        {
            Console.WriteLine("Key = \"tif\" is not found.");
        }

        // ContainsKey can be used to test keys before inserting 
        // them.
        if (!openWith.ContainsKey("ht"))
        {
            openWith.Add("ht", "hypertrm.exe");
            Console.WriteLine("Value added for key = \"ht\": {0}", 
                openWith["ht"]);
        }

        // When you use foreach to enumerate dictionary elements,
        // the elements are retrieved as KeyValuePair objects.
        Console.WriteLine();
        foreach( KeyValuePair kvp in openWith )
        {
            Console.WriteLine("Key = {0}, Value = {1}", 
                kvp.Key, kvp.Value);
        }

        // To get the values alone, use the Values property.
        Dictionary.ValueCollection valueColl =
            openWith.Values;

        // The elements of the ValueCollection are strongly typed
        // with the type that was specified for dictionary values.
        Console.WriteLine();
        foreach( string s in valueColl )
        {
            Console.WriteLine("Value = {0}", s);
        }

        // To get the keys alone, use the Keys property.
        Dictionary.KeyCollection keyColl =
            openWith.Keys;

        // The elements of the KeyCollection are strongly typed
        // with the type that was specified for dictionary keys.
        Console.WriteLine();
        foreach( string s in keyColl )
        {
            Console.WriteLine("Key = {0}", s);
        }

        // Use the Remove method to remove a key/value pair.
        Console.WriteLine("\nRemove(\"doc\")");
        openWith.Remove("doc");

        if (!openWith.ContainsKey("doc"))
        {
            Console.WriteLine("Key \"doc\" is not found.");
        }
    }
}

/* This code example produces the following output:

An element with Key = "txt" already exists.
For key = "rtf", value = wordpad.exe.
For key = "rtf", value = winword.exe.
Key = "tif" is not found.
Key = "tif" is not found.
Value added for key = "ht": hypertrm.exe

Key = txt, Value = notepad.exe
Key = bmp, Value = paint.exe
Key = dib, Value = paint.exe
Key = rtf, Value = winword.exe
Key = doc, Value = winword.exe
Key = ht, Value = hypertrm.exe

Value = notepad.exe
Value = paint.exe
Value = paint.exe
Value = winword.exe
Value = winword.exe
Value = hypertrm.exe

Key = txt
Key = bmp
Key = dib
Key = rtf
Key = doc
Key = ht

Remove("doc")
Key "doc" is not found.
 */

Сведения о версии

.NET Framework Поддерживается в версиях: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0 .NET Framework (клиентский профиль) Поддерживается в версиях: 4, 3.5 с пакетом обновления 1 (SP1) Переносимая библиотека классов Поддерживается в версии: Переносимая библиотека классов Приложения .NET для Магазина Windows Поддерживается в версии: Windows 8 Приложения .NET для Windows Phone Поддерживается в версиях: Windows Phone 8, Silverlight 8.1


Более полная информация о Dictionary тут

Комментарии 1

Загрузка комментариев…