C#类型转换: Explicit cast exists but throws a conversion error?

标签 c# dictionary type-conversion ienumerable hashset

我了解到HashSet实现 IEnumerable界面。因此,可以隐式地转换一个 HashSet。对象进入 IEnumerable :

HashSet<T> foo = new HashSet<T>();
IEnumerable<T> foo2 = foo; // Implicit cast, everything fine.

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

HashSet<HashSet<T>> dong = new HashSet<HashSet<T>>();
IEnumerable<IEnumerable<T>> dong2 = dong; // Implicit cast, everything fine.

至少我是这么想的。但是如果我做一个Dictionary ,我遇到了一个问题:

IDictionary<T, HashSet<T>> bar = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar2 = bar; // compile error

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

Cannot implicitly convert type

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

An explicit conversion exists (are you missing a cast?)

但是如果我通过写作来进行转换

IDictionary<T, IEnumerable<T>> bar2 = (IDictionary<T, IEnumerable<T>>) bar;

然后我在运行时得到一个无效的转换异常。

两个问题:

  • 我该如何解决这个问题?迭代键并一点一点地构建新字典是唯一的方法吗?
  • 为什么我首先遇到这个问题,即使 HashSet确实实现了 IEnumerable界面?

最佳答案

它不起作用的原因是 IDictionary<TKey, TValue> 中的值不是 co-variant (出于同样的原因,也不是关键)。如果允许的话,那么这段代码可以编译,但必须导致异常:

IDictionary<T, HashSet<T>> foo = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar = foo;
foo.Add(key, new List<T>());

你会想添加一个 List<T>会起作用,因为它会编译,因为值类型应该是 IEnumerable<T> .但是,它不会成功,因为实际 值类型是 HashSet<T> .

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

var bar = foo.ToDictionary(x => x.Key, x => x.Value.AsEnumerable());

关于C#类型转换: Explicit cast exists but throws a conversion error?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38503311/

相关文章:

c# - 使用 List<MyClass> 数组创建单元测试

python - 反转默认字典

c++ - DVP7010B 显卡 DLL 的 C++ 头文件的 Delphi 转换?

swift - 使用枚举键向 Swift 字典添加值

python - 试图找到元素较少的列表

go - 如何将字节类型值转换为int类型值

string - 如何将整数转换为字符串?

c# - 无法在 memcached 中存储复杂对象

c# - 如何使用 NEST QueryString 并转义特殊字符?

c# - List.Contains 在迭代 foreach 循环时不起作用