Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to cast .Net ConcurrentDictionary<K,V> to IReadOnlyDictionary<K,V> interface?

Tags:

c#

interface

I must be missing something and feel like I have to go back to the very basics but according to the reference sources for ConcurrentDictionary in .Net 4.5 it implements the IReadOnlyDictionary interface (albeit some members explicitely), but for some reason I cannot cast an instance to that interface - why is that?

IDictionary<int, string> a = new ConcurrentDictionary<int, string>(); // works
IReadOnlyDictionary<int, string> b = new ConcurrentDictionary<int, string>(); // does not work

.. why is that?

To make this a bit more clear:

enter image description here

like image 346
Jörg Battermann Avatar asked Mar 13 '16 12:03

Jörg Battermann


2 Answers

You probably use .NET version where this interface is not implemented by the ConcurrentDictionary. From what I have tried it is not implemented by .NET versions before 4.6:

[SerializableAttribute]
[ComVisibleAttribute(false)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
    ExternalThreading = true)]
public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
    ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
    IDictionary, ICollection, IEnumerable

In current .NET framework version (4.6.2) the ConcurrentDictionary implements it:

[SerializableAttribute]
[ComVisibleAttribute(false)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
    ExternalThreading = true)]
public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
    ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
    IEnumerable, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>, 
    IReadOnlyCollection<KeyValuePair<TKey, TValue>>
like image 78
Eugene Podskal Avatar answered Nov 15 '22 00:11

Eugene Podskal


Well as it turns out a combo of .Net 4.6 being an in-place update and Resharper's 'Navigate to Sources' tricked me here -.-

Even though the project targets 4.5(.1), when navigating to the ConcurrentDictionary Sources (and being offline) R# fell back to 'decompiling' the assembly - and as .Net 4.6 replaces 4.5 altogether with its assemblies, R# "presented" the incorrect assemblies to me & I incorrectly assumed 4.5(.1) to already implement the IReadOnlyCollection interface, too. Meh.

Those in-place .Net updates really are somewhat confusing sometimes.

Oh well - thanks Eugene / Yacoub for making me triple check my source(s).

like image 43
Jörg Battermann Avatar answered Nov 15 '22 00:11

Jörg Battermann