Это ошибка в Cast
или ToArray
, IMO. Код в этом ответе написан на C #, но, надеюсь, вы поймете, о чем он:)
Я полагаю, что Cast
сначала пытается выяснить, сработает ли простое преобразование ссылок, т. Е. Где он может вернуть ту же ссылку обратно.
Например:
String x = "hello";
IEnumerable<char> y = x.Cast<char>();
Console.WriteLine(object.ReferenceEquals(x, y)); // Prints true
К сожалению, он делает это, используя правила CLR для совместимости, согласно которым UInt16[]
и Int16[]
совместимы с . Это приводит к этому:
short[] array = new short[]{4, 5, 6};
IEnumerable<ushort> cast = array.Cast<ushort>();
Console.WriteLine(object.ReferenceEquals(array, cast)); // Prints True
К сожалению, если вы затем попытаетесь позвонить ToArray()
, это не радует:
// Explicit type argument just for clarity
cast.ToArray<ushort>(); // Bang
ToArray
без сомнения, пытается провести некоторую оптимизацию, которая в данном конкретном случае заканчивается неудачей, потому что тип не тот, который он действительно ожидает.
Я полагаю, что правильное поведение должно быть для Cast
, чтобы вернуть ленивый итератор, но для этого произойдет сбой, когда он будет выполнен позже. Вот что происходит, если вы попытаетесь перейти, например, с Int16
на Int32
.
Теперь, чтобы вернуться к тому, что вы действительно хотите сделать: используйте вместо этого Select
вызов. Cast
предназначен только для операций распаковки и преобразования ссылочных типов.