.NET_Framework

.NET Core.NET Framework Acronym Glossary.NET Framework ADO.NET.NET Framework CLR.NET Framework Code Contracts.NET Framework Collections.NET Framework Custom Types.NET Framework DateTime parsing.NET Framework Dependency Injection.NET Framework Dictionaries.NET Framework Encryption / Cryptography.NET Framework Exceptions.NET Framework Expression Trees.NET Framework File Input/Output.NET Framework ForEach.NET Framework Garbage Collection.NET Framework Globalization in ASP.NET MVC using Smart internationalization for ASP.NET.NET Framework HTTP clients.NET Framework HTTP servers.NET Framework Introduction.NET Framework JIT compiler.NET Framework JSON Serialization.NET Framework LINQ.NET Framework Managed Extensibility.NET Framework Memory management.NET Framework Networking.NET Framework NuGet packaging system.NET Framework Platform Invoke.NET Framework Process and Thread affinity setting.NET Framework Reading and writing Zip files.NET Framework ReadOnlyCollections.NET Framework Reflection.NET Framework Regular Expressions (System.Text.RegularExpressions).NET Framework Serial Ports.NET Framework Settings.NET Framework SpeechRecognitionEngine class to recognize speech.NET Framework Stack and Heap.NET Framework Strings.NET Framework Synchronization Contexts.NET Framework System.Diagnostics.NET Framework System.IO.NET Framework System.IO.File class.NET Framework System.Net.Mail.NET Framework System.Reflection.Emit namespace.NET Framework System.Runtime.Caching.MemoryCache (ObjectCache).NET Framework Task Parallel Library (TPL).NET Framework Task Parallel Library (TPL) API Overviews.NET Framework Threading.NET Framework TPL Dataflow.NET Framework Unit testing.NET Framework Upload file and POST data to webserver.NET Framework Using ProgressT and IProgressT.NET Framework VB Forms.NET Framework Work with SHA1 in C Sharp.NET Framework Write to and read from StdErr stream.NET Framework XmlSerializerJSON in .NET with Newtonsoft.JsonParallel processing using .NET framework



.NET Framework Dictionaries

From WikiOD

Initializing a Dictionary with a Collection Initializer[edit | edit source]

// 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"
};

Adding to a Dictionary[edit | edit source]

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");

Getting a value from a dictionary[edit | edit source]

Given this setup code:

var dict = new Dictionary<int, string>()
{
    { 1, "First" },
    { 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);

Make a Dictionary with Case-Insensivitve keys.[edit | edit source]

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

Enumerating a Dictionary[edit | edit source]

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

Using KeyValue pairs

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);
}

ConcurrentDictionary (from .NET 4.0)[edit | edit source]

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

Creating an instance[edit | edit source]

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[edit | edit source]

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");

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[edit | edit source]

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[edit | edit source]

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." );

IEnumerable to Dictionary (≥ .NET 3.5)[edit | edit source]

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);

Removing from a Dictionary[edit | edit source]

Given this setup code:

var dict = new Dictionary<int, string>()
{
    { 1, "First" },
    { 2, "Second" },
    { 3, "Third" }
};

Use the Remove method to remove a key and its associated value.

bool wasRemoved = dict.Remove(2);

Executing this code removes the key 2 and it's value from the dictionary. Remove returns a boolean value indicating whether the specified key was found and removed from the dictionary. If the key does not exist in the dictionary, nothing is removed from the dictionary, and false is returned (no exception is thrown).

It's incorrect to try and remove a key by setting the value for the key to null.

dict[2] = null; // WRONG WAY TO REMOVE!

This will not remove the key. It will just replace the previous value with a value of null.

To remove all keys and values from a dictionary, use the Clear method.

dict.Clear();

After executing Clear the dictionary's Count will be 0, but the internal capacity remains unchanged.

ContainsKey(TKey)[edit | edit source]

To check if a Dictionary has an specifique key, you can call the method ContainsKey(TKey) and provide the key of TKey type. The method returns a bool value when the key exists on the dictionary. For sample:

var dictionary = new Dictionary<string, Customer>()
{
   {"F1", new Customer() { FirstName = "Felipe", ... } },
   {"C2", new Customer() { FirstName = "Carl", ... } },
   {"J7", new Customer() { FirstName = "John", ... } },
   {"M5", new Customer() { FirstName = "Mary", ... } },
};

And check if a C2 exists on the Dictionary:

if (dictionary.ContainsKey("C2")) 
{
   // exists
}

The ContainsKey method is available on the generic version Dictionary<TKey, TValue>.

Dictionary to List[edit | edit source]

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);

ConcurrentDictionary augmented with Lazy'1 reduces duplicated computation[edit | edit source]

Problem[edit | edit source]

ConcurrentDictionary shines when it comes to instantly returning of existing keys from cache, mostly lock free, and contending on a granular level. But what if the object creation is really expensive, outweighing the cost of context switching, and some cache misses occur?

If the same key is requested from multiple threads, one of the objects resulting from colliding operations will be eventually added to the collection, and the others will be thrown away, wasting the CPU resource to create the object and memory resource to store the object temporarily. Other resources could be wasted as well. This is really bad.

Solution[edit | edit source]

We can combine ConcurrentDictionary<TKey, TValue> with Lazy<TValue>. The idea is that ConcurrentDictionary GetOrAdd method can only return the value which was actually added to the collection. The loosing Lazy objects could be wasted in this case too, but that's not much problem, as the Lazy object itself is relatively unexpensive. The Value property of the losing Lazy is never requested, because we are smart to only request the Value property of the one actually added to the collection - the one returned from the GetOrAdd method:

public static class ConcurrentDictionaryExtensions
{
    public static TValue GetOrCreateLazy<TKey, TValue>(
        this ConcurrentDictionary<TKey, Lazy<TValue>> d,
        TKey key,
        Func<TKey, TValue> factory)
    {
        return
            d.GetOrAdd(
                key,
                key1 =>
                    new Lazy<TValue>(() => factory(key1),
                    LazyThreadSafetyMode.ExecutionAndPublication)).Value;
    }
}

Caching of XmlSerializer objects can be particularly expensive, and there is a lot of contention at the application startup too. And there is more to this: if those are custom serializers, there will be a memory leak too for the rest of the process lifecycle. The only benefit of the ConcurrentDictionary in this case is that for the rest of the process lifecycle there will be no locks, but application startup and memory usage would be inacceptable. This is a job for our ConcurrentDictionary, augmented with Lazy:

private ConcurrentDictionary<Type, Lazy<XmlSerializer>> _serializers =
    new ConcurrentDictionary<Type, Lazy<XmlSerializer>>();

public XmlSerializer GetSerialier(Type t)
{
    return _serializers.GetOrCreateLazy(t, BuildSerializer);
}

private XmlSerializer BuildSerializer(Type t)
{
    throw new NotImplementedException("and this is a homework");
}

Credit:Stack_Overflow_Documentation