Why Enumerable.Cast raises an InvalidCastException?
Solution 1
Well, you have incorrect expectations of Cast
, that's all - it's meant to deal with boxing/unboxing, reference and identity conversions, and that's all. It's unfortunate that the documentation isn't as clear as it might be :(
The solution is to use Select
:
doubleNumbers2 = intNumbers.Select(x => (double) x).ToArray();
Solution 2
To add to Jon's answer cast is mainly useful for objects that implement IEnumerable
but nothing else. Take XmlNodeList for example. If you don't have the luxury of using System.Xml.Linq
namespace you can use Cast<XmlElement>
to write some nice LINQ queries against it.
var result = xmlNodeList
.Cast<XmlElement>()
.Select(e=> e.GetAttribute("A") + e.GetAttribute("B"))
.ToArray();
outlookrperson
Microsoft .NET (MCT/MCSD/MCPD) Instructor/Consultant established in São Paulo/Brazil Renato Person | MCT, MCSD
Updated on July 09, 2022Comments
-
outlookrperson almost 2 years
If I can implicitly cast an integer value to a double, like:
int a = 4; double b = a; // now b holds 4.0
Why can I not do this:
int[] intNumbers = {10, 6, 1, 9}; double[] doubleNumbers2 = intNumbers.Cast<double>().ToArray();
I get a "Specified cast is not valid"
InvalidCastException
exception.Doing the opposite (casting from double to int) results in the same error.
What am I doing wrong?
-
outlookrperson about 14 yearsgreat. It works to me. In fact as you have mentioned, the documentation is not clear about it. The documentation says "Converts the elements of an IEnumerable to the specified type". But reading foward, I realize that the IEnumerable.Cast<> is used to enable the standard query operators to be invoked on non-generic collections. Tks!
-
Jon Skeet about 14 yearsIt's also useful pre-C# 4 to get something like covariance: you can convert an
IEnumerable<Cat>
to anIEnumerable<Animal>
viaCast
, for instance. This isn't a problem as of C# 4, of course... although you might useCast
to perform the reverse conversion. -
Pop Catalin about 14 yearsCast performed value type and user defined conversions prior to Visual Studio 2008 SP1, when this behavior was removed: "Queries over non-generic collections now use standard C# cast semantics. " msdn.microsoft.com/en-us/library/dd310284.aspx
-
Shimmy Weitzhandler over 13 yearsWhat takes more performance, IEnumerable.Cast or Select(x=>(MyClass)x)?
-
Jon Skeet over 13 years@Shimmy: I'd have to measure to check - I doubt that it's significant. I'd expect the
Cast<>
call to be very silghtly faster, but almost unmeasurably so. -
Shimmy Weitzhandler over 13 yearsThanks @Jon, the question is if the Cast<> is an iterator function or is to be performed on the collection wrapper level (if there is such a thing at all).
-
Jon Skeet over 13 years@Shimmy: I don't know what you mean by "collection wrapper level" but
Cast
is a normal extension method onIEnumerable
. In fact, thinking about it, in some casesSelect
will be faster - if it's aList<int>
for example,Cast
would have to box and unbox each element, whereasSelect
won't. -
Felix K. about 12 years@JonSkeet I've tested the performance recently and select is faster in the most cases ( 1.000.000 runs @ 1000 iterations for both test's ).