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
, notmemcpy.
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
.Net Out of Memory Exception - Used 1.3Gb But Have 16Gb Installed
C# Listview, How to Add Items to Columns 2, 3 and 4 etc
Convert an Image (Selected by Path) to Base64 String
How to Enable Http Put and Delete for ASP.NET MVC in Iis
Differencebetween Await Task<T> and Task<T>.Result
How to Count Duplicates in List with Linq
Calling C# Code from C++, But Executeindefaultappdomain() Is Too Limited
What Is the C# Version of Vb.Net's Inputdialog
Reading Datetime Value from Excel Sheet
String.Split - by Multiple Character Delimiter
Why Implement Interface Explicitly
Checking for Null Before Event Dispatching... Thread Safe
Round a Double to X Significant Figures
How to Create/Edit a Manifest File
Change Attribute's Parameter at Runtime
How to Enumerate All Windows Belonging to a Particular Process Using .Net