Question

Through the travels in StackOverflow there are many usages of the ToList() extension method for an ICollection (or classes that derive from ICollection<T>).

I have pulled out the good ol' decompiler to have a look at how the ToList() extension method is executed and does it enumerate the collection at anytime. Going through the source I came across:

[__DynamicallyInvokable]
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    return new List<TSource>(source);
}

Now this is pretty straight forward, so the ToList() extension method just creates a new List<T> with the source object. Digging deeper into the List constructor shows this line.

ICollection<T> ts = collection as ICollection<T>;
//.. ommited code
ts.CopyTo(this._items, 0);

As you would, you would dig into the CopyTo method. This is where I got stuck. After all the digging through method calls we get to the final extern method call

[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[SecurityCritical]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);

My question is (although I cant seem to find it) does the ToList() extension method (ICollection<T>.CopyTo()) iterate through all objects of the Collection (Array) when executed?

Subquestion: Where can I find the source for the extern void Copy() above?

Edit: I have edited the question directly as I realized after that I am trying to get a specification on an Interface and not implementation. Sorry

Was it helpful?

Solution

My question is (although I cant seem to find it) does the ToList() extension method (ICollection<T>.CopyTo()) iterate through all objects of the Collection (Array) when executed?

No, it does not. It just copies the underlying array storage using Array.Copy.


Update

Just to make sure my answer is interpreted correctly. ToList() does not enumerate the source collection when it's being called directly on another List<T> or T[] array (or other collection which implements ICollection.CopyTo without enumerator).

When you call ToList<> e.g. on Enumerable.Range(0, 1000).ToList() there will be an enumeration. Enumeration will be also performed when you use any LINQ method, e.g. myList.Select(x => x.PropertyName).ToList() will cause enumeration.

End of update


void ICollection.CopyTo(Array array, int arrayIndex)
{
    if (array != null && array.Rank != 1)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
    }
    try
    {
        Array.Copy(this._items, 0, array, arrayIndex, this._size);
    }
    catch (ArrayTypeMismatchException)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
    }
}

which uses unmanaged c++ code to do that in efficient way:

This method is equivalent to the standard C/C++ function memmove, not memcpy.

from Array.Copy Method (Array, Array, Int32)

OTHER TIPS

does the ToList() extension method (ICollection.CopyTo()) iterate through all objects of the Collection

It depends on how ICollection<T> is implemented in particular class.

For example, List<T> implementation just copies array (without iteration), because internally List<T> uses array as a storage. But nothing prevents you (or someone else) to write implementation, which will iterate though the source collection.

Where can I find the source for the extern void Copy() above

methods, marked by MethodImpl(MethodImplOptions.InternalCall), are implemented in unmanaged C++ code. I'm not sure, that there are any opened sources for them. But I suppose, that, ultimately, there's something like memcpy(...).

extern it means that function will be implemented in outside of C# code. It could be implemented in C/C++. More detail :

extern keyword

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top