C#类型转换:显式转换存在但引发转换错误?

Kja*_*ara 2 c# ienumerable dictionary type-conversion hashset

我了解到HashSet实现了IEnumerable接口.因此,可以隐式地将HashSet对象转换为IEnumerable:

HashSet<T> foo = new HashSet<T>();
IEnumerable<T> foo2 = foo; // Implicit cast, everything fine.
Run Code Online (Sandbox Code Playgroud)

这也适用于嵌套泛型类型:

HashSet<HashSet<T>> dong = new HashSet<HashSet<T>>();
IEnumerable<IEnumerable<T>> dong2 = dong; // Implicit cast, everything fine.
Run Code Online (Sandbox Code Playgroud)

至少那是我的想法.但如果我做了Dictionary,我遇到了一个问题:

IDictionary<T, HashSet<T>> bar = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar2 = bar; // compile error
Run Code Online (Sandbox Code Playgroud)

最后一行给出了以下编译错误(Visual Studio 2015):

无法隐式转换类型

System.Collections.Generic.IDictionary<T, System.Collections.Generic.HashSet<T>>System.Collections.Generic.IDictionary<T, System.Collections.Generic.IEnumerable<T>>.

存在显式转换(您是否错过了演员?)

但如果我通过写作进行演员表演

IDictionary<T, IEnumerable<T>> bar2 = (IDictionary<T, IEnumerable<T>>) bar;
Run Code Online (Sandbox Code Playgroud)

然后我在运行时获得了无效的强制转换异常.

两个问题:

  • 我该如何解决这个问题?是迭代密钥并逐步建立新字典的唯一方法吗?
  • 为什么我首先会遇到这个问题,即使HashSet实现了IEnumerable接口?

Cha*_*ger 5

它不起作用的原因是,由于相同的原因,其中的值IDictionary<TKey, TValue>不是共变量(也不是关键).如果允许,则此代码将编译,但必须导致异常:

IDictionary<T, HashSet<T>> foo = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar = foo;
foo.Add(key, new List<T>());
Run Code Online (Sandbox Code Playgroud)

你认为添加一个List<T>会工作,因为它会编译给定的值类型IEnumerable<T>.但是,它不能成功,因为实际值类型是HashSet<T>.

所以,是的:唯一的方法是创建一个新的字典.

var bar = foo.ToDictionary(x => x.Key, x => x.Value.AsEnumerable());
Run Code Online (Sandbox Code Playgroud)