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
The tolist() function is used to convert a given array to an ordinary list with the same items, elements, or values.
The ToList() method is always creating an instance of List<T> object in which on some cases, not really necessary. If the current instance of the IEnumerable is already a List<T> , then, the creation is not needed, but instead, simply cast it back to that specific type.
The collect() method (along with toList() method) is used to clone a list. Approach: Create a class. Create a list of the class objects from an array using the asList method.
This extension method converts collections (IEnumerables) to List instances. It is fast and easy-to-remember. It returns a List instance with the appropriate elements.
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
, notmemcpy.
from
Array.Copy
Method (Array, Array, Int32)
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(...)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With