C# Convert ReadOnlyMemory<byte> to byte[]

C#Rabbitmq

C# Problem Overview


Given ReadOnlyMemory Struct I want to convert the stream into a string

I have the following code:

var body = ea.Body; //ea.Body is of Type ReadOnlyMemory<byte>
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);

And it gives the following error. I am using the latest C# with .NET CORE 3.1

enter image description here

Which is funny because I am literally copy pasting the Hello World example of a major product called RabbitMQ and it doesn't compile.

C# Solutions


Solution 1 - C#

You cannot drop a thing that's read-only into a slot typed as byte[], because byte[]s are writable and that would defeat the purpose. It looks like RabbitMQ changed their API in February and perhaps forgot to update the sample code.

A quick workaround is to use .ToArray():

var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);

Edit: Since this was accepted, I'll amend it with the better solution posed by Dmitry and zenseb which is to use .Span:

var body = ea.Body.Span;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);

Solution 2 - C#

Use Span property to convert message to string without additional memory allocation

var body = ea.Body; //ea.Body is of Type ReadOnlyMemory<byte>
var message = Encoding.UTF8.GetString(body.Span);
Console.WriteLine(" [x] Received {0}", message);

Solution 3 - C#

You need to use the Spanproperty.

var data = new byte[] { 72, 101, 108, 108, 111 };
var body = new ReadOnlyMemory<byte>(data);
var text = Encoding.UTF8.GetString(body.Span);

Console.WriteLine(text);

Encoding.UTF8.GetString has an overload for ReadOnlySpan<byte>. You can read more here

Solution 4 - C#

I updated the RabbitMQ.Client package and had the same problem at my Consumer_Received method:

private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
        // Code

I checked BasicDeliverEventArgs and saw that Body is now a ReadOnlyMemory type:
public ReadOnlyMemory<byte> Body { get; set; }

As Jeff said, RabbitMQ changed their API, so I think this changed from previous tutorials we had on internet.

To fix, I only had to transform my Body message into a Array (into Consumer_Received method):
var message = Encoding.UTF8.GetString(e.Body.ToArray());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJebathonView Question on Stackoverflow
Solution 1 - C#JeffView Answer on Stackoverflow
Solution 2 - C#Dmitry KolchevView Answer on Stackoverflow
Solution 3 - C#zansebView Answer on Stackoverflow
Solution 4 - C#Isac MouraView Answer on Stackoverflow