Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DotNETFrameworkNotesForProfessionals.pdf
Скачиваний:
32
Добавлен:
20.05.2023
Размер:
1.82 Mб
Скачать

Chapter 4: Dictionaries

Section 4.1: Initializing a Dictionary with a Collection Initializer

// Translates to `dict.Add(1, "First")` etc. var dict = new Dictionary<int, string>()

{

{1, "First" },

{2, "Second" },

{3, "Third" }

};

//Translates to `dict[1] = "First"` etc.

//Works in C# 6.0.

var dict = new Dictionary<int, string>()

{

[1] = "First", [2] = "Second", [3] = "Third"

};

Section 4.2: Adding to a Dictionary

Dictionary<int, string> dict = new Dictionary<int, string>(); dict.Add(1, "First");

dict.Add(2, "Second");

// To safely add items (check to ensure item does not already exist - would throw) if(!dict.ContainsKey(3))

{

dict.Add(3, "Third");

}

Alternatively they can be added/set via the an indexer. (An indexer internally looks like a property, having a get and set, but takes a parameter of any type which is specified between the brackets) :

Dictionary<int, string> dict = new Dictionary<int, string>(); dict[1] = "First";

dict[2] = "Second"; dict[3] = "Third";

Unlike the Add method which throws an exception, if a key is already contained in the dictionary, the indexer just replaces the existing value.

For thread-safe dictionary use ConcurrentDictionary<TKey, TValue>:

var dict = new ConcurrentDictionary<int, string>(); dict.AddOrUpdate(1, "First", (oldKey, oldValue) => "First");

Section 4.3: Getting a value from a dictionary

Given this setup code:

var dict = new Dictionary<int, string>()

{

{ 1, "First" },

GoalKicker.com – .NET Framework Notes for Professionals

13

{2, "Second" },

{3, "Third" }

};

You may want to read the value for the entry with key 1. If key doesn't exist getting a value will throw KeyNotFoundException, so you may want to first check for that with ContainsKey:

if (dict.ContainsKey(1)) Console.WriteLine(dict[1]);

This has one disadvantage: you will search through your dictionary twice (once to check for existence and one to read the value). For a large dictionary this can impact performance. Fortunately both operations can be performed together:

string value;

if (dict.TryGetValue(1, out value)) Console.WriteLine(value);

Section 4.4: Make a Dictionary<string, T> with CaseInsensivitve keys

var MyDict = new Dictionary<string,T>(StringComparison.InvariantCultureIgnoreCase)

Section 4.5: IEnumerable to Dictionary (≥ .NET 3.5)

Create a Dictionary<TKey, TValue> from an IEnumerable<T>:

using System;

using System.Collections.Generic; using System.Linq;

public class Fruits

{

public int Id { get; set; } public string Name { get; set; }

}

var fruits = new[]

{

new Fruits { Id = 8 , Name = "Apple" }, new Fruits { Id = 3 , Name = "Banana" }, new Fruits { Id = 7 , Name = "Mango" },

};

// Dictionary<int, string> key value

var dictionary = fruits.ToDictionary(x => x.Id, x => x.Name);

Section 4.6: Enumerating a Dictionary

You can enumerate through a Dictionary in one of 3 ways:

Using KeyValue pairs

GoalKicker.com – .NET Framework Notes for Professionals

14

Dictionary<int, string> dict = new Dictionary<int, string>(); foreach(KeyValuePair<int, string> kvp in dict)

{

Console.WriteLine("Key : " + kvp.Key.ToString() + ", Value : " + kvp.Value);

}

Using Keys

Dictionary<int, string> dict = new Dictionary<int, string>(); foreach(int key in dict.Keys)

{

Console.WriteLine("Key : " + key.ToString() + ", Value : " + dict[key]);

}

Using Values

Dictionary<int, string> dict = new Dictionary<int, string>(); foreach(string s in dict.Values)

{

Console.WriteLine("Value : " + s);

}

Section 4.7: ConcurrentDictionary<TKey, TValue> (from .NET 4.0)

Represents a thread-safe collection of key/value pairs that can be accessed by multiple threads concurrently.

Creating an instance

Creating an instance works pretty much the same way as with Dictionary<TKey, TValue>, e.g.:

var dict = new ConcurrentDictionary<int, string>();

Adding or Updating

You might be surprised, that there is no Add method, but instead there is AddOrUpdate with 2 overloads:

(1)AddOrUpdate(TKey key, TValue, Func<TKey, TValue, TValue> addValue) - Adds a key/value pair if the key does not already exist, or updates a key/value pair by using the specified function if the key already exists.

(2)AddOrUpdate(TKey key, Func<TKey, TValue> addValue, Func<TKey, TValue, TValue> updateValueFactory)

- Uses the specified functions to add a key/value pair to the if the key does not already exist, or to update a key/value pair if the key already exists.

Adding or updating a value, no matter what was the value if it was already present for given key (1):

string addedValue = dict.AddOrUpdate(1, "First", (updateKey, valueOld) => "First");

Adding or updating a value, but now altering the value in update, based on the previous value (1):

string addedValue2 = dict.AddOrUpdate(1, "First", (updateKey, valueOld) => $"{valueOld} Updated");

GoalKicker.com – .NET Framework Notes for Professionals

15

Using the overload (2) we can also add new value using a factory:

string addedValue3 = dict.AddOrUpdate(1, (key) => key == 1 ? "First" : "Not First", (updateKey, valueOld) => $"{valueOld} Updated");

Getting value

Getting a value is the same as with the Dictionary<TKey,TValue>:

string value = null;

bool success = dict.TryGetValue(1, out value);

Getting or Adding a value

There are two mehod overloads, that will get or add a value in a thread-safe manner. Get value with key 2, or add value "Second" if the key is not present:

string theValue = dict.GetOrAdd(2, "Second");

Using a factory for adding a value, if value is not present:

string theValue2 = dict.GetOrAdd(2, (key) => key == 2 ? "Second" : "Not Second." );

Section 4.8: Dictionary to List

Creating a list of KeyValuePair:

Dictionary<int, int> dictionary = new Dictionary<int, int>(); List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>(); list.AddRange(dictionary);

Creating a list of keys:

Dictionary<int, int> dictionary = new Dictionary<int, int>(); List<int> list = new List<int>(); list.AddRange(dictionary.Keys);

Creating a list of values:

Dictionary<int, int> dictionary = new Dictionary<int, int>(); List<int> list = new List<int>(); list.AddRange(dictionary.Values);

Section 4.9: Removing from a Dictionary

Given this setup code:

var dict = new Dictionary<int, string>()

{

{1, "First" },

{2, "Second" },

{3, "Third" }

};

GoalKicker.com – .NET Framework Notes for Professionals

16