令人困惑的 Enumerable.Cast InvalidCastException [英] Puzzling Enumerable.Cast InvalidCastException

查看:14
本文介绍了令人困惑的 Enumerable.Cast InvalidCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下抛出一个 InvalidCastException.

IEnumerable<int> list = new List<int>() { 1 };
IEnumerable<long> castedList = list.Cast<long>();
Console.WriteLine(castedList.First());

为什么?

我使用的是 Visual Studio 2008 SP1.

I'm using Visual Studio 2008 SP1.

推荐答案

这很奇怪!有一篇博文 这里 描述了 Cast() 的行为在 .NET 3.5 和 .NET 3.5 SP1 之间是如何变化的,但它仍然没有解释InvalidCastException,如果你这样重写你的代码,你甚至会得到它:

That's very odd! There's a blog post here that describes how the behaviour of Cast<T>() was changed between .NET 3.5 and .NET 3.5 SP1, but it still doesn't explain the InvalidCastException, which you even get if you rewrite your code thus:

var list = new[] { 1 };
var castedList = from long l in list select l;
Console.WriteLine(castedList.First());

显然你可以自己做演员来解决这个问题

Obviously you can work around it by doing the cast yourself

var castedList = list.Select(i => (long)i);

这行得通,但它并不能首先解释错误.我尝试将列表转换为 short 和 float,但那些抛出了相同的异常.

This works, but it doesn't explain the error in the first place. I tried casting the list to short and float and those threw the same exception.

编辑

那篇博文确实解释了为什么它不起作用!

That blog post does explain why it doesn't work!

Cast()IEnumerable 上的扩展方法,而不是 IEnumerable.这意味着当每个值到达它被转换的点时,它已经被装回一个 System.Object.从本质上讲,它正在尝试这样做:

Cast<T>() is an extension method on IEnumerable rather than IEnumerable<T>. That means that by the time each value gets to the point where it's being cast, it has already been boxed back into a System.Object. In essence it's trying to do this:

int i = 1;
object o = i;
long l = (long)o;

这段代码会抛出你得到的 InvalidCastException.如果您尝试将 int 直接转换为 long 没问题,但将盒装 int 转换回 long 不起作用.

This code throws the InvalidCastException you're getting. If you try to cast an int directly to a long you're fine, but casting a boxed int back to a long doesn't work.

当然是个怪人!

这篇关于令人困惑的 Enumerable.Cast InvalidCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆