Is there a way in C# to convert a plain byte array to an object?
e.g given this class:
class Data
{
public int _int1;
public int _int2;
public short _short1;
public long _long1;
}
I want to basically be able to do something like this:
var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
var obj = (Data)bytes;
You could try marshalling:
Declare the layout of your class as Sequential (and note that you will need to use Pack = 1):
[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
public int _int1;
public int _int2;
public short _short1;
public long _long1;
}
Marshal the bytes into a new instance of the Data class:
var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
gcHandle.Free();
// Now data should contain the correct values.
Console.WriteLine(data._int1); // Prints 1
Console.WriteLine(data._int2); // Prints 2
Console.WriteLine(data._short1); // Prints 3
Console.WriteLine(data._long1); // Prints 4
For convenience you could write a static method on Data to do the conversion:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
public int _int1;
public int _int2;
public short _short1;
public long _long1;
public static Data FromBytes(byte[] bytes)
{
GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
gcHandle.Free();
return data;
}
}
...
var data = Data.FromBytes(new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0});
If you really wanted to you could write an explicit operator to convert from an array of bytes, to get the syntax in your OP. I would suggest just using Data.FromBytes() which is going to be a lot clearer IMO.
Still, just for completeness:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
public int _int1;
public int _int2;
public short _short1;
public long _long1;
public static explicit operator Data(byte[] bytes)
{
GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
gcHandle.Free();
return data;
}
}
...
var data = (Data)new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With