问题描述
我了解到 HashSet
实现了 IEnumerable
接口。因此,可以将 HashSet
对象隐式转换为 IEnumerable
:
I learned that HashSet
implements the IEnumerable
interface. Thus, it is possible to implicitly cast a HashSet
object into IEnumerable
:
HashSet<T> foo = new HashSet<T>();
IEnumerable<T> foo2 = foo; // Implicit cast, everything fine.
这也适用于嵌套泛型类型:
This works for nested generic types, too:
HashSet<HashSet<T>> dong = new HashSet<HashSet<T>>();
IEnumerable<IEnumerable<T>> dong2 = dong; // Implicit cast, everything fine.
至少这就是我的想法。但是如果我做一个字典
,我遇到一个问题:
At least that's what I thought. But if I make a Dictionary
, I run into a problem:
IDictionary<T, HashSet<T>> bar = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar2 = bar; // compile error
最后一行给我以下编译错误(Visual Studio 2015): p>
The last line gives me the following compile error (Visual Studio 2015):
System.Collections.Generic .IDictionary< T,System.Collections.Generic.HashSet< T>
到
System.Collections.Generic.IDictionary< T,System.Collections.Generic
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?)
但是,如果我通过写作执行演员
But if I do the cast by writing
IDictionary<T, IEnumerable<T>> bar2 = (IDictionary<T, IEnumerable<T>>) bar;
然后我在运行时得到一个无效的转换异常。
then I get an invalid cast exception at runtime.
两个问题:
- 我该如何解决?是唯一的方法来迭代密钥,并逐一建立一个新的字典?
- 为什么我首先得到这个问题,即使
HashSet
实现IEnumerable
界面?
- How do I solve this? Is the only way to iterate over the keys and build up a new dictionary bit by bit?
- Why do I get this problem in the first place, even though
HashSet
does implement theIEnumerable
interface?
推荐答案
它不起作用的原因是 IDictionary< TKey,TValue>
中的值不是(同样的原因也不是关键)。如果它被允许,那么这个代码将被编译,但是有会导致一个异常:
The reason it doesn't work is that the value in IDictionary<TKey, TValue>
is not co-variant (and nor is the key, for the same reasons). If it were allowed to be, then this code would compile, but has to result in an exception:
IDictionary<T, HashSet<T>> foo = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar = foo;
foo.Add(key, new List<T>());
你会认为添加一个列表< T>
将工作,因为它将编译,因为值类型应该是 IEnumerable< T>
。但是,由于实际值类型是 HashSet
。
You'd think adding a List<T>
would work, as it would compile given the value type is supposedly IEnumerable<T>
. It can't succeed, though, as the actual value type is HashSet<T>
.
所以,是的,唯一的方法是创建一个新的字典。
So, yes: the only way is to create a new dictionary.
var bar = foo.ToDictionary(x => x.Key, x => x.Value.AsEnumerable());
这篇关于C#类型转换:显式转换存在但抛出一个转换错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!