我有:
IDictionary<string, IDictionary<string, IList<long>>> OldDic1;
(仅用于说明目的,它被实例化并具有值 - 在其他地方)
为什么我可以这样做:?
Dictionary<string, IDictionary<string, IList<long>>> dic1 =
OldDic1 as Dictionary<string, IDictionary<string, IList<long>>>;
执行此行后,基本上dic1具有OldDic1的所有值;的工作原理。
然而,当我这样做时:
Dictionary<string, Dictionary<string, List<long>>> dic1 =
OldDic1 as Dictionary<string, Dictionary<string, List<long>>>;
我得到null,它与cast相同,除了它不会崩溃,而是返回null。所以问题是为什么我不能将它从接口转换为类型?有解决方案,然后改变它的存储方式吗?
答案 0 :(得分:2)
您只能重新投射最外层的接口/类名,而不是通用参数。你的第二次转换不起作用的原因与你不能从一种数组类型转换为另一种数组类型的原因相同,即使你可以转换“包含”对象。原因如下:
List<object> objects;
List<string> strings;
objects = strings as List<object>;
// Uh oh, that's not a string!
objects.Add(42);
objects = new List<object> { "The", "answer", "is", 42 };
// Uh oh, now strings contains an integer?
strings = objects as List<string>;
在你的第二个案例中会发生同样的事情。您可以向IDictionary
添加某种OldDic1
实际上不是Dictionary
,然后dic1
会爆炸。它将具有非Dictionary
值。茹哇!
因此,当您拥有容器时,只要IList<X>
相同,就可以从List<X>
更改为X
并返回。
答案 1 :(得分:0)
该行为与C#中的as keyword相关。字典与IDictionary不同。
如果你是以另一种方式进行投射,你可以在下一版本的.NET中使用它,这增加了对covariance and contravariance的支持。
您可能想要确定的解决方案为什么需要转换为具体的词典/列表,如果需要,则更改该类型的存储。