以下代码有效,因为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?)
我在这里缺少什么?当然编译器应该能够弄清楚这一点,所以我猜测要么必须在限制背后做出一些有意义的决定,要么我做错了。
答案 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);
这种方法的真正缺点是你正在创建一个新词典。