LINQ在创建返回时是否会增加内存

时间:2011-01-21 17:33:16

标签: linq deep-copy shallow-copy

LINQ是否实际上将结果的深层副本执行到不同的列表/数组/等,或者它只是给我一个列表/数组/等。由对原文的引用组成?

3 个答案:

答案 0 :(得分:10)

这将取决于您是否(以及如何)使用Select来投影结果。

如果您未在投影中创建新对象,则结果将引用与原始集合相同的对象。

但是,如果你在项目中创建新对象,那么显然它们将是不一样的。

此处返回的集合将包含_myCollection中相同对象的引用:

from m in _myCollection
where m.SomeFilterCriteria
select m

在这些情况下返回的集合不会:

from m in _myCollection
where m.SomeFilterCriteria
select new { m.Prop1, m.Prop2 }

在这种情况下,值得指出的是,新匿名对象的Prop1和Prop2(如果它们是引用类型)将包含对与原始对象相同的相同对象的引用。只有集合中的顶级引用才会有所不同。

基本上 - 除了序列化程序(如本文其他地方所述)之外,.Net中的任何内容都不会“深入”复制,除非你实现它。

from m in _myCollection
where m.SomeFilterCriteria
select m.Clone()

同样,假设任何“深度”复制都在这里进行是错误的。当然,Clone的实现将在类中,可以是任何东西,包括深度复制,但是没有给出。

答案 1 :(得分:3)

  

LINQ是否实际上将结果的深层副本执行到不同的列表/数组/等,或者它只是给我一个列表/数组/等。由对原文的引用组成?

来自Enumerable.ToArray。 (在Enumerable.ToList发现了类似的文字)

  

ToArray(IEnumerable)方法强制立即进行查询评估并返回包含查询结果的数组。您可以将此方法附加到查询中,以获取查询结果的缓存副本。

嗯,这看起来确实令人困惑。

  1. 返回包含查询结果的数组
  2. 获取查询结果的缓存副本
  3. 从第一句开始,显然查询中没有项目副本

    从第二句开始,您将获得整个查询结果的副本,但这是一个浅层副本,因为查询中没有项目副本

答案 2 :(得分:2)

它返回的内容非常依赖于您所指的LINQ方法。但是除了少数显式复制枚举的方法(例如ToListToArray)之外,一般模式是不将输入复制到新结构。相反,它更喜欢懒惰的评估。