简体   繁体   中英

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. 在foreach循环期间

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?

  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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM