質問

C#'s List<> has a set of CopyTo functions that will extract the contents of its internal array into another array using a fast memory block copy.

Is there a way to do this in reverse? It might look like...

var buffer = new List<byte>();
buffer.AddRange(afewbytes);
buffer.AddFromArray(myArray, startIndex, countBytesToCopy);
buffer.AddRange(afewmorebytes);

As my List is the List<byte> variety, I'd prefer to avoid a loop that copies byte by byte.

役に立ちましたか?

解決

The List<T>(IEnumerable<T>) constructor will use ICollection<T>.CopyTo if the collection implements ICollection<T>, which byte[] will do.

That's not going to help directly if you only want to extract part of the array, but you could create your own ByteArraySegment class implementing ICollection<byte> and implement the CopyTo operation using Buffer.BlockCopy or whatever:

public class ByteArraySegment : ICollection<byte>
{ 
    private readonly byte[] array;
    private readonly int start;
    private readonly int count;

    public ByteArraySegment(...)
    {
        // Obvious code
    }

    public void CopyTo(byte[] target, int index)
    { 
        Buffer.BlockCopy(array, start, target, index, count);
    }

    // Other ICollection<T> members
}

Then:

List<byte> bytes = new List<byte>(new ByteArraySegment(myArray, start, count));

(Or use AddRange which has the same optimization.)

他のヒント

To copy part of an array, wrap the array in an ArraySegment, specifying the index and count of the segment. Add the ArraySegment to the list with the list's AddRange method. AddRange will use ArraySegment.CopyTo, which uses Array.Copy, which is fast.

List.AddRange(myArray) should be pretty efficient.

From MSDN: "If the new Count (the current Count plus the size of the collection) will be greater than Capacity, the capacity of the List is increased by automatically reallocating the internal array to accommodate the new elements, and the existing elements are copied to the new array before the new elements are added."

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top