jas*_*son 44 .net c# exception
以下抛出一个InvalidCastException.
IEnumerable<int> list = new List<int>() { 1 };
IEnumerable<long> castedList = list.Cast<long>();
Console.WriteLine(castedList.First());
Run Code Online (Sandbox Code Playgroud)
为什么?
我正在使用Visual Studio 2008 SP1.
Mat*_*ton 60
那很奇怪!有一个博客张贴在这里,描述了如何的行为Cast<T>().NET 3.5和.NET 3.5 SP1,但它仍然无法解释InvalidCastException的,如果你这样重写你的代码,你甚至间已改变:
var list = new[] { 1 };
var castedList = from long l in list select l;
Console.WriteLine(castedList.First());
Run Code Online (Sandbox Code Playgroud)
显然你可以通过自己做演员来解决它
var castedList = list.Select(i => (long)i);
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它并不首先解释错误.我尝试将列表转换为short和float,然后抛出相同的异常.
编辑
该博客文章确实解释了为什么它不起作用!
Cast<T>()是一种扩展方法,IEnumerable而不是IEnumerable<T>.这意味着当每个值到达它所投射的点时,它已经被装箱回System.Object.本质上,它试图这样做:
int i = 1;
object o = i;
long l = (long)o;
Run Code Online (Sandbox Code Playgroud)
此代码抛出您正在获取的InvalidCastException.如果你试图直接将一个int转换为long,那么将一个盒装的int转换为long也行不通.
当然怪异!
oku*_*ane 27
Enumerable.Cast方法定义如下:
public static IEnumerable<TResult> Cast<TResult>(
this IEnumerable source
)
Run Code Online (Sandbox Code Playgroud)
并且没有关于IEnumerable项的初始类型的信息,所以我认为你的每个int最初都是通过装箱转换为System.Object,然后它被尝试拆箱成长变量,这是不正确的.
类似的代码重现这个:
int i = 1;
object o = i; // boxing
long l = (long)o; // unboxing, incorrect
// long l = (int)o; // this will work
Run Code Online (Sandbox Code Playgroud)
因此,您的问题的解决方案将是:
ints.Select(i => (long)i)
Run Code Online (Sandbox Code Playgroud)