我遇到了(对我来说)奇怪的行为。这是代码:
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
,这是对db的查询,我跳过了详细信息。
然后我必须做其他计算,最后我迭代我的对象来设置另一个参数。返回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;
据我所知,对象不是复制的,而是引用的......对吗? 显然代码背后会发生什么?有什么区别?
答案 0 :(得分:6)
请记住,Linq查询只是一个查询 - 它说“如果我要求这些数据,这就是我想要的。它不会保留任何数据,但会等到你问结果(通过foreach
,ToList
,ToArray
等。)
不同之处在于,您并未捕获第一个示例中ToList
返回的列表。它由ForEach
调用使用,但objects
变量仍保留对原始查询的引用。当你再次要求它时 - 它会再次获取数据。当它再次获取数据时,会创建新对象。
所以在这方面 - 是ToList()
创建一个新列表。它不会修改它被调用的对象将其转换为列表。
在第二个示例中,objects
变量通过ToList()
保存对查询生成的列表的引用,因此当您修改它们并返回objects
时你将返回相同的列表。
答案 1 :(得分:0)
在您的第一个代码示例中,objects.ToList()
实际上正在创建一个类型List
的新对象,您正在使用ForEach
。 ForEach
完成后,您仍然只是返回IEnumerable
,您实际想要返回的列表将会消失。
通过将ToList()
的LINQ查询分配给object
变量,您将使用ForEach
中新创建的列表。