C# 为什么升级IDictionary<;TKey,TValue>;到IEnumerable<;对象>;失败?

C# 为什么升级IDictionary<;TKey,TValue>;到IEnumerable<;对象>;失败?,c#,.net,casting,c#-6.0,.net-4.6,C#,.net,Casting,C# 6.0,.net 4.6,请参阅以下代码段: (IEnumerable<object>)new Dictionary<string, string>() (IEnumerable)新字典() 上述强制转换将引发无效的强制转换异常 实际上,IDictionary也间接实现了IEnumerable,因为它还实现了ICollection。也就是说,整个演员阵容应该是有效的 事实上,对我来说,更奇怪的是,如果我在调试器的观察槽上运行整个cast,它可以工作 发生了什么事?该词典确实实现了IEnume

请参阅以下代码段:

(IEnumerable<object>)new Dictionary<string, string>()
(IEnumerable)新字典()
上述强制转换将引发无效的强制转换异常

实际上,
IDictionary
也间接实现了
IEnumerable
,因为它还实现了
ICollection
。也就是说,整个演员阵容应该是有效的

事实上,对我来说,更奇怪的是,如果我在调试器的观察槽上运行整个cast,它可以工作


发生了什么事?

该词典确实实现了
IEnumerable
IEnumerable
,但是结构的
IEnumerable
与对象的
IEnumerable
不同

这在我这边确实有效,应该是合乎逻辑的选择:

var x = (IEnumerable)new Dictionary<string, string>();
var x=(IEnumerable)new Dictionary();
作为示例,这确实有效:

List<string> l = new List<string>();
var x = (IEnumerable<object>)l;
List l=新列表();
变量x=(IEnumerable)l;
但这一条没有:

List<DateTime> l2 = new List<DateTime>();
var x = (IEnumerable<object>)l2;
List l2=新列表();
变量x=(IEnumerable)l2;
明确指出结构是问题所在


(我不知道为什么它能在手表窗口中工作)

我认为这是因为
KeyValuePair
是一种值类型

这将失败:

List<int> ints = new List<int>();
var objs = (IEnumerable<object>)ints;
List ints=new List();
var objs=(IEnumerable)int;
这将有助于:

List<string> ints = new List<string>();
var objs = (IEnumerable<object>)ints;
List ints=new List();
var objs=(IEnumerable)int;

字典也是如此。

这很奇怪。您的代码片段在.NET 4.0中运行良好。我建议您强制转换为
IEnumerable


阅读:(MSDN)

如果你真的不能忍受纯
IEnumerable
,试试以下方法:

new Dictionary<string, string>().Cast<object>();
newdictionary().Cast();


但是
IEnumerable
是协变的!这并不能解释为什么一块有着相同表带的手表已经可以工作了!相关:@PatrickHofman这就是让我发疯的原因,我想问这个问题。事实上,我必须承认我的错误:我从未要求值类型的协方差,这让我对无法完成整个过程一无所知cast@PatrickHofman为什么不呢?只有一个名为
IEnumerable
的接口具有协变类型参数。即使协方差不能用于值类型…………我错了吗?@CodeCaster我的意思是接口本身是
IEnumerable
@CodeCaster Argh,@CodeCaster你知道我们在说什么。我知道
IEnumerable
IEnumerable
的类型不同,但当您实现这些时,您实现的是
IEnumerable
太好了,这就清楚了。我厌倦了在MSDN上点击继承树你完全正确。现在我们应该接受Patrick的答案,但是像Eric Lippert这样的人能够回答我们为什么调试器比我们更强大,这将是一件好事!我想这只是调试工具中的一个解析错误。我不认为他们真的会即时编译语句,然后对其进行评估@马蒂asFidemraizer@PatrickHofman是的,应该是。。。顺便说一句,这可能被认为是一个bug:调试器与实际运行时行为并非100%一致:\@MatíasFidemraizer一方面,你是对的。另一方面。。。当您意识到调试器根本无法使用.NET framework时(您正在调试的进程被挂起,这包括该进程的整个.NET运行时),调试器离您有多近仍然令人印象深刻。在LISP机器上,“调试”仍然给您留下了“运行时”的所有能力;在进行本机调试时也是如此(然而,与.NET相比,本机调试器通常很糟糕)。NET调试器也不能这样做。我希望他们能像这样修复每一个小错误,但不能真的阻止他们:D@Luaan你说得对。毕竟,软件是由像我们这样的人完成的,我们不能涵盖世界上的每一个角落。这更让人开心,不是吗?你确定吗?我自己已经试过了,它抛出了同样的例外,它与.net4.0一起工作,与.net4.5一起失败。无论如何,帕特里克·霍夫曼和用户3185569搞定了。从MSDN中,它实现IEnumerable,而不是IEnumerable,因为KeyValuePair是一个结构。我建议我们接受帕特里克·霍夫曼的回答,这不是问题所在。奥普肯定知道这一点。他只是想知道为什么会这样。是的,当然。问题是调用
Enumerable.Cast
会生成一个新的Enumerable,我需要保存同一个实例,并将其强制转换到由整个类型实现的不同接口上。您可以将
Dictionary
子类化吗?如果可以,可以让它实现
IEnumerable