【发布时间】:2016-06-23 12:47:46
【问题描述】:
我遇到了(对我而言)奇怪的行为。代码如下:
var objects = from i in items
//some calculations
select something;
// other calculations
objects.ToList().ForEach(x => {
//some calculations
x.Property = "some text"
});
return objects;
首先我生成一个IEnumerable,它是对数据库的查询,我跳过了细节。
然后我必须进行其他计算,最后我遍历我的对象以设置更多参数。运行此代码,一旦返回 IEnumerable 对象,它们的 Property 就不会被设置。
否则,如果我在 Linq 表达式中移动 ToList(),如下所示,Property 被设置:
var objects = (from i in items
//some calculations
select something).ToList();
// other calculations
objects.ForEach(x => {
//some calculations
x.Property = "some text"
});
return objects;
据我所知,对象不是复制的,而是引用的……对吧? 显然代码背后发生了什么?有什么区别?
【问题讨论】:
-
当您执行
objects.ToList()时,查询将被执行。然后你返回objects。假设有人随后迭代了返回的对象:在这种情况下,查询将再次执行(因此将创建新对象) -
var objectswithoutToList只是一个查询,所以定义不是执行。如果你实现它,例如使用ToList或forach,它就会被执行。因此,通过附加ToList,可以查询数据库并填充内存列表。List.ForEach将枚举它们并修改属性。在第一种方法中,该列表被立即丢弃,因为它没有存储在变量中。第二个版本是正确的。 -
@TimSchmelter 你能否解释一下“这个列表被立即丢弃,因为它没有存储在变量中”?即使它没有在变量定义上实现,也不应该在执行 ToList 或 ForEach 后将结果存储在 objects 变量中吗?
-
@NahuelIanni:不,
objects变量仍然只是数据库查询。该列表未存储在任何地方。另一种可能更好的方法是将文本分配给查询本身的属性。那么之后就不需要循环列表了。