For a network protocol implementation I want to make use of the new Memory
and Span
classes to achieve zero-copy of the buffer while accessing the data through a struct
.
I have the following contrived example:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Data
{
public int IntValue;
public short ShortValue;
public byte ByteValue;
}
static void Prepare()
{
var buffer = new byte[1024];
var dSpan = MemoryMarshal.Cast<byte, Data>(buffer);
ref var d = ref dSpan[0];
d.ByteValue = 1;
d.ShortValue = (2 << 8) + 3;
d.IntValue = (4 << 24) + (5 << 16) + (6 << 8) + 7;
}
The result is that buffer
is filled with 7, 6, 5, 4, 3, 2, 1
, which is as desired, but I can hardly imagine that MemoryMarshal.Cast
is the only way (bar anything requiring the unsafe
keyword) to do this. I tried some other methods, but I can't figure out how to use them with either a ref struct
(which can't be used as generic type argument) or how to get a struct that's in the actual buffer and not a copy (on which any mutations made are not reflected in the buffer).
Is there a some easier way to get this mutable struct from the buffer?
Oof. It looks like
MemoryMarshal.Cast
is what used to be theNonPortableCast
extension method (from: this commit), in which case - yes, that's the appropriate way to thunk between layouts of spans, most commonly (but not exclusively) like in this case - betweenbyte
and somestruct
.