Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does List<T>.ToList() enumerate the collection

Tags:

c#

icollection

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

like image 794
Nico Avatar asked Jan 09 '14 06:01

Nico


People also ask

What does ToList () do?

The tolist() function is used to convert a given array to an ordinary list with the same items, elements, or values.

Does ToList always create a new List?

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.

Does ToList clone a List?

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.

Why do we use ToList () in C#?

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.


2 Answers

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)

like image 77
MarcinJuraszek Avatar answered Sep 16 '22 15:09

MarcinJuraszek


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(...).

like image 31
Dennis Avatar answered Sep 18 '22 15:09

Dennis