Hello,
why the next example throws a System.ArrayTypeMismatchException?
New Int16(){4,5,6}.Cast(of UInt16).ToArray()
I expected that this line returned a UInt16 array containing 4,5 and 6.
Thanks in advance.
Hello,
why the next example throws a System.ArrayTypeMismatchException?
New Int16(){4,5,6}.Cast(of UInt16).ToArray()
I expected that this line returned a UInt16 array containing 4,5 and 6.
Thanks in advance.
Because Int16 and UInt16 are different types. You could try this:
New Int16() {4, 5, 6}.Select(Function(x) CType(x, UInt16)).ToArray()
This is a bug in Cast
or ToArray
, IMO. The code in this answer is in C#, but hopefully you can see what it's about :)
I believe that Cast
first tries to see if a simple reference conversion will work - i.e. where it can return the same reference back.
For example:
String x = "hello";
IEnumerable<char> y = x.Cast<char>();
Console.WriteLine(object.ReferenceEquals(x, y)); // Prints true
Unfortunately, it does this using the CLR rules for compatibility - under which UInt16[]
and Int16[]
are compatible. That leads to this happening:
short[] array = new short[]{4, 5, 6};
IEnumerable<ushort> cast = array.Cast<ushort>();
Console.WriteLine(object.ReferenceEquals(array, cast)); // Prints True
Unfortunately if you then try to call ToArray()
, it's not happy:
// Explicit type argument just for clarity
cast.ToArray<ushort>(); // Bang
ToArray
no doubt tries to do some optimisation - which fails in this particular case because the type isn't what it really expects it to be.
I believe the correct behaviour should be for Cast
to return a lazy iterator, but for that to fail when it executes later. That's what happens if you try to go from Int16
to Int32
, for example.
Now, to get back to what you really want to do: use a Select
call instead. Cast
is only meant to be for unboxing operations and reference type conversions.