将对象转换为IEnumerable <object>

时间:2018-03-19 16:55:27

标签: c# visual-studio-2017

以下是我遇到的问题的简化版本:

var list = new List<int> {1, 2, 3, 4, 5};
// list Count = 5 System.Collections.Generic.List<int>

var obj = list as object;
// obj  Count = 5   object {System.Collections.Generic.List<int>}

var enumerable = obj as IEnumerable<object>;
// enumerable   null    System.Collections.Generic.IEnumerable<object>

注释是Visual Studio 2017中观察窗口中的值

但是,如果我输入:

obj as IEnumerable<object>
在观察窗口中,我得到:

obj as IEnumerable<object>  Count = 5   System.Collections.Generic.IEnumerable<object> {System.Collections.Generic.List<int>}

那么为什么我可以在监视窗口中投射它并且它可以工作,但如果我在代码中执行它,它的计算结果为null?

1 个答案:

答案 0 :(得分:9)

来自C# documentation

  

仅针对参考类型支持通用接口的差异。值类型不支持方差。例如,IEnumerable<int>无法隐式转换为IEnumerable<object>,因为整数由值类型表示。

这里有一点有用的是,以下两件事情是非常不同的操作:

var l = (object) new List<int>();
var i = (object) 42;

尽管语法看起来一样。第一行仅将列表视为另一种类型(有些检查是否实际上可以使用强制转换),而第二行将整数转换为包含它的对象(装箱)。第三个变体是调用转换运算符,但看起来仍然相同。由于第一种变体可以随意改变对象并且只是以不同的方式解释它,它比第二种变体便宜得多。我在这个上下文中猜测这是唯一可以用于接口协方差的选项。