Jest to błąd w Cast
lub ToArray
, IMO. Kod w tej odpowiedzi jest w języku C#, ale mam nadzieję, że widzisz o co chodzi :)
Najpierw spróbuję sprawdzić, czy prosta konwersja referencyjna zadziała - tzn. Czy może przywrócić to samo odwołanie.
Na przykład:
String x = "hello";
IEnumerable<char> y = x.Cast<char>();
Console.WriteLine(object.ReferenceEquals(x, y)); // Prints true
Niestety, robi to za pomocą reguł CLR dla kompatybilności - w ramach którego UInt16[]
i Int16[]
są kompatybilne. To prowadzi do tego dzieje:
short[] array = new short[]{4, 5, 6};
IEnumerable<ushort> cast = array.Cast<ushort>();
Console.WriteLine(object.ReferenceEquals(array, cast)); // Prints True
Niestety jeśli spróbuj zadzwonić ToArray()
, że nie jest zadowolony:
// Explicit type argument just for clarity
cast.ToArray<ushort>(); // Bang
ToArray
niewątpliwie stara się zrobić kilka optymalizacji - co nie w tym konkretnym przypadku, ponieważ typ nie jest tym, czego naprawdę oczekuje.
Uważam, że poprawne zachowanie należy do Cast
, aby zwrócić leniwy iterator, ale do tego, aby zawieść, gdy wykonuje się później. To się dzieje, gdy próbujesz na przykład przejść z Int16
do Int32
.
Teraz, aby wrócić do tego, co chcesz zrobić: : użyj połączenia Select
. Cast
służy wyłącznie do rozpakowywania operacji i konwersji typów referencyjnych.
Dzięki, niestety nie mam wiedzy o LINQ nadal i Zawsze mam więcej rzeczy do załatwienia, wiesz. Jeszcze raz dzięki. –