Tolist()-- Does It Create a New List

ToList()-- does it create a new list?

Yes, ToList will create a new list, but because in this case MyObject is a reference type then the new list will contain references to the same objects as the original list.

Updating the SimpleInt property of an object referenced in the new list will also affect the equivalent object in the original list.

(If MyObject was declared as a struct rather than a class then the new list would contain copies of the elements in the original list, and updating a property of an element in the new list would not affect the equivalent element in the original list.)

Is a Linq-Query called toList() generating copies of the contained elements?

Remember that a Linq query is just a query - it is saying "if I ask for this data, here's what I want_. It does not hold any data but waits until you ask_ for the results (via foreach, ToList, ToArray, etc.)

The difference is you're not capturing the list returned by ToList in the first example. It's used by the ForEach call but the objects variable still holds a reference to the original query. When you ask for it again - it fetches the data again. When it fetches the data again, new objects are created.

So in that respect - yes ToList() creates a new list. It does not modify the object that it's called on to turn it into a list.

In your second example the objects variable holds a reference to the list generated from the query via ToList(), so when you modify them and return objects you're returning the same list.

Does tasks.ToList() create a list containing newly copied tasks or the list refers to the same tasks?


What happens [when we call ToList on a sequence of tasks]? Do we have two sets of tasks running separately? Or they point to the same tasks?

This is actually a good question, and it depends on the source sequence on which you call ToList. If temp is a collection of running tasks (as in your case), then ToList simply creates a copy of their references, meaning your new list would point to the same set of tasks.

However, if temp constitutes a sequence of tasks that have yet to be instantiated (due to deferred execution), then you would get a new set of tasks each time you call ToList. Here is a simple example (using ToArray, which has the same effect as ToList):

int count = 0;

var tasks = Enumerable.Range(0, 10).Select(_ =>
Task.Run(() => Interlocked.Increment(ref count)));

// tasks = tasks.ToArray(); // deferred vs. eager execution

Task.WaitAll(tasks.ToArray());
Task.WaitAll(tasks.ToArray());

Console.WriteLine(count);

If you run the code above, the final result will be 20, meaning that two batches of tasks were run (one for each ToArray call). However, if you uncomment the line that enables eager execution, the final result will become 10, indicating that the subsequent ToArray calls only copy the references, rather than spawn new tasks.

Does List T .ToList() enumerate the collection


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)

Dart: What is the difference between .toList() and casting as List

toList() is a method called on multiple types of objects and will gather all data from a data stream (or existing List) and create a new List object containing the data.

as List is a way to tell a given object (often dynamic) is in fact a List object on runtime. This is used if we cannot determined the type on compile type (e.g. if parsing JSON).

Example

We decodes some JSON and tell Dart that we can guarantee that the type on runtime will be List by using as List.

import 'dart:convert';

void main() {
final list = json.decode('[1, 2, 3]') as List;
print(list); // [1, 2, 3]

final newList = list.cast<int>().map((e) => e * 2).toList();
print(newList); // [2, 4, 6]
}

We then use .map to double each value and want to convert this into a new list by usin toList().

To ToList() or not to ToList()?

Yes there is a difference and it can be significant.

ToList() will iterate and append each iterated item into a new list. This has the effect of creating a temporary list which consumes memory.

Sometimes you might want to take the memory penalty especially if you intend on iterating the list multiple times and the original list is not in memory.

In your particular example using the ToList() you actually end up iterating twice - once to build the list and a second time in your foreach. Depending on the size of the list and your application this may or may not be a concern.



Related Topics



Leave a reply



Submit