using System.Runtime.InteropServices;
const int PREFIX_BYTE_COUNT = 29;
const int POSTFIX_BYTE_COUNT = 17;
var bytes = toByteArray(PREFIX_BYTE_COUNT, POSTFIX_BYTE_COUNT, ref demo1, ref demo2, ref demo3);
consumeStructs(PREFIX_BYTE_COUNT, bytes);
static byte[] toByteArray(int prefixByteCount, int postfixByteCount, ref Demo1 demo1, ref Demo2 demo2, ref Demo3 demo3)
var demo1Bytes = AsSpan(ref demo1);
var demo2Bytes = AsSpan(ref demo2);
var demo3Bytes = AsSpan(ref demo3);
var prefixBytes = Enumerable.Repeat((byte)0, prefixByteCount);
var postfixBytes = Enumerable.Repeat((byte)0, postfixByteCount);
.Concat(demo1Bytes.ToArray())
.Concat(demo2Bytes.ToArray())
.Concat(demo3Bytes.ToArray())
static void consumeStructs(int prefixByteCount, byte[] data)
var demo1Bytes = new Span<byte>(data, prefixByteCount, Marshal.SizeOf<Demo1>());
var demo2Bytes = new Span<byte>(data, prefixByteCount + Marshal.SizeOf<Demo1>(), Marshal.SizeOf<Demo2>());
var demo3Bytes = new Span<byte>(data, prefixByteCount + Marshal.SizeOf<Demo1>() + Marshal.SizeOf<Demo2>(), Marshal.SizeOf<Demo3>());
ref var demo1Ref = ref MemoryMarshal.AsRef<Demo1>(demo1Bytes);
ref var demo2Ref = ref MemoryMarshal.AsRef<Demo2>(demo2Bytes);
ref var demo3Ref = ref MemoryMarshal.AsRef<Demo3>(demo3Bytes);
Console.WriteLine(demo1Ref);
Console.WriteLine(demo2Ref);
Console.WriteLine(demo3Ref);
Console.WriteLine("Modifying first byte of Demo2 struct in byte buffer.");
data[prefixByteCount + Marshal.SizeOf<Demo1>()] = (byte)'*';
Console.WriteLine(demo2Ref);
public static Span<byte> AsSpan<T>(ref T val) where T : unmanaged
var valSpan = MemoryMarshal.CreateSpan(ref val, 1);
return MemoryMarshal.Cast<T, byte>(valSpan);
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public double DoubleValue;
public override string ToString()
return $"byte = {BoolValue}, double = {DoubleValue}";
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
public double DoubleValue;
public override string ToString()
return $"char = {CharValue}, short = {ShortValue}, int = {IntValue}, long = {LongValue}, float = {FloatValue}, double = {DoubleValue}";
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public override string ToString()
return $"byte = {ByteValue}, float = {FloatValue}";