Linq-Query是否被称为toList()生成包含元素的副本?

时间:2016-06-23 12:47:46

标签: c# linq tolist

我遇到了(对我来说)奇怪的行为。这是代码:

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;

据我所知,对象不是复制的,而是引用的......对吗? 显然代码背后会发生什么?有什么区别?

2 个答案:

答案 0 :(得分:6)

请记住,Linq查询只是一个查询 - 它说“如果我要求这些数据,这就是我想要的。它不会保留任何数据,但会等到你问结果(通过foreachToListToArray等。)

不同之处在于,您并未捕获第一个示例中ToList返回的列表。它由ForEach调用使用,但objects变量仍保留对原始查询的引用。当你再次要求它时 - 它会再次获取数据。当它再次获取数据时,会创建新对象。

所以在这方面 - 是ToList()创建一个新列表。它不会修改它被调用的对象将其转换为列表。

在第二个示例中,objects变量通过ToList()保存对查询生成的列表的引用,因此当您修改它们并返回objects时你将返回相同的列表。

答案 1 :(得分:0)

在您的第一个代码示例中,objects.ToList()实际上正在创建一个类型List的新对象,您正在使用ForEachForEach完成后,您仍然只是返回IEnumerable,您实际想要返回的列表将会消失。

通过将ToList()的LINQ查询分配给object变量,您将使用ForEach中新创建的列表。