为什么我需要转换IDictionary <t,hashset <s =“”>&gt;到IDictionary <t,ienumerable <s =“”>&gt;?</t,> </t,>

时间:2015-04-16 21:50:21

标签: c# dictionary casting type-inference

以下代码有效,因为HashSet实现了IEnumerable

IEnumerable<TEdge> edges = new HashSet<TEdge>();

但是如果我尝试在Dictionary中使用与键入值相同的值,则会出现编译错误:

IDictionary<TVertex, IEnumerable<TEdge>> vertexEdges = 
    new Dictionary<TVertex, HashSet<TEdge>>();  
  

Cannot implicitly convert type 'System.Collections.Generic.Dictionary<TVertex,System.Collections.Generic.HashSet<TEdge>>' to 'System.Collections.Generic.IDictionary<TVertex,System.Collections.Generic.IEnumerable<TEdge>>'. An explicit conversion exists (are you missing a cast?)

我在这里缺少什么?当然编译器应该能够弄清楚这一点,所以我猜测要么必须在限制背后做出一些有意义的决定,要么我做错了。

2 个答案:

答案 0 :(得分:6)

因为IDictionary<TVertex, HashSet<TEdge>>不是Dictionary<TVertex, IEnumerable<TEdge>>。如果是,您可以添加除TEdge以外的HashSet其他集合的值。

同样,您无法将List<Cat>投射到List<IAnimal>,否则您可以在列表中添加Dog

另请注意,演员表会在运行时失败。

答案 1 :(得分:2)

以下代码可以使用:

IDictionary<TVertex, IEnumerable<TEdge>> vertexEdges =
    new Dictionary<TVertex, IEnumerable<TEdge>>();  

这就是为什么你所拥有的代码无法运作的原因。您的vertexEdges将允许此代码:

IEnumerable<TEdge> list = new List<TEdge>();
vertexEdges.Add(vert, list);

这看似有效,因为list是IEnumerable。但是,vertexEdges只能存储HashSet,而不能存储IEnumerables。

您必须做出决定:如果您希望所有包含的类型都是哈希集,请更改您的vertexEdges decleration以显式使用HashSet。如果您不关心您存储的IEnumerable类型,请将您的字典设为IEnumerable。如果您这样做,将列表或哈希集添加到您的词典中是有效的。

如果您已经存在字典,并且希望将其转换为通用字典,则可以使用Linq实例化新字典:

Dictionary<TVertex, HashSet<TEdge>> oldDict = 
       new Dictionary<TVertex, HashSet<TEdge>>();
IDictionary<TVertex, IEnumerable<TEdge>> vertexEdges = oldDict
       .Select(k => 
          new KeyValuePair<TVertex, IEnumerable<TEdge>(k.Key, k.Value))
       .ToDictionary(k => k.Key, k => k.Value);

这种方法的真正缺点是你正在创建一个新词典。