简体   繁体   English

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

[英]C# type conversion: Explicit cast exists but throws a conversion error?

I learned that HashSet implements the IEnumerable interface. 我了解到HashSet实现了IEnumerable接口。 Thus, it is possible to implicitly cast a HashSet object into IEnumerable : 因此,可以将HashSet对象隐式转换为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: 但如果我创建一个Dictionary ,我会遇到一个问题:

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

The last line gives me the following compile error (Visual Studio 2015): 最后一行给出了以下编译错误(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>> . 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. 然后我在运行时获得了无效的强制转换异常。

Two questions: 两个问题:

  • 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 the IEnumerable interface? 为什么我首先会遇到这个问题,即使HashSet确实实现了IEnumerable接口?

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). 它不起作用的原因是IDictionary<TKey, TValue>值不是共变体 (并且也是关键,出于同样的原因)。 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>());

You'd think adding a List<T> would work, as it would compile given the value type is supposedly IEnumerable<T> . 您认为添加List<T>会起作用,因为它会编译,因为值类型应该是IEnumerable<T> It can't succeed, though, as the actual value type is HashSet<T> . 但是,它不能成功,因为实际值类型是HashSet<T>

So, yes: the only way is to create a new dictionary. 所以,是的:唯一的方法是创建一个新的字典。

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

How do I solve this? 我该如何解决这个问题? Is the only way to iterate over the keys and build up a new dictionary bit by bit? 是迭代密钥并逐步建立新字典的唯一方法吗?

It may not be the most elegant solution, but it works: 它可能不是最优雅的解决方案,但它有效:

IDictionary<T, HashSet<T>> bar = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar2 = bar.ToDictionary(x => x.Key, y => (IEnumerable<T>)y.Value);

The reason why the Dictionary cast isn't working is because IEnumerable is co-variant, note <out T> in the declaration Dictionary强制转换不起作用的原因是因为IEnumerable是共变量,请注意声明中的<out T>

public interface IEnumerable<out T> : IEnumerable

IDictionary isn't. IDictionary不是。

public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable

You can read more about it here: https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx 你可以在这里阅读更多相关信息: https//msdn.microsoft.com/en-us/library/dd799517(v = vs1010).aspx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 显式转换存在C# - Explicit conversion exists c# vb.NET到C#的转换错误:无法将类型&#39;object&#39;隐式转换为&#39;MyCustomObject&#39; - vb.NET to C# conversion error: Cannot implicitly convert type 'object' to 'MyCustomObject' An explicit conversion exists c#从字符串转换为特殊类型-“存在显式转换” - c# Converting from string to special type - “an explicit conversion exists” 错误存在显式转换C#,MVVM Light-LINQ - Error An explicit conversion exists C#, MVVM Light - LINQ C#显式转换错误 - C# Explicit Conversion Error 转换错过的C#显式转换 - cast missed c# explicit conversion CS0266 C# 无法将类型“UnityEngine.Object”隐式转换为“”。 存在显式转换(您是否缺少演员表?) - CS0266 C# Cannot implicitly convert type 'UnityEngine.Object' to ''. An explicit conversion exists (are you missing a cast?) 无法隐式转换类型,存在显式转换(您是否缺少强制转换?) - Cannot implicitly convert type, explicit conversion exists (are you missing a cast?) 无法隐式转换类型,存在显式转换(您是否缺少强制转换?) - Cannot implicitly convert type, an explicit conversion exists (are you missing a cast?) 错误26无法将类型&#39;object&#39;隐式转换为&#39;string&#39;。 存在显式转换(您是否缺少演员表?) - Error 26 Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM