Reputation: 16168
I have following struct:
[StructLayout(LayoutKind.Sequential)]
struct Message
{
int Header;
int Data;
}
and I want to send it over the wire, without allocations (using SendAsync(ReadOnlyMemory<byte>)
) call.
How can I get the Memory<byte>
from given struct?
I ended up in having Span<byte>
, and then got stuck.
var message = new Message {
Header = 1, Data = 3
};
var bytes = MemoryMarshal.AsBytes(
MemoryMarshal.CreateReadOnlySpan(ref message, 1)
);
Is there any way how to put the struct directly into stream without any allocations?
I'm on netcoreapp2.1
.
Upvotes: 5
Views: 3211
Reputation: 1062745
Something like:
Span<Message> valSpan = stackalloc Message[1];
valSpan[0] = new Message { Header = 123, Data = 456 };
Span<byte> bytes = MemoryMarshal.Cast<Message, byte>(valSpan); // has length 8
Note I'm using Span<T>
here. You can do mostly the same stuff with Memory<T>
if needed - but you need a backing array or similar, which will usually require an allocation - if not of the array, then of a custom MemoryManager<T>
:
var arr = new Message[1];
arr[0] = new Message { Header = 123, Data = 456 };
Memory<byte> bytes = MemoryMarshal.Cast<Message, byte>(arr); // has length 8
Essentially, you are very close here:
MemoryMarshal.CreateReadOnlySpan(ref message, 1)
The trick, though, is to use MemoryMarshal.Cast<TFrom, byte>(...)
to get a a span of bytes.
Upvotes: 4