Does LINQ actually perform a deep copy of the results to a different list/array/etc, or does it simply give me a list/array/etc. composed of references to the original?
-
6Nothing in .NET - except perhaps serialization - ever automatically creates a deep copy of anything. One of the reasons is that deep copies are not trivial to automatically construct. – bzlm Jan 21 '11 at 17:43
-
@bzlm - so when I edit the result of a LINQ query, I'm actually editing the value of the member of the original collection? – Joel B Jan 21 '11 at 18:11
-
Yes, you are. Try it. :) – bzlm Jan 21 '11 at 18:28
3 Answers
It's going to depend on if (and how) you use Select to project the results.
If you do not create new objects in a projection then the result will reference the same objects as the original collection.
If, however, you create new objects in the project then, obviously, they will not be the same.
The collection returned here will contain references to the same objects in _myCollection
:
from m in _myCollection
where m.SomeFilterCriteria
select m
The collections returned in these cases will not:
from m in _myCollection
where m.SomeFilterCriteria
select new { m.Prop1, m.Prop2 }
In this case, it is worth pointing out that Prop1 and Prop2 of the new anonymous object - if they are reference types - will contain a reference to the same object as the original object. Only the top-level references in the collection will be different.
Basically - nothing in .Net aside from serializers (as mentioned elsewhere here) will "deep" copy, unless you implement it.
or
from m in _myCollection
where m.SomeFilterCriteria
select m.Clone()
Again, it would be a mistake to assume that any "deep" copying is going on here. Of course, Clone
's implementation will be in the class and could be anything, including deep copying, but that is not given.

- 26,121
- 7
- 68
- 86
-
On your last example, I thought `Clone()` only performed a shallow copy. – Joel B Jan 21 '11 at 19:04
-
Clone will copy however it was implemented to do so. There is no default .Clone - you would have to implement it for any object you want to support it on. My answer only speaks to the top-level references in the collection. Nothing "deep" copies in .Net. – quentin-starin Jan 21 '11 at 19:29
-
1@Joel B: To add to qstarin's comment, the [MSDN article](http://msdn.microsoft.com/en-us/library/system.icloneable.clone.aspx) states explicitly that "Clone can be implemented either as a deep copy or a shallow copy. " So, not only will clone copy however it was implemented to do so, but shallow and deep copy are **both** permissible implementations according to the MSDN documentation. Interestingly, object has a protected [MemberwiseClone](http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx) member for making shallow copies. – Brian Jan 24 '11 at 15:41
-
@Brian - Is there a standard/best practice for what type of copy `Clone` performs? Doesn't `Clone` just allow for writing your own implementation of `MemberwiseClone`? Why not just make `MemberwiseClone` virtual in the Framework? – Joel B Jan 24 '11 at 16:46
-
@Joel: I don't think there is a standard way to implement `Clone`; MSDN explicitly says deep and shallow are both are OK. `MemberwiseClone` is included in the framework. I assume it is `protected` rather than public because not all classes should have a public method for making shallow copies; those that do need one can just make a public method which calls `MemberwiseClone`. I assume it is `virtual` because the base implementation will work fine even on derived types; there is no need to override it. – Brian Jan 24 '11 at 16:55
-
1`MemberwiseClone` operates in a very specific manner and is intended to be used to implement cloning operations. Making it virtual would allow overridden implementations, and then derived classes would be unable to rely on its behavior themselves. – quentin-starin Jan 24 '11 at 17:00
-
Also note that `MemberwiseClone` is implemented directly in the CLR (the hint for this if you ignore documentation is that it has `[MethodImpl(MethodImplOptions.InternalCall)]` as its attribute). – Brian Jan 24 '11 at 17:01
Does LINQ actually perform a deep copy of the results to a different list/array/etc, or does it simply give me a list/array/etc. composed of references to the original?
From Enumerable.ToArray. (Similiar text found at Enumerable.ToList)
The ToArray(IEnumerable) method forces immediate query evaluation and returns an array that contains the query results. You can append this method to your query in order to obtain a cached copy of the query results.
Well, that certainly looks confusing.
- returns an array that contains the query results
- obtain a cached copy of the query results
From the first sentence, it is clear that no copies of items in the query are made.
From the second sentence, you get a copy of the query results as a whole, but that is a shallow copy since no copies of items in the query are made.

- 108,202
- 21
- 135
- 185
What it returns is very dependent on which LINQ method you are referring to. But with the exception of the few methods which explicitly copy the enumeration (ToList
and ToArray
for example) the general pattern is to not copy the input to a new structure. Instead it prefers lazy evaluation.

- 733,204
- 149
- 1,241
- 1,454
-
1If you re-read the question, you'll find that ToList() and ToArray() are not special. :) – bzlm Jan 21 '11 at 17:43
-
1@bzlm, not sure how the question is related to that part of my answer. I wanted to specifically call them out as 2 LINQ methods which eagerly evaluate the input and produce a new collection structure for it before I made the broader statement about the rest. I didn't say it did a deep copy so not sure what you're referring to. – JaredPar Jan 21 '11 at 17:46
-
1@JaredPar The question is "Does LINQ actually perform a deep copy [...] or does it simply give me a list [...] composed of references to the original". Your answer is about whether the *enumerations* are evaluated. Right? – bzlm Jan 21 '11 at 17:49
-
1@bzlm, how the enumerations are evaluated has an impact on how / what a LINQ operation returns which is the substance of the question. – JaredPar Jan 21 '11 at 17:51
-
-
@bzlm if you want to disagree that's fine but it doesn't change that how the inputs are evaluated directly affects what a LINQ operation returns. – JaredPar Jan 21 '11 at 17:58