Проблема в том, что 3 байта - это действительно неудобное число, так как нет доступного размера регистра в 3 байта. Один из способов - разделить его на 2 байта и 1 байт и |
их вместе:
var arr = new byte[] { 5, 20, 10 };
var span = arr.AsSpan();
var val = MemoryMarshal.Cast<byte, ushort>(span.Slice(1))[0] << 16 | (span[0] << 8);
Ассемблерный код, сгенерированный JIT, представляет собой просто прямые копии (lea
) и сдвиги (shr
), как и ожидалось, это просто синтаксис C#, который немного громоздок.