2014-09-10 20 views
7

Bir Array öğesini byte[]'dan sbyte[]'a dönüştürmeyi denedim. Zaten bu denenmişKopyalama [] - sbyte []

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

:

İşte benim örnek Array

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

Ama çalışmıyor. Bu işlemden sonra dizide değer yoktur.

Herhangi birinin daha iyi bir fikri var mı?

+1

Bu kod, derleme yapması ve hata yapmaması anlamında çalışır. Neredeyse her durumda sbyte [] 'olarak kullanılabilen bir dizi ile sonuçlanır, ancak çalışma zamanı tarafından hala byte [] olarak işaretlenir. "Dizide değer yok" ile ne kastettiğinizden emin değilim, benim için dizi beklendiği gibi {0, -1, 31, -113, -128}. – CodesInChaos

+0

Derlemeden sonra imzalı dizide değer yoktur. Visual Studio "?" Gösterir İmzalı dizinin her öğesinde. – REMberry

+0

Tamam, imzalı diziden bir öğe almaya çalışıyorum ve hala çalışıyor. Yardım ettiğin için teşekkür ederim. Bu çözümü kullanmaya çalışıyorum. – REMberry

cevap

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

Bu çalışır.

Bu yöntem, hata ayıklayıcısında bazı garip hatalara neden olabilir. Bayt diziniz çok büyük değilse, bunun yerine Array.ConvertAll'u kullanabilirsiniz.

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

'İşaretlenmemiş ((sbyte) b) 'yi kullanırdım, böylece kontrol edilen aritmetik etkin olsa bile çalışır. Ayrıca taşmaların yalnızca bir performans optimizasyonu değil, kasıtlı olduğu dokümantasyonu olarak da hizmet eder. – CodesInChaos

+0

Hafızamda, taşma kontrollerinin bayt/sbytes için geçerli olmadığı belirtildi. Yanılmış olabilirim. ** DÜZENLEME: ** şimdi düzeltildi :) –

+0

Döküm 255'ten 'sbyte'ye kesinlikle kontrol edilen aritmetik ile atar. Kafanızı karıştıran şey, “(byte) 255 + (byte) 255” in atmadığıdır, çünkü işlenenler taşmadığı yerde “int” ye terfi edilirler. – CodesInChaos

1

Kolayca böyle yapın:

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

Ben sözdizimi hakkında emin değilim. doğrulayın. bayt ve sbyte bellekte aynı uzunluğa sahip ve bellek temsilini değiştirmek gerek kalmadan dönüştürülebilir çünkü

+1

Bu çalışır. Ama 1) 'ConvertAll' daha hızlıdır ve okunabilir olarak 2) Ben işaretlenmemiş ((sbyte) b)' yi tercih ederim. Detaylar için @ Sepehr'in cevabına bakınız. – CodesInChaos

2

Buffer.BlockCopy nasıl kullanılır? Bu cevaba ilişkin iyi şey, bayt bazında bayt bazında kontrol yapılmasını önlemektir. Bu cevapla ilgili kötü olan şey, bayt bazında bayt bazında kontrol yapılmasını önlemektir.

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

Bu sadece kopyalar bayt, byte.MaxValue Yukarıdaki değerler negatif sbyte değerine sahip olacaktır.

İki satırlık kod alır, ancak hızlı olmalıdır.

+0

'@' 'a gerek yok. "imzalı"/"imzasız", C# anahtar kelimeler değildir. – CodesInChaos

+0

@CodesInChaos SO beni yoldan çıkardı. – Jodrell