转换包含通用字典的通用字典

时间:2011-04-12 13:59:17

标签: c# generics dictionary casting nested

我有:

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

我希望将它转换为接口版本,即:

someInterfaceInstance = (IDictionary<string, IDictionary<string, bool>>)someConcreteInstance;

'someInterfaceInstance'是一个公共属性:

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

这可以正确编译,但会抛出运行时转换错误。

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]]'.

我错过了什么? (嵌套泛型类型/ Property的问题?)

3 个答案:

答案 0 :(得分:12)

其他答案是正确的,但为了清楚地知道这是非法的,请考虑以下事项:

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?

没有凡人可以阻止你将老虎放入IAnimals的字典中。但该字典实际上只限于包含长颈鹿。

出于同样的原因,你不能走另一条路:

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?

现在你把老虎放在长颈鹿类型的变量中。

如果编译器可以证明不会出现这种情况,那么通用接口协方差在C#4中是合法的。

答案 1 :(得分:4)

IDictionary不支持协方差。

看这里 IDictionary<TKey, TValue> in .NET 4 not covariant

答案 2 :(得分:1)

你能做的最多就是

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

此内部字典无法以不同方式引用(或通过强制转换)的原因是虽然Dictionary<string, bool>IDictionary<string, bool>,但并非所有IDictionary个对象都是Dictionary对象。因此,获得纯接口转换似乎允许您将其他<string, IDictionary<string, bool>>对添加到原始集合中,此时显然可能存在原始对象的类型违规。因此,不支持此功能。