我有:
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的问题?)
答案 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
不支持协方差。
答案 2 :(得分:1)
你能做的最多就是
IDictionary<string, Dictionary<string, bool>> viaInterface = someConcreteInstance
此内部字典无法以不同方式引用(或通过强制转换)的原因是虽然Dictionary<string, bool>
是IDictionary<string, bool>
,但并非所有IDictionary
个对象都是Dictionary
对象。因此,获得纯接口转换似乎允许您将其他<string, IDictionary<string, bool>>
对添加到原始集合中,此时显然可能存在原始对象的类型违规。因此,不支持此功能。