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

2024-01-08

我了解到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):

无法隐式转换类型

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

存在显式转换(您是否缺少强制转换?)

但如果我通过写作来选角

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

然后我在运行时收到无效的强制转换异常。

两个问题:

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

它不起作用的原因是IDictionary<TKey, TValue> is not 协变体 https://msdn.microsoft.com/en-gb/library/mt654055.aspx(出于同样的原因,也不是关键)。如果允许,那么这段代码可以编译,但是has导致异常:

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>。但它不可能成功,因为actual值类型是HashSet<T>.

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

var bar = foo.ToDictionary(x => x.Key, x => x.Value.AsEnumerable());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 类型转换:存在显式强制转换但引发转换错误? 的相关文章

随机推荐