IEnumerable <T> Using ToArray - is it a copy or a pointer?

I am parsing an arbitrary array of length bytes that will be passed to several different parses. Each parser creates the header and payload of the packet in the same way as any regular encapsulation.

My problem is how encapsulation contains the payload of an array of packet bytes. Let's say I have a 100-byte array with three levels of encapsulation. Three packet objects will be created, and I want to set the payload of these packets to the appropriate position in the packet byte array.

For example, suppose the payload size is 20 for all levels, then imagine what it has public byte[] Payloadfor each object. However, the problem is that this one byte[] Payloadis a copy of the original 100 bytes, so I'm going to end up with 160 bytes in memory instead of 100.

If it were in C ++, I could just use a pointer, but I am writing this in C #.

So, I created the following class:

public class PayloadSegment<T> : IEnumerable<T>
{
    public readonly T[] Array;
    public readonly int Offset;
    public readonly int Count;

    public PayloadSegment(T[] array, int offset, int count)
    {
        this.Array = array;
        this.Offset = offset;
        this.Count = count;
    }

    public T this[int index]
    {
        get
        {
            if (index < 0 || index >= this.Count)
                throw new IndexOutOfRangeException();
            else
                return Array[Offset + index];
        }
        set
        {
            if (index < 0 || index >= this.Count)
                throw new IndexOutOfRangeException();
            else
                Array[Offset + index] = value;
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        for (int i = Offset; i < Offset + Count; i++)
            yield return Array[i];
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        IEnumerator<T> enumerator = this.GetEnumerator();
        while (enumerator.MoveNext())
        {
            yield return enumerator.Current;
        }
    }
}

That way, I can just refer to the position inside the original byte array, but use positional indexing. However, if I do something like:

 PayloadSegment<byte> something = new PayloadSegment<byte>(someArray, 5, 10);
 byte[] somethingArray = something.ToArray();

Will it somethingArraybe a copy of bytes or a reference to the source PayloadSegment(which, in turn, is a reference to the original byte array)?

EDIT: Actually, after rethinking this question, can I just use the new one MemoryStream(array, offset, length)?

+3
5

Enumerable.ToArray , , , . .NET Reflector , .

, , ICollection<T> ( Array), , , , List<T>, .

+5

, , ToArray , - . , , , , , . "ToNewArray", , .

"AsReadableArray", , . , , , ( ), . , .net ImmutableArray, , String [a String, , ImmutableArray (Of Char)] ReadableArray ( Array ImmutableArray ). , .Net 5.0, .

+1

. To<Type>,

+1

Since it byteis a value type, the array will store copies of the values, not pointers to them.
If you need the same behavior as the reference type, it is best to create a class that contains bytes, has a property, and can group other data and functionality.

0
source

This is a copy. It would be very unintuitive if I passed to something.ToArray()some method and the method changed the value somethingby changing the array!

0
source

Source: https://habr.com/ru/post/1742062/