# Better way to Read /Write Memory<byte> to/from POCO

I am communicating with a machine that sends/received structured binary data to my netcore service. The machine supplier's new library uses Memory in their library's API.

I have written the following code for Ser/Des which works, but seems verbose. I know I can wrap some of this in methods/helpers, but it feels cumbersome compared to the "old" Streams & BinaryWriter/BinaryReader approach.

Is there a better way to approach this? A better part of the framework or technique I should be using?

### Deserialising from Memory:

public void Read(Memory<byte> data)
{
if (data.Length < StaticSize) // StaticSize = 56. Defined by machine's struct.
throw new ArgumentOutOfRangeException($"Span length too small. Minimum: {StaticSize}, Received: {data.Length}."); var s = data.Span; MemoryMarshal.TryRead<bool>(s.Slice(0, 1), out _forward); MemoryMarshal.TryRead<bool>(s.Slice(1, 2), out _reverse); SomeString = Encoding.UTF8.GetString(s.Slice(2, 22)).Replace("\0", string.Empty); Dynamics = new TcDynamics(data.Slice(24)); // "TcDynamics" object de-serialized in same manner as this. }  ### Serialising to Memory:  public void Write(Memory<byte> data) { if (data.Length < StaticSize) // StaticSize = 56. Defined by machine's struct. throw new ArgumentOutOfRangeException($"Span length too small. Minimum: {StaticSize}, Received: {data.Length}.");

var s = data.Span;
MemoryMarshal.TryWrite<bool>(s.Slice(0, 1), ref _forward);
MemoryMarshal.TryWrite<bool>(s.Slice(1, 2), ref _reverse);
Encoding.UTF8.GetBytes(_someString).CopyTo(s.Slice(2,22)); // Strings are fixed length (21 + termination).
Dynamics.Write(data.Slice(24)); // "TcDynamics" object serialized in same manner as this.
}

• Why do you think it is cumbersome? Have you considered SequenceReader and PipeWriter 1, 2 – Peter Csala Jul 2 '20 at 9:47
• @PeterCsala, when using a binary reader, I could just call something like: myDouble= reader.ReadDouble(); or writer.Write(myDouble); writer.Write(myString, lengthInBytes); I know I can create that myself using Facade pattern to hide away most of the above, but thought there would be a better way somewhere else. I will have a look at your suggestions, thank you. – Mark Lazz Jul 2 '20 at 14:27
• Yes, I agree that those abstractions make the usage more convenient. Memory, Span and ReadOnlySpanwere designed to work mainly with byteand char types. – Peter Csala Jul 3 '20 at 8:05
• If the data structure in data is the same, couldn't you then load a MemoryStream with the data, and then use a `BinaryReader-/Writer as you did before? – user73941 Jul 5 '20 at 10:59
• @HenrikHansen, I couldn't figure out how to do this without copying data into the Memory Stream. That feels like I'm losing one of the efficiency benefits of Memory<T>. I.e. I'd be creating memory in the stream to copy the memory<> into. Then the read operation would be copying to variable. The last copy is unavoidable, but the interim one I was hoping to avoid with these new classes. have I misunderstood the MemoryStream WriteAsync docs? – Mark Lazz Jul 5 '20 at 14:53