RodH257
RodH257

Reputation: 3632

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. during foreach loop

but then in a breakpoint at the end of the loop, it didn't save it? enter image description here

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?

Upvotes: 5

Views: 2873

Answers (4)

villecoder
villecoder

Reputation: 13483

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

Upvotes: 0

Jim Mischel
Jim Mischel

Reputation: 133975

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.

Upvotes: 1

Ed Marty
Ed Marty

Reputation: 39690

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.

Upvotes: 4

Dark Falcon
Dark Falcon

Reputation: 44181

  1. What is the IEnumerable implementation? Could it be returning a copy of the object?

  2. Is RetreaveIndex a struct, and thus a value type? If so, then the variable index will be a copy.

Upvotes: 8

Related Questions