How do I get a byte array fro an ArraySegment

Viewed 1480

If someone passes me an ArraySegment<byte> foo and this segment points into a larger buffer, what's the idiomatic way to copy this segment into a fresh new byte[] ?

I tried accessing at foo.Array but this seems to point to the beginning of the larger buffer, not the beginning of the segment.

e.g. the larger buffer could be "blahfoobar" and the ArraySegment points to "foo". I want to get a byte[] with just "foo".

I'm sure it's dead simple, but coming from C++, I can't figure the lingo used in c#.

2 Answers

Creating a new array would be entirely to miss the point of the API, which is to represent a pre-existing segment. In more recent .NET version, Span<T> and ReadOnlySpan<T> would be better choices - they allow you to create an abstraction over contiguous memory without needing the consumer to worry about the Offset etc, as that can be imposed externally. There are constructors on Span<T> and ReadOnlySpan<T> that allow you to deal with aspects so that the consumer never needs to know about them, with the knowledge that on recent runtimes: the JIT will elide bounds checks on spans.

using System;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        private static readonly byte[] _initArray = Encoding.ASCII.GetBytes("blahfoobar");

        //private static byte[] ArraySegmentToArray(ArraySegment<byte> segment)
        //{
        //    var result = new byte[segment.Count];

        //    for (int i = 0; i < segment.Count; i++)
        //    {
        //        result[i] = segment.Array[i + segment.Offset];
        //    }

        //    return result;
        //}

        private static byte[] ArraySegmentToArray(ArraySegment<byte> segment) =>
            segment.ToArray();

        static void Main(string[] args)
        {
            var segFoo = new ArraySegment<byte>(_initArray, 4, 3);

            var test = ArraySegmentToArray(segFoo);
        }
    }
}

But of course it is bad practice. Because if you turn segment to array you allocate memory, and if you use ArraySegment stuff as pointers , you don't allocate memory, actually, that is the main idea of using ArraySegment, because if not the array could be provided as parameters :) P.S. Commented code just for understanding the idea.

Related