Domanda

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

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 sento come questo è così sbagliato ma non riesco a trovare niente di meglio modo di farlo. C'è un modo più semplice?

È stato utile?

Soluzione

BinaryWriter è molto efficiente:

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

Altri suggerimenti

Non è necessario inizializzare tmp ad un nuovo array. BitConverter.GetBytes crea un nuovo array e lo restituisce per voi. Non c'è molto che tu possa fare GetBytes ma è possibile utilizzare metodi come Buffer.BlockCopy per semplificare l'operazione di copia.

Se non stai facendo questo in una performance-critical di codice, si può andare un po 'LINQy e fare cose come:

IEnumerable<byte> 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 si conosce la dimensione in anticipo (avere un insieme di tipi di valore) si potrebbe usare una struct e assegnare i valori nella struct. Quindi utilizzare il codice unsafe per copiare i byte grezzi. Vorrei ancora consigliare contro di essa meno che non sia realmente necessario per scopi di velocità. E si potrebbe pensare che è 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;
}

Just po-shift ...

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

Questo significa anche che si è in completo controllo della endian-ness (in questo caso, little-endian)

È possibile rendere il codice un po 'più corto utilizzando Array.Copy, ma non non c'è alcun GetBytes sovraccarico o equivalente in BitConverter che pone il byte direttamente nel buffer.

BinaryWriter su un < a href = "http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx" rel = "nofollow noreferrer"> MemoryStream è ciò che si vuole?

Si noti che, adottando le convenzioni API di BitConverter che non ti piace, si sta facendo lo stesso problema per gli utenti della vostra classe. Invece, scrivere un metodo che accetta un BinaryWriter e serializza la classe in esso, questo si estende bene quando la classe è incorporato in qualche altro oggetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top