You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何List<int>调用Cast<long>会抛出InvalidCastException?

问题解答

先看你给出的代码:

static void Main(string[] args) 
{ 
    List<int> myList = Enumerable.Range(0, 100).ToList(); 
    try 
    { 
        List<long> myListLong = myList.Cast<long>().ToList(); 
    } 
    catch (InvalidCastException e) 
    { 
        Console.WriteLine("Error"); 
    } 
    Console.ReadLine(); 
}

为什么会抛出InvalidCastException?

核心原因是LINQ的Cast<T>()方法并不处理数值类型之间的显式/隐式转换,它的设计目标是做两种特定转换:

  • 把非泛型IEnumerable(比如ArrayList)里的元素拆箱转换为指定的引用类型或值类型;
  • 对泛型IEnumerable<TInput>做引用转换(比如从基类引用转换为派生类引用,前提是实际类型匹配),或者拆箱转换(比如把object类型的装箱int转换为int)。

你的场景里,myList是List<int>,实现了IEnumerable<int>。调用Cast<long>()时,方法会尝试对每个int元素执行CLR层面的直接强制类型转换——但这不是我们平时写的(long)intValue这种数值转换,而是CLR认可的类型强制转换逻辑。由于int和long是完全独立的值类型,不存在这种CLR层面的转换规则,所以就会抛出InvalidCastException。

是不是因为int和long都是结构体类型?

不是的。这个异常和两者都是结构体没有直接关联:

  • 反例:如果有一个List<object>里面装的是装箱的int,调用Cast<long>()同样会抛出异常,因为拆箱只能拆回原类型(int),不能直接拆成long;
  • 正面例子:如果是引用类型,比如List<Animal>里面实际装的是Dog实例(Dog继承自Animal),调用Cast<Dog>()是完全可以正常工作的,这时候都是引用类型,但Cast能正确处理。

所以问题的本质是Cast<T>()不处理数值类型之间的数值转换,和是否是结构体无关。

正确的转换方式

如果你想把List<int>转成List<long>,应该用Select()方法来执行数值转换:

List<long> myListLong = myList.Select(x => (long)x).ToList();

Select()会遍历每个元素,执行你指定的显式数值转换,这才是处理这种场景的正确方式。

内容的提问来源于stack exchange,提问作者Martin Verjans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:04:21