为什么Enumerable.Cast会引发InvalidCastException?

out*_*son 39 c# ienumerable casting

如果我可以隐式地将整数值转换为double,例如:

int a = 4;    
double b = a;
// now b holds 4.0
Run Code Online (Sandbox Code Playgroud)

为什么我不能这样做:

int[] intNumbers = {10, 6, 1, 9};    
double[] doubleNumbers2 = intNumbers.Cast<double>().ToArray();
Run Code Online (Sandbox Code Playgroud)

我得到"指定的演员表无效" InvalidCastException例外.

相反(从double转换为int)会导致相同的错误.

我究竟做错了什么?

Jon*_*eet 56

好吧,你有不正确的期望Cast,这就是全部 - 它意味着处理装箱/拆箱,参考和身份转换,这就是全部.不幸的是,文档并不像它可能那样清晰:(

解决方案是使用Select:

doubleNumbers2 = intNumbers.Select(x => (double) x).ToArray();
Run Code Online (Sandbox Code Playgroud)

  • @Shimmy:我不知道"收集包装器级别"是什么意思,但是"Cast"是"IEnumerable"上的常规扩展方法.事实上,考虑到它,在*某些情况下`Select`会更快 - 如果它是一个`List <int>`例如,`Cast`必须打包并取消装箱每个元素,而`Select`则不会. (2认同)

Cha*_*ion 8

添加到Jon的答案中,主要用于实现IEnumerable但没有其他任何内容的对象.以XmlNodeList为例.如果您没有使用System.Xml.Linq命名空间的奢侈,您可以使用它Cast<XmlElement>来编写一些不错的LINQ查询.

var result = xmlNodeList
    .Cast<XmlElement>()
    .Select(e=> e.GetAttribute("A") + e.GetAttribute("B"))
    .ToArray();
Run Code Online (Sandbox Code Playgroud)

  • 获得类似协方差之类的前C#4也很有用:例如,你可以通过`Cast`将`IEnumerable <Cat>`转换为`IEnumerable <Animal>`.当然,这不是C#4的问题......虽然您可以使用`Cast`来执行反向转换. (2认同)