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
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 anotherList<T>
orT[]
array (or other collection which implementsICollection.CopyTo
without enumerator).When you call
ToList<>
e.g. onEnumerable.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
which uses unmanaged c++ code to do that in efficient way: