Modifying a property of an object inside of a foreach loop doesn't work?
This is puzzling me. I'm using PetaPoco to retreive some values from a database, and then looping over them and retrieving a value to assign to one of the properties of each object.
public IEnumerable<RetreaveIndex> FillResults(IEnumerable<RetreaveIndex> results)
{
//add the associated users
foreach (RetreaveIndex index in results)
{
index.AssociatedUsers = _registeredUserDao.GetUsersByIndex(index).ToList();
}
return results;
}
When I set a breakpoint during the foreach loop, the AssociatedUsers property is being set correctly.
开发者_运维百科but then in a breakpoint at the end of the loop, it didn't save it?
I'm confused, shouldn't Index be a reference to a place in memory which is being modified? It's an object after all. What am I missing here?
What is the IEnumerable implementation? Could it be returning a copy of the object?
Is RetreaveIndex a struct, and thus a value type? If so, then the variable
index
will be a copy.
Depending on how the IEnumerable passed in is implemented, it has no requirement that the next time it enumerates over the data that it return the same objects as before. Try turning the IEnumerable into a List before the foreach loop and return that insead.
From the project web site:
Query vs Fetch
The Database class has two methods for retrieving records Query and Fetch. These are pretty much identical except Fetch returns a List<> of POCO's whereas Query uses yield return to iterate over the results without loading the whole set into memory.
In other words, Query
re-loads the values from the backing store each time, and doesn't keep an item around after it's been enumerated. When you go look at an item again after the end of your loop, that item is re-loaded from the backing store.
Actually, what is going on is that you are misinterpreting the output from the yield return
syntax.
What's happening is that as you iterate over the IEnumerable
returned from yield return
, the code after that yield return
is being executed. In technical terms, yield return
is doing lazy evaluation. So in the net effect of your foreach
loop is that it's calling the code to make the item in the IEnumerable
for however many items are in that IEnumerable
.
The following post from CodeProject does an excellent job of explaining this behavior: http://www.codeproject.com/Articles/38097/The-Mystery-Behind-Yield-Return.aspx
精彩评论