Вот так?
byte[] data = new byte[16];
// 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
Console.WriteLine(BitConverter.ToString(data));
ref SomeStruct typed = ref Unsafe.As<byte, SomeStruct>(ref data[4]);
typed.F1 = 42;
typed.F2 = 3;
typed.F3 = 9;
// 00-00-00-00-2A-00-00-00-03-00-00-00-09-00-00-00
Console.WriteLine(BitConverter.ToString(data));
Приводит данные из середины массива байтов, используя ref-local, который является «внутренним управляемым указателем» на данные. Нулевые копии.
Если вам нужно несколько элементов (например, как будет работать вектор), вы можете сделать то же самое с промежутками и MemoryMarshal.Cast
Обратите внимание, что он использует правила байта процессора для элементы - в моем случае с прямым порядком байтов.
Для промежутков:
byte[] data = new byte[256];
// create a span of some of it
var span = new Span<byte>(data, 4, 128);
// now coerce the span
var typed = MemoryMarshal.Cast<byte, SomeStruct>(span);
Console.WriteLine(typed.Length); // 10 of them fit
typed[3].F1 = 3; // etc