You can look into the Microsoft .NET assemblies using a reflector program, such as ILSpy.
This tells me that the implementation of System.Linq.Enumerable::ToArray() is:
public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
{
// ...
return new Buffer<TSource>(source).ToArray();
}
And the constructor of the internal struct Buffer<T> does:
- If the source enumerable implements
ICollection<T>, then:
- allocate an array of
Count elements, and
- use
CopyTo() to copy the collection into the array.
- Otherwise:
- allocate an array of 4 elements, and
- start enumerating the IEnumerable, storing each value in the array.
- Is the array too small?
- Create a new array that has twice the size of the old one,
- and copy the old array's content into the new one,
- then use the new array instead, and continue.
And Buffer<T>.ToArray() simply returns the inner array if its size matches the number of elements in it; otherwise copies the inner array to a new array with the exact size.
Note that this Buffer<T> class is internal and not related to the Buffer class you mentioned.
All copying is done using Array.Copy().
So, to conclude: all copying is done using Array.Copy() and there is no optimization for byte arrays. But I don't know whether it is slower than Buffer.BlockCopy(). The only way to know is to measure.
Buffer.BlockCopyin the first place?byte[]of the length of the source, then copy the source to the new array. It's just a DRY function so I don't have to write the 3 lines of code everywhere I need to copy a buffer.