为什么将 IDictionary<TKey, TValue> 向上转换为 IEnumerable<object> 会失败?

Why does upcasting IDictionary<TKey, TValue> to IEnumerable<object> fail?

查看以下代码片段:

(IEnumerable<object>)new Dictionary<string, string>()

以上转换将抛出无效转换异常。

其实IDictionary<TKey, TValue>也间接实现了IEnumerable<out T>,因为它也实现了ICollection<T>。也就是说,整个演员阵容应该是有效的。

事实上,对我来说更奇怪的是,如果我 运行 在调试器 watch 插槽上进行整个转换, 它可以工作!

怎么回事?

该字典确实实现了 IEnumerable<KeyValuePair<TKey, TValue>>IEnumerable,但是结构的 IEnumerable 与对象的 IEnumerable 不同。 Variance only works for reference-typesKeyValuePair<K, V> 是结构而不是 class。

这对我来说确实有效,应该是合乎逻辑的选择:

var x = (IEnumerable)new Dictionary<string, string>();

作为示例,这确实有效:

List<string> l = new List<string>();
var x = (IEnumerable<object>)l;

但是这个没有:

List<DateTime> l2 = new List<DateTime>();
var x = (IEnumerable<object>)l2;

清楚地表明结构是问题所在。

(为什么它在你的手表上有效 windows,我不知道)

我认为这是因为 KeyValuePair 是一个值类型。

这会失败:

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

这可行:

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

字典也一样。

这很奇怪。您的代码片段适用于 .NET 4.0。我建议你转换为 IEnumerable.

阅读:IDictionary Interface (MSDN)

如果你真的无法忍受简单的 IEnumerable,试试这个:

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