C#类型转换:显式转换存在但抛出一个转换错误? [英] C# type conversion: Explicit cast exists but throws a conversion error?

查看:274
本文介绍了C#类型转换:显式转换存在但抛出一个转换错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


不能隐式转换类型

Cannot implicitly convert type

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 thoughHashSet does implement the IEnumerable 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#类型转换:显式转换存在但抛出一个转换错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆