LINQ是否实际上将结果的深层副本执行到不同的列表/数组/等,或者它只是给我一个列表/数组/等。由对原文的引用组成?
答案 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)方法强制立即进行查询评估并返回包含查询结果的数组。您可以将此方法附加到查询中,以获取查询结果的缓存副本。
嗯,这看起来确实令人困惑。
从第一句开始,显然查询中没有项目副本。
从第二句开始,您将获得整个查询结果的副本,但这是一个浅层副本,因为查询中没有项目副本。
答案 2 :(得分:2)
它返回的内容非常依赖于您所指的LINQ方法。但是除了少数显式复制枚举的方法(例如ToList
和ToArray
)之外,一般模式是不将输入复制到新结构。相反,它更喜欢懒惰的评估。