2014-09-10 17 views
7

Próbowałem przekonwertować tablicę z byte[] na sbyte[].Konwertuj bajt [] na sbyte []

Oto mój przykładowy Array:

byte[] unsigned = { 0x00, 0xFF, 0x1F, 0x8F, 0x80 }; 

ja już próbowałem:

sbyte[] signed = (sbyte[])((Array)unsigned); 

Ale to nie działa. Po tej operacji nie ma wartości w tablicy.

Czy ktoś ma lepszy pomysł?

+1

Ten kod działa w tym sensie, że kompiluje i nie zgłasza żadnego błędu. Wynikiem tego jest tablica, która może być używana jako 'sbyte []' w prawie każdej sytuacji, ale nadal jest oznaczona jako "byte []" przez środowisko wykonawcze. Nie jestem pewien, co masz na myśli przez "nie ma wartości w tablicy", dla mnie tablica ma postać {0, -1, 31, -113, -128} 'zgodnie z oczekiwaniami. – CodesInChaos

+0

Po kompilacji nie ma wartości w podpisanej tablicy. Visual Studio pokazuje "?" w każdym elemencie podpisanej tablicy. – REMberry

+0

Ok, próbuję uzyskać element z podpisanej tablicy i nadal działa. Dzięki za pomoc. Próbuję użyć tego rozwiązania. – REMberry

Odpowiedz

12
sbyte[] signed = (sbyte[]) (Array) unsigned; 

Działa to, ponieważ bajt i bajt mają tę samą długość w pamięci i można je konwertować bez potrzeby zmiany reprezentacji pamięci.

Ta metoda może jednak prowadzić do dziwnych błędów w debugerze. Jeśli twoja tablica bajtów nie jest zbyt duża, możesz zamiast tego użyć Array.ConvertAll.

sbyte[] signed = Array.ConvertAll(unsigned, b => unchecked((sbyte)b)); 
+0

Użyłbym 'niezaznaczonego ((sbyte) b)' tak działa, nawet jeśli włączona jest sprawdzona arytmetyka. Służy także jako dokumentacja, że ​​przepełnienia są zamierzone, a nie tylko optymalizacja wydajności. – CodesInChaos

+0

Moja pamięć poinformowała mnie, że kontrole przepełnienia nie mają zastosowania do bajtów/sbajtów. Mogłem się mylić. ** EDYCJA: ** ustalona teraz :) –

+0

Rzucanie 255 do 'sbyte' z pewnością rzuca ze sprawdzoną arytmetyką. To, co mogło cię pomylić, to to, że '(byte) 255 + (byte) 255' nie rzuca, ponieważ operandy zostają awansowane do' int', gdzie nie przepełnia się. – CodesInChaos

1

łatwo zrobić tak:

sbyte[] signed = unsigned.Select(b=>(sbyte)b).ToArray(); 

nie jestem pewien o składni. sprawdź to.

+1

To działa. Ale 1) 'ConvertAll' jest szybszy i tak samo czytelny 2) Wolę' niezaznaczone ((sbyte) b) '. Aby uzyskać szczegółowe informacje, patrz odpowiedź @ Sepehr. – CodesInChaos

2

Jak korzystać z Buffer.BlockCopy? Dobrą rzeczą w tej odpowiedzi jest to, że unika kontroli odlewania bajt po bajcie. Złą rzeczą w tej odpowiedzi jest to, że unika kontroli odlewania bajt po bajcie.

var unsigned = new byte[] { 0x00, 0xFF, 0x1F, 0x8F, 0x80 }; 
var signed = new sbyte[unsigned.Length]; 
Buffer.BlockCopy(unsigned, 0, signed, 0, unsigned.Length); 

to tylko kopiuje bajtów wartości powyżej byte.MaxValue będzie miał wartość ujemną sbyte.

Wykonuje dwie linie kodu, ale powinna być szybka.

+0

Nie ma potrzeby "@". "signed' /" unsigned' nie są słowami kluczowymi w języku C#. – CodesInChaos

+0

@CodesInChaos SO doprowadziło mnie do złą. – Jodrell