这令我感到困惑。我正在使用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属性。
但是在循环结束时的断点处,它没有保存它?
我很困惑,不应该将Index作为对正在被修改的内存中的位置的引用吗?毕竟这是一个对象。我在这里缺少什么?
答案 0 :(得分:8)
什么是IEnumerable实现?它可以返回该对象的副本吗?
RetreaveIndex是一个结构,因而是一个值类型?如果是,那么变量index
将是副本。
答案 1 :(得分:3)
根据传入的IEnumerable的实现方式,它不要求下次枚举数据时它返回与之前相同的对象。尝试在foreach循环之前将IEnumerable转换为List并返回该insead。
答案 2 :(得分:1)
查询与提取
Database类有两种方法 检索记录查询和获取。 这些几乎完全相同,除了 获取返回List&lt;&gt; POCO的 而Query使用yield return to 迭代结果没有 将整个集合加载到内存中。
换句话说,Query
每次都会从后备存储中重新加载值,并且在枚举后不会保留项目。当您在循环结束后再次查看某个项目时,该项目将从后备存储中重新加载。
答案 3 :(得分:0)
实际上,正在发生的是你误解了yield return
语法的输出。
当您迭代从IEnumerable
返回的yield return
时,正在执行的是yield return
之后的代码。在技术方面,yield return
正在进行懒惰评估。因此,在foreach
循环的净效果中,它会调用代码在IEnumerable
中生成该项,因为IEnumerable
中的项目很多。
CodeProject的以下帖子非常出色地解释了这种行为: http://www.codeproject.com/Articles/38097/The-Mystery-Behind-Yield-Return.aspx