Reputation: 2860
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?
Upvotes: 3
Views: 2042
Reputation: 152566
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.
Upvotes: 6
Reputation: 23506
In your first code sample the objects.ToList()
is in fact creating a new object of type List
you're working on with your ForEach
. After the ForEach
is done you're still just returning your IEnumerable
and the list you actually wanted to return will be gone.
By assigning the LINQ query with a ToList()
to the object
variable, you're using the newly created list in your ForEach
.
Upvotes: 0