C# 为什么我需要投IDictionary<;T、 HashSet<;S>&燃气轮机;到IDictionary<;T、 IEnumerable<;S>>;?

C# 为什么我需要投IDictionary<;T、 HashSet<;S>&燃气轮机;到IDictionary<;T、 IEnumerable<;S>>;?,c#,dictionary,casting,type-inference,C#,Dictionary,Casting,Type Inference,以下代码有效,因为HashSet实现了IEnumerable: IEnumerable<TEdge> edges = new HashSet<TEdge>(); IEnumerable edges=new HashSet(); 但如果我尝试在字典中使用与类型化值相同的值,则会出现编译错误: IDictionary<TVertex, IEnumerable<TEdge>> vertexEdges = new Dictionary<

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

IEnumerable<TEdge> edges = new HashSet<TEdge>();
IEnumerable edges=new HashSet();
但如果我尝试在字典中使用与类型化值相同的值,则会出现编译错误:

IDictionary<TVertex, IEnumerable<TEdge>> vertexEdges = 
    new Dictionary<TVertex, HashSet<TEdge>>();  
IDictionary顶点=
新字典();
无法将类型“System.Collections.Generic.Dictionary”隐式转换为“System.Collections.Generic.IDictionary”。存在显式转换(是否缺少转换?


我错过了什么?当然,编译器应该能够弄明白这一点,所以我猜测,要么限制背后有一些有意义的决定,要么我做错了。

因为
IDictionary
不是
字典。如果是,您可以添加一个值,该值是
TEdge
的其他集合,而不是
HashSet

同样,您不能将
列表
强制转换为
列表
,否则您可以将
添加到列表中


还要注意,强制转换将在运行时失败。

以下代码将正常工作:

IDictionary<TVertex, IEnumerable<TEdge>> vertexEdges =
    new Dictionary<TVertex, IEnumerable<TEdge>>();  
IDictionary顶点=
新字典();
这就是为什么你的代码不起作用。顶点将允许以下代码:

IEnumerable<TEdge> list = new List<TEdge>();
vertexEdges.Add(vert, list);
IEnumerable list=new list();
添加(顶点,列表);
这看起来是有效的,因为列表是IEnumerable。但是,顶点只能存储哈希集,不能存储IEnumerables

您必须做出一个决定:如果您希望所有包含的类型都是hashset,请将vertexgesdeclaration更改为显式使用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);
字典oldDict=
新字典();
IDictionary vertexges=oldDict
.选择(k=>
新的KeyValuePair(k.Key,k=>k.Value);

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

这个问题不应该结束,结束投票应该撤回。这是一个非常有效的问题,它表明我们努力了解幕后的情况,并提供足够的信息重现问题。谢谢,这是有意义的。我没有想到add方法的问题。据我所知,这是一个协方差的问题^_^另外,您完全正确,强制转换在运行时确实失败。您很高兴提到使用Linq在字典之间转换的示例=P