开发者

Casting a generic dictionary containing a generic dictionary

开发者 https://www.devze.com 2023-02-25 13:21 出处:网络
I have: var someConcreteInstance = new Dictionary<string, Dictionary<string, bool>>(); and I wish to cast it to an interface version, i.e.:

I have:

var someConcreteInstance = new Dictionary<string, Dictionary<string, bool>>();

and I wish to cast it to an interface version, i.e.:

someInterfaceInstance = (IDictionary<string, IDictionary<string, bool>>)someCo开发者_C百科ncreteInstance;

'someInterfaceInstance' is a public property:

IDictionary<string, IDictionary<string, bool>> someInterfaceInstance { get; set; }

This compiles correctly, but throws a runtime casting error.

Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.Dictionary`2[System.String,System.Boolean]]' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Collections.Generic.IDictionary`2[System.String,System.Boolean]]'.

What am I missing? (Problems with the nested generic type/Property?)


The other answers are right, but just to be crystal clear as to why this is illegal, consider the following:

interface IAnimal {}
class Tiger : IAnimal {}
class Giraffe : IAnimal {}
...
Dictionary<string, Giraffe> d1 = whatever;
IDictionary<string, IAnimal> d2 = d1; // suppose this were legal
d2["blake"] = new Tiger(); // What stops this?

No mortal hand can stop you putting a tiger into a dictionary of IAnimals. But that dictionary is actually constrained to contain only giraffes.

For the same reason you can't go the other way either:

Dictionary<string, IAnimal> d3 = whatever;
d3["blake"] = new Tiger(); 
IDictionary<string, Giraffe> d4 = d3; // suppose this were legal
Giraffe g = d4["blake"]; // What stops this?

Now you're putting a tiger in a variable of type giraffe.

Generic interface covariance is only legal in C# 4 if the compiler can prove that situations like this cannot arise.


IDictionary does not support covariance.

Look here IDictionary<TKey, TValue> in .NET 4 not covariant


The most you will be able to do is

IDictionary<string, Dictionary<string, bool>> viaInterface = someConcreteInstance

The reason your inner dictionary cannot be referenced differently here (or via a cast) is that while Dictionary<string, bool> is an IDictionary<string, bool>, not all IDictionary objects will be Dictionary objects. As such, obtaining a pure interface cast would then seemingly allow you to add other <string, IDictionary<string, bool>> pairs to the original collection, when clearly there could be type violations for the original object. Therefore, this is not supported.

0

精彩评论

暂无评论...
验证码 换一张
取 消