2009-07-01 25 views
6

que quiero hacer el equivalente a esto:cómo convertir un tipo de valor a byte [] en C#?

byte[] byteArray; 
enum commands : byte {one, two}; 
commands content = one; 
byteArray = (byte*)&content; 

sí, es un byte, pero considero que quiero cambiar en el futuro? ¿Cómo hago que ByteArray contenga contenido? (No me importa copiarlo).

Respuesta

11

La clase BitConverter es lo que estás buscando. Ejemplo:

int input = 123; 
byte[] output = BitConverter.GetBytes(input); 

Si su enumeración era conocido por ser un tipo Int32 derivada, simplemente podría emitir sus valores en primer lugar:

BitConverter.GetBytes((int)commands.one); 
+0

todavía tiene que echarlo, pero es mejor. ¡Gracias! – Nefzen

+0

Si los tipos primitivos no son suficientes, consulte mi respuesta sobre cómo convertir cualquier tipo de valor. – OregonGhost

16

para convertir cualquier tipo de valor (no sólo los tipos primitivos) a las matrices de bytes y viceversa:

public T FromByteArray<T>(byte[] rawValue) 
    { 
     GCHandle handle = GCHandle.Alloc(rawValue, GCHandleType.Pinned); 
     T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 
     handle.Free(); 
     return structure; 
    } 

    public byte[] ToByteArray(object value, int maxLength) 
    { 
     int rawsize = Marshal.SizeOf(value); 
     byte[] rawdata = new byte[rawsize]; 
     GCHandle handle = 
      GCHandle.Alloc(rawdata, 
      GCHandleType.Pinned); 
     Marshal.StructureToPtr(value, 
      handle.AddrOfPinnedObject(), 
      false); 
     handle.Free(); 
     if (maxLength < rawdata.Length) { 
      byte[] temp = new byte[maxLength]; 
      Array.Copy(rawdata, temp, maxLength); 
      return temp; 
     } else { 
      return rawdata; 
     } 
    } 
+0

Muy bien, exactamente lo que he estado buscando, esta debería ser la respuesta correcta ya que BitConverter no funciona para todos los tipos – Qwerty01

+0

BitConverter es * consistente * en todos los tipos admitidos en todas las plataformas donde se implementa. Debe tenerse en cuenta que los bytes que obtiene de este método NO son portátiles en diferentes plataformas y es posible que ni siquiera funcionen en diferentes versiones de .NET Framework, por lo que no es adecuado para la serialización a menos que pueda garantizar el marco .NET la versión es idéntica en el extremo de serialización y deserialización. Podría hacer que la actualización de su aplicación sea bastante difícil. –

+0

@MikeMarynowski: Acabo de ver tu comentario. No sé a qué te refieres. Este código NO involucra serialización binaria, usa clasificación, y el punto de clasificación es obtener exactamente los bytes que está solicitando para llamar a las API de P/Invoke o COM. Con este método, obtienes exactamente los bytes que definiste en tu estructura (con StructLayoutAttribute y similares), sin importar la versión .NET o la plataforma. – OregonGhost

1

Para cualquiera que esté interesado en la forma en que funciona sin necesidad de utilizar BitConverter puede hacerlo de esta manera:

// Convert double to byte[] 
public unsafe byte[] pack(double d) { 
    byte[] packed = new byte[8]; // There are 8 bytes in a double 
    void* ptr = &d; // Get a reference to the memory containing the double 
    for (int i = 0; i < 8; i++) { // Each one of the 8 bytes needs to be added to the byte array 
     packed[i] = (byte)(*(UInt64 *)ptr >> (8 * i)); // Bit shift so that each chunk of 8 bits (1 byte) is cast as a byte and added to array 
    } 
    return packed; 
} 

// Convert byte[] to double 
public unsafe double unpackDouble(byte[] data) { 
    double unpacked = 0.0; // Prepare a chunk of memory ready for the double 
    void* ptr = &unpacked; // Reference the double memory 
    for (int i = 0; i < data.Length; i++) { 
     *(UInt64 *)ptr |= ((UInt64)data[i] << (8 * i)); // Get the bits into the right place and OR into the double 
    } 
    return unpacked; 
} 

En realidad, es mucho más fácil y más seguro usar BitConverter, pero es divertido saberlo.

0

También puede simplemente hacer un molde simple y pasarlo al constructor de la matriz. También es similar en longitud al método BitConverter.

new[] { (byte)mode }