Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Why does IEnumerable.ToList() on an existing List create new array

Just out of curiosity, why does calling IEnumerable.ToList() on an existing List not return the same instance? Same applies to IEnuerable.ToArray(). Would this not be better from a memory consumption standpoint?

I ran the following quick test:

  var things= new List<Thing>( new [] {new Thing(), new Thing()});
        Console.WriteLine(things.GetHashCode());

        things= things.ToList();
        Console.WriteLine(things.GetHashCode());

And I get different object instances. Why not simply the same instances?

like image 330
Klaus Nji Avatar asked Nov 28 '11 23:11

Klaus Nji


People also ask

Does ToList always create a new List?

The references are copied, but the new references still point to the same instances as the original references point to. When you think of it, ToList cannot create any new MyObject() when MyObject is a class type.

What does ToList () do C#?

The ToList<TSource>(IEnumerable<TSource>) method forces immediate query evaluation and returns a List<T> that contains the query results. You can append this method to your query in order to obtain a cached copy of the query results.

Does ToList clone a List?

We use ToList() method to copy or clone the list to another list as shown in the below example. The ToList() returns the new List<T> that containing the original list.

Does ToList decrease performance?

ToList() does have a performance impact, it is an O(n) operation though it will likely only require attention in performance critical operations.


2 Answers

This is intentionally done so to enable for the "copy list" scenario.

For example, it I do foreach( var a in list ) list.Remove(a), I will get an exception saying that "the collection has been modified" while the enumeration was in progress.

To fix this, I do: foreach( var a in list.ToList() ) list.Remove(a).

If you want the semantics along the lines of "convert to list if it is not one already", you'll have to handle it yourself. In fact, you could actually write a neat extension method for this:

public static IList<T> ToListIfNotAlready( this IEnumerable<T> source )
{
     var list = source as IList<T>;
     return list == null ? source.ToList() : list;
}

Yes, it could have been the other way around, but the LINQ designers chose this approach, and had every right to do so, as neither approach has distinct advantage in general case.

like image 154
Fyodor Soikin Avatar answered Oct 25 '22 06:10

Fyodor Soikin


Because you can't modify the contents of an enumeration while it's being enumerated, there are times when you need to create a copy of the list so you can iterate over one copy and modify the other. ToList() is defined as returning a new list which is independent of the original list.

like image 31
dthorpe Avatar answered Oct 25 '22 07:10

dthorpe