Shallow and deep copies
-
Hey, I'm a little confused with the definition of a shallow copy. From the definitions I can find online, I get that reference types get copied, but not the value they refer to. In other words, they should point to the same value. However, when I test this, I can assign a new value to a reference type in either the original or the copy, and the value in it's counterpart won't change. This is the code I used to test this:
Sub Main() Dim list1 As New List(Of Spam) list1.Add(New Spam(1)) list1.Add(New Spam(2)) list1.Add(New Spam(3)) Dim list2 As List(Of Spam) list2 = list1.GetRange(0, list1.Count) ' this should make a shallow copy list2.Item(1) = New Spam(5) For Each s As Spam In list1 Console.Write(s.ToString & " ") Next Console.ReadKey() End Sub Private Class Spam Public Sub New(ByVal v As Integer) value = v End Sub Dim value As Integer Public Overrides Function ToString() As String Return value.ToString End Function End Class
The output of this code is "1 2 3", and not "1 5 3", which I'd expect from the definition of a shallow copy. Please un-confuse me here :) Cheers!
Jeroen De Dauw --- Forums ; Blog ; Wiki --- 70 72 6F 67 72 61 6D 6D 69 6E 67 20 34 20 6C 69 66 65!
-
Hey, I'm a little confused with the definition of a shallow copy. From the definitions I can find online, I get that reference types get copied, but not the value they refer to. In other words, they should point to the same value. However, when I test this, I can assign a new value to a reference type in either the original or the copy, and the value in it's counterpart won't change. This is the code I used to test this:
Sub Main() Dim list1 As New List(Of Spam) list1.Add(New Spam(1)) list1.Add(New Spam(2)) list1.Add(New Spam(3)) Dim list2 As List(Of Spam) list2 = list1.GetRange(0, list1.Count) ' this should make a shallow copy list2.Item(1) = New Spam(5) For Each s As Spam In list1 Console.Write(s.ToString & " ") Next Console.ReadKey() End Sub Private Class Spam Public Sub New(ByVal v As Integer) value = v End Sub Dim value As Integer Public Overrides Function ToString() As String Return value.ToString End Function End Class
The output of this code is "1 2 3", and not "1 5 3", which I'd expect from the definition of a shallow copy. Please un-confuse me here :) Cheers!
Jeroen De Dauw --- Forums ; Blog ; Wiki --- 70 72 6F 67 72 61 6D 6D 69 6E 67 20 34 20 6C 69 66 65!
Dag Jeroen, While you write
jeroen de dauw wrote:
I can assign a new value to a reference type
that does not really make sense (a type is a type, a type does not have a value at all); and it is not what
list2.Item(1) = New Spam(5)
does. Yes list2 is a reference type (it is an object, not a value type), as lists and arrays are collections holding things of a single type (either value types of reference types themselves). In this case, the list holds reference types, i.e. references toSpam
instances. What your statement does is it overwrites an existing reference by a reference to a new object. So none of the existingSpam
objects is being modified. As your use of the terminology isn't correct, this suggests you got a few things confused. A shallow copy copies everything: the data in value types and the data in a reference type. The trick is a reference type only holds a reference (think of it as a pointer), and that is what gets copied. The thing (object) it points to is not being copied or cloned, so the old and new pointers now point to one and the same thing. To prove, or rather disprove, your statement about shallow copies, you should add aValue
property to the Spam class, then executelist2.Item(1).Value = 17
and watch how both lists reflect the change, as you now would have changed an existing object, where both lists are referring to. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
-
Dag Jeroen, While you write
jeroen de dauw wrote:
I can assign a new value to a reference type
that does not really make sense (a type is a type, a type does not have a value at all); and it is not what
list2.Item(1) = New Spam(5)
does. Yes list2 is a reference type (it is an object, not a value type), as lists and arrays are collections holding things of a single type (either value types of reference types themselves). In this case, the list holds reference types, i.e. references toSpam
instances. What your statement does is it overwrites an existing reference by a reference to a new object. So none of the existingSpam
objects is being modified. As your use of the terminology isn't correct, this suggests you got a few things confused. A shallow copy copies everything: the data in value types and the data in a reference type. The trick is a reference type only holds a reference (think of it as a pointer), and that is what gets copied. The thing (object) it points to is not being copied or cloned, so the old and new pointers now point to one and the same thing. To prove, or rather disprove, your statement about shallow copies, you should add aValue
property to the Spam class, then executelist2.Item(1).Value = 17
and watch how both lists reflect the change, as you now would have changed an existing object, where both lists are referring to. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages