简体   繁体   English

修改foreach循环内对象的属性不起作用?

[英]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. 我正在使用PetaPoco从数据库中检索某些值,然后循环它们并检索一个值以分配给每个对象的一个​​属性。

    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循环期间设置断点时,正确设置了AssociatedUsers属性。 在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? 我很困惑,不应该将Index作为对正在被修改的内存中的位置的引用吗? It's an object after all. 毕竟这是一个对象。 What am I missing here? 我在这里错过了什么?

  1. What is the IEnumerable implementation? 什么是IEnumerable实现? Could it be returning a copy of the object? 它可以返回对象的副本吗?

  2. Is RetreaveIndex a struct, and thus a value type? RetreaveIndex是一个结构,因此是一个值类型? If so, then the variable index will be a copy. 如果是这样,那么变量index将是一个副本。

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. 根据传入的IEnumerable的实现方式,它不要求下次枚举数据时它返回与之前相同的对象。 Try turning the IEnumerable into a List before the foreach loop and return that insead. 尝试在foreach循环之前将IEnumerable转换为List并返回该insead。

From the project web site : 项目网站

Query vs Fetch 查询与提取

The Database class has two methods for retrieving records Query and Fetch. Database类有两种方法用于检索记录Query和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. 除了Fetch返回POCO的List <>之外,它们几乎完全相同,而Query使用yield return来迭代结果而不将整个集合加载到内存中。

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. 换句话说, Query每次都会从后备存储重新加载值,并且在枚举后不会保留项目。 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. 实际上,正在发生的是你错误解释了yield return语法的输出。

What's happening is that as you iterate over the IEnumerable returned from yield return , the code after that yield return is being executed. 发生的事情是,当您迭代从yield returnIEnumerable ,正在执行该yield return之后的代码。 In technical terms, yield return is doing lazy evaluation. 在技​​术方面, yield return正在进行懒惰评估。 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 . 因此,在你的foreach循环的净效果是它调用代码来使IEnumerable中的项目成为可能,因为很多项目都在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 CodeProject的以下帖子非常出色地解释了这种行为: http//www.codeproject.com/Articles/38097/The-Mystery-Behind-Yield-Return.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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