31

I have a ConcurrentDictionary object that I would like to set to a Dictionary object.

Casting between them is not allowed. So how do I do it?

JYelton
  • 34,250
  • 25
  • 123
  • 184
umbersar
  • 1,647
  • 2
  • 20
  • 33

4 Answers4

45

The ConcurrentDictionary<K,V> class implements the IDictionary<K,V> interface, which should be enough for most requirements. But if you really need a concrete Dictionary<K,V>...

var newDictionary = yourConcurrentDictionary.ToDictionary(kvp => kvp.Key,
                                                          kvp => kvp.Value,
                                                          yourConcurrentDictionary.Comparer);

// or...
// substitute your actual key and value types in place of TKey and TValue
var newDictionary = new Dictionary<TKey, TValue>(yourConcurrentDictionary, yourConcurrentDictionary.Comparer);
ANeves
  • 5,951
  • 3
  • 36
  • 63
LukeH
  • 252,910
  • 55
  • 358
  • 405
  • 6
    Note that the dictionary to copy might use a non-default `IEqualityComparer` that won't be preserved that way! Better: `var newDict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value, dict.Comparer);` – Roman Reiner Dec 01 '14 at 16:12
  • 2
    Note that [MSDN](https://msdn.microsoft.com/en-us/library/system.collections.concurrent(v=vs.110).aspx) says this may not be thread safe. How would you make it thread safe? – JonDrnek May 05 '15 at 12:48
  • Don't worry, it actually is thread-safe, by virtue of the ConcurrentDictionary. You will get a snapshot of the ConcurrentDictionary's content. The dictionary you get from that won't be thread-safe itself later on though. – Falanwe Mar 10 '16 at 11:08
  • 5
    @Falanwe: It is safe, but you don't get a snapshot of the contents: _"The enumerator returned from the dictionary is safe to use concurrently with reads and writes to the dictionary, however it does not represent a moment-in-time snapshot of the dictionary. The contents exposed through the enumerator may contain modifications made to the dictionary after GetEnumerator was called."_ (From the _Remarks_ section of https://msdn.microsoft.com/en-us/library/dd287131.aspx) – LukeH Mar 10 '16 at 12:50
19

Why do you need to convert it to a Dictionary? ConcurrentDictionary<K, V> implements the IDictionary<K, V> interface, is that not enough?

If you really need a Dictionary<K, V>, you can copy it using LINQ:

var myDictionary = myConcurrentDictionary.ToDictionary(entry => entry.Key,
                                                       entry => entry.Value);

Note that this makes a copy. You cannot just assign a ConcurrentDictionary to a Dictionary, since ConcurrentDictionary is not a subtype of Dictionary. That's the whole point of interfaces like IDictionary: You can abstract away the desired interface ("some kind of dictionary") from the concrete implementation (concurrent/non-concurrent hashmap).

Heinzi
  • 159,022
  • 53
  • 345
  • 499
12

I think i have found a way to do it.

ConcurrentDictionary<int, int> concDict= new ConcurrentDictionary<int, int>( );
Dictionary dict= new Dictionary<int, int>( concDict);
umbersar
  • 1,647
  • 2
  • 20
  • 33
2
ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();
Dictionary<int,string> d = cd.ToDictionary(pair => pair.Key, pair => pair.Value);
Andrey
  • 19,434
  • 24
  • 100
  • 171