Puzzling Enumerable.Cast 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);

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!

Leave a Comment