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);
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.
Edit
That blog post does explain why it doesn't work!
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;
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.
Certainly an oddity!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…