I encountered a (for me) strange behaviour. Here is the code:
var objects = from i in items
//some calculations
select something;
// other calculations
objects.ToList().ForEach(x => {
//some calculations
x.Property = "some text"
});
return objects;
First I generate a IEnumerable, it is a query to the db, I skipped the details.
Then I have to do other calculations and at the end I iterate over my objects to set a further parameter. Running this code, once the IEnumerable objects is returned, their Property is not set.
Otherwise if I move the ToList() in the Linq expression as followed, the Property is set:
var objects = (from i in items
//some calculations
select something).ToList();
// other calculations
objects.ForEach(x => {
//some calculations
x.Property = "some text"
});
return objects;
As far I know, the objects are not copied, but referenced...right? What does behind the apparently codes happen? What is the difference?
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.
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