IEnumerable<T> ToArray usage, is it a copy or a pointer?

Posted by Daniel on Stack Overflow See other posts from Stack Overflow or by Daniel
Published on 2010-04-21T04:37:55Z Indexed on 2010/04/21 4:43 UTC
Read the original article Hit count: 264

Filed under:
|
|
|

I am parsing an arbitrary length byte array that is going to be passed around to a few different layers of parsing. Each parser creates a Header and a Packet payload just like any ordinary encapsulation. And my problem lies in how the encapsulation holds its packet byte array payload. Say i have a 100 byte array, and it has 3 levels of encapsulation. 3 packet objects will be created and i want to set the payload of these packets to the corresponding position in the byte array of the packet. For example lets say the payload size is 20 for all levels, then imagine it has a public byte[] Payload on each object. However the problem is that this byte[] Payload is 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 easily use a pointer however i'm 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;
        }
    }
}

This way i can simply reference a 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 the somethingArray be a copy of the bytes, or a reference to the original PayloadSegment which in turn is a reference to the original byte array?

Sorry it was hard to word this lol >_<

© Stack Overflow or respective owner

Related posts about c#

Related posts about array