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 the NonPortableCast 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 - between byte and some struct.
来源:https://stackoverflow.com/questions/50546782/proper-way-to-get-a-mutable-struct-for-memorybyte-spanbyte