【问题标题】:Modifying a property of an object inside of a foreach loop doesn't work?在 foreach 循环内修改对象的属性不起作用?
【发布时间】:2011-05-21 12:53:00
【问题描述】:

这让我很困惑。我正在使用 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;
    }

当我在 foreach 循环期间设置断点时,AssociatedUsers 属性设置正确。

但是在循环结束的断点处,它没有保存它?

我很困惑,索引不应该是对正在修改的内存位置的引用吗?毕竟是对象。我在这里错过了什么?

【问题讨论】:

    标签: c# .net foreach


    【解决方案1】:
    1. 什么是 IEnumerable 实现?它会返回对象的副本吗?

    2. RetreaveIndex 是一个结构,因此是一个值类型?如果是这样,那么变量index 将是一个副本。

    【讨论】:

    • 它是一个对象(见原始问题的底部)。我查看了 PetaPoco 源代码,看来我调用的方法 Query() 使用 Yield Return 来返回 IENumerable。当我将调用更改为返回 List 的 Fetch() 时,它起作用了。也许我需要更多地阅读收益回报,我认为构建某种列表只是语法糖,猜我错了吗?
    • yield return 导致方法主体被拆分成一个巨大的 case 语句,该语句成为新 IEnumerator 类的 MoveNext 方法的主体。
    • 我已经使用 IEnumerables 多年了,令人惊讶的是,这是我第一次遇到这个......(这完全让我感到困惑)干杯!
    【解决方案2】:

    根据传入的 IEnumerable 是如何实现的,它没有要求它下次枚举数据时返回与以前相同的对象。尝试在 foreach 循环之前将 IEnumerable 转换为 List 并将其返回。

    【讨论】:

      【解决方案3】:

      来自project web site

      查询与提取

      Database 类有两种方法 检索记录 Query 和 Fetch。 这些几乎相同,除了 Fetch 返回 POCO 的 List 而 Query 使用 yield return 来 迭代结果而不 将整个集合加载到内存中。

      换句话说,Query 每次都从后备存储重新加载值,并且在枚举后不会保留项目。当您在循环结束后再次查看某个项目时,该项目将从后备存储重新加载。

      【讨论】:

        【解决方案4】:

        实际上,您误解了yield return 语法的输出。

        发生的情况是,当您迭代从yield return 返回的IEnumerable 时,正在执行yield return 之后的代码。用技术术语来说,yield return 正在做惰性评估。因此,foreach 循环的最终效果是,它调用代码来制作 IEnumerable 中的项目,因为 IEnumerable 中有很多项目。

        CodeProject 的以下帖子很好地解释了这种行为: http://www.codeproject.com/Articles/38097/The-Mystery-Behind-Yield-Return.aspx

        【讨论】:

          猜你喜欢
          • 2020-06-05
          • 2013-03-21
          • 2016-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-21
          • 1970-01-01
          • 2014-06-11
          相关资源
          最近更新 更多