2009-12-14 11 views

Odpowiedz

7

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[] 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.

+0

Dzięki, niestety nie mam wiedzy o LINQ nadal i Zawsze mam więcej rzeczy do załatwienia, wiesz. Jeszcze raz dzięki. –

5

Ponieważ Int16 i UInt16 są różnymi typami. Można spróbować to:

New Int16() {4, 5, 6}.Select(Function(x) CType(x, UInt16)).ToArray() 
+0

Dlatego dzwonię do Casta, nieprawdaż? Jeśli będą tam, gdzie tego samego typu nie będzie potrzebny Cast. –

+0

"Cast" działa tylko wtedy, gdy typy są zgodne (jeden pochodzi od drugiego). 'Int16' i' UInt16' nie mają ze sobą nic wspólnego. –

+0

OK, więc czy istnieje sposób robienia tego samego z CType zamiast z DirectCast? –

Powiązane problemy