【问题标题】:Why Enumerable.Cast raises an InvalidCastException?为什么 Enumerable.Cast 会引发 InvalidCastException?
【发布时间】:2018-01-18 17:30:31
【问题描述】:

如果我可以将整数值隐式转换为双精度值,例如:

int a = 4;    
double b = a;
// now b holds 4.0

为什么我不能这样做:

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

我收到“指定的演员表无效”InvalidCastException 异常。

做相反的事情(从 double 转换为 int)会导致同样的错误。

我做错了什么?

【问题讨论】:

标签: c# casting ienumerable


【解决方案1】:

好吧,您对 Cast 的期望不正确,仅此而已 - 它旨在处理装箱/拆箱、引用和身份转换,仅此而已。不幸的是,文档并不像它可能的那样清晰:(

解决方法是使用Select:

doubleNumbers2 = intNumbers.Select(x => (double) x).ToArray();

【讨论】:

  • 太棒了。它对我有用。事实上,正如您所提到的,文档并不清楚。文档说“将 IEnumerable 的元素转换为指定的类型”。但是向前阅读,我意识到 IEnumerable.Cast 用于使标准查询运算符能够在非泛型集合上调用。谢了!
  • Cast 在 Visual Studio 2008 SP1 之前执行值类型和用户定义的转换,当此行为被移除时:“对非泛型集合的查询现在使用标准 C# 转换语义。”msdn.microsoft.com/en-us/library/dd310284.aspx
  • 什么需要更高的性能,IEnumerable.Cast 还是 Select(x=>(MyClass)x)?
  • @Shimmy:我不知道您所说的“集合包装级别”是什么意思,但CastIEnumerable 上的正常扩展方法。事实上,仔细想想,在 某些 的情况下,Select 会更快——例如,如果是 List&lt;int&gt;Cast 将不得不对每个元素进行装箱和拆箱,而 Select 赢了't。
  • @JonSkeet 我最近测试了性能,在大多数情况下 select 更快(两个测试的 1.000.000 次运行 @ 1000 次迭代)。
【解决方案2】:

添加到 Jon 的答案中主要对实现 IEnumerable 的对象有用,但仅此而已。以XmlNodeList 为例。如果你没有使用 System.Xml.Linq 命名空间的奢侈,你可以使用 Cast&lt;XmlElement&gt; 来编写一些不错的 LINQ 查询。

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

【讨论】:

  • 在 C# 4 之前获得协方差之类的东西也很有用:例如,您可以通过 CastIEnumerable&lt;Cat&gt; 转换为 IEnumerable&lt;Animal&gt;。从 C# 4 开始,这当然不是问题……尽管您可以使用 Cast 执行反向转换。
猜你喜欢
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 2011-12-03
  • 2016-04-19
相关资源
最近更新 更多