C# Convert ReadOnlyMemory<byte> to byte[]
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, converting ReadOnlyMemory<byte> to byte[] is easy, but the right method depends on whether you want a copy or you want to reuse an underlying array. The safest general answer is ToArray(), while zero-copy access is only possible in some cases and requires more care.
The Simple and Safe Approach
If you need a real byte array and do not care about allocating a copy, use ToArray():
This always creates a new byte[]. That means:
- it is safe
- it works regardless of how the memory was created
- changes to the new array do not affect the original source
For most application code, this is the best default.
Why ReadOnlyMemory<byte> Exists
ReadOnlyMemory<byte> is often used to pass byte data around without forcing immediate copies. It can represent:
- a full array
- a slice of an array
- memory from other sources exposed through the memory abstractions
That flexibility is exactly why converting to byte[] is not always free. A byte array requires one concrete owned buffer, while ReadOnlyMemory<byte> is more general.
Zero-Copy Access When the Memory Is Array-Backed
If the memory came from an array, you may be able to get access to that underlying array using MemoryMarshal.TryGetArray.
This does not guarantee that the returned segment.Array is exactly the logical slice you want. You may need to respect Offset and Count.
That is why treating segment.Array as the final answer can be wrong if the ReadOnlyMemory<byte> is only a slice of a larger array.
Handling Slices Correctly
Consider this:
The underlying array is still the full source, not only the logical three-byte slice. If you need an exact standalone array for that slice, ToArray() is still the cleanest choice.
When You Should Avoid Converting
Sometimes the best answer is not to convert at all. Many modern .NET APIs accept ReadOnlyMemory<byte> or ReadOnlySpan<byte>. If the next API can already consume memory safely, keeping the existing type avoids unnecessary allocation.
That can matter in:
- high-throughput networking
- parsing pipelines
- serialization code
- streaming systems
The need to convert often comes from an older API boundary rather than from the data itself.
A Copy into a Preallocated Array
If you want control over allocation, you can create the destination yourself and copy into it:
This still copies, but it lets you decide where the destination buffer comes from.
Common Pitfalls
The most common mistake is assuming that TryGetArray always returns a perfectly sized standalone array. It does not; it may expose a larger array plus an offset and count.
Another issue is converting automatically with ToArray() in hot paths without measuring allocations. It is correct, but it may be more expensive than necessary if the next API already accepts spans or memory.
A third pitfall is forgetting that ReadOnlyMemory<byte> being read-only does not guarantee the underlying array can never change elsewhere. Read-only describes the view, not universal immutability.
Summary
- Use
ToArray()when you need a simple, exactbyte[]. - '
MemoryMarshal.TryGetArraycan avoid copying only when the memory is array-backed.' - Respect
ArraySegment.OffsetandCountif you expose the underlying array. - Prefer staying in
ReadOnlyMemory<byte>orReadOnlySpan<byte>when downstream APIs allow it. - Choose the conversion method based on whether correctness, allocation cost, or zero-copy access matters most.

