C’è un modo meno doloroso per GetBytes per un buffer che non inizia a 0?

Sto avendo a che fare con i byte grezzi in un progetto e ho bisogno di fare fondamentalmente qualcosa di simile

byte[] ToBytes(){ byte[] buffer=new byte[somelength]; byte[] tmp; tmp=BitConverter.GetBytes(SomeShort); buffer[0]=tmp[0]; buffer[1]=tmp[1]; tmp=BitConverter.GetBytes(SomeOtherShort); buffer[2]=tmp[0]; buffer[3]=tmp[1]; } 

Mi sembra che sia così sbagliato, ma non riesco a trovare un modo migliore per farlo. C’è un modo più semplice?

BinaryWriter è molto efficiente:

  byte[] ToBytes() { var ms = new MemoryStream(somelength); var bw = new BinaryWriter(ms); bw.Write(SomeShort); bw.Write(SomeOtherShort); return ms.ToArray(); } 

Non è necessario inizializzare tmp in un nuovo array. BitConverter.GetBytes crea un nuovo array e lo restituisce per te. Non c’è molto che puoi fare su GetBytes ma puoi usare metodi come Buffer.BlockCopy per semplificare l’operazione di copia.

Se non lo fai in un pezzo di codice critico per le prestazioni, puoi fare un po ‘LINQy e fare cose come:

 IEnumerable bytes = BitConverter.GetBytes(first); bytes = bytes.Concat(BitConverter.GetBytes(second)); bytes = bytes.Concat(BitConverter.GetBytes(third)); // ... so on; you can chain the calls too return bytes.ToArray(); 

Se conosci la dimensione in anticipo (hai un set di tipi di valore) puoi usare una struct e assegnare i tuoi valori nella struct. Quindi utilizzare il codice unsafe per copiare i byte non elaborati. Continuerò a sconsigliarlo a meno che non sia davvero necessario per scopi di velocità. E potresti pensare che sia doloroso 🙂

 private struct MyStruct { public short A; public short B; public MyStruct(short a, short b) { A = a; B = b; } } private unsafe byte[] UnsafeStruct(MyStruct myStruct) { byte[] buffer = new byte[4]; // where 4 is the size of the struct fixed (byte* ptr = buffer) { *((MyStruct*)ptr) = myStruct; } return buffer; } 

Solo un po ‘di spostamento …

 buffer[0]=(byte)SomeShort; buffer[1]=(byte)(SomeShort >> 8); buffer[2]=(byte)SomeOtherShort; buffer[3]=(byte)(SomeOtherShort >> 8); 

Questo significa anche che hai il controllo completo dell’endianità (in questo caso, little-endian)

Puoi rendere il tuo codice un po ‘più breve usando Array.Copy, ma non c’è nessun overload GetBytes o equivalente in BitConverter che mette i byte direttamente nel tuo buffer.

Forse BinaryWriter su MemoryStream è quello che vuoi?

Nota che adottando le convenzioni API di BitConverter che non ti piacciono, stai causando lo stesso problema agli utenti della tua class. Invece, scrivi un metodo che accetta un BinaryWriter e serializza la tua class in esso, questo si estende bene quando la tua class è incorporata in qualche altro object.