-1

I would like to confirm the expanation to some things I've been trying to understand.

I have two scenarios:

Scenario 1: I have one list stored in a private field of my class, I make a deep copy of it and store it in other private field. After doing so, I make some changes in the list, but I can choose to retrieve its original state. For doing so, I assign the copy of the original listto the modified one:

Public Class ClassX
    Private myList As List(Of Double)
    Private myOriginalList As List(Of Double)

    Public Sub New()
        myList = New List(Of Double)
        myOriginalList = ObjectCopier.Clone(myList)
    End Sub

    Private Sub Main()
        ChangeMyList()
        'myList  has one element
        RevertChanges()
        'myList  has zero elements
    End Sub

    Public Sub ChangeMyList()
        Dim r As New Random
        myList.Add(r.NextDouble)
    End Sub

    Public Sub RevertChanges()
       myList = myOriginalList 
    End Sub
End Class

Doing so, makes everything work as I would expect.

Scenario 2: The idea is pretty much the same, make a deep copy of one list for allowing the retrieval of its original state. However, in this case, the list is passed to another object, which makes a deep copy of it, modifies it, and decides to save those changes or revert them. And by doing so, I cannot get the desired behaviour, since the list is changed even when I make the assignment "myList = myOriginalList". Code:

Public Class ClassX
    Private myList As List(Of Double)

    Private Sub Main()
        Dim myList As New List(Of Double)
        Dim c As New ClassY(myList)

        c.ChangeList()
        'myList has one element
        c.RevertChanges()
        'myList still has one element

    End Sub
End Class

Public Class ClassY
    Private myList As List(Of Double)
    Private myOriginalList As List(Of Double)

    Public Sub New(ByVal c As List(Of Double))
        myList = c
        myOriginalList = ObjectCopier.Clone(myList)
    End Sub

    Public Sub ChangeList()
        Dim r As New Random
        myList.Add(r.NextDouble)
    End Sub

    Public Sub RevertChanges()
        myList = myOriginalList
    End Sub
End Class

So the question is... why? Why can I revert changes this way in the first case, but not in the second? Why changes made to the list passed as reference to ClassY are saved, but an assignment is not transmited to the original list in ClassX?

Hope it makes sense! Thanks!

Tao Gómez Gil
  • 1,770
  • 13
  • 31
  • 1
    `myList = myOriginalList` doesnt make a copy or revert it, it simply makes the two objects refer to the same List. If that is what you do in `ObjectCopier`, you didnt make a copy, but a copy of the object reference – Ňɏssa Pøngjǣrdenlarp Apr 08 '14 at 15:11
  • In ObjectCopier I make a deep copy by serialization and deserialization of the copied object, so it is really a different object, with no references to the previous. Thanks. – Tao Gómez Gil Apr 08 '14 at 15:14
  • there is obviously something wrong with `ObjectCopier` and we cant see that code to tell if you are actually returning a `New` List (serialization seems the long way around for a List copy). Also, why cant ClassX inherit ClassY instead of creating a private internal object (not clear that X maintains a ref to Y either if that is the real code)? – Ňɏssa Pøngjǣrdenlarp Apr 08 '14 at 15:30
  • With this code, you can't revert a second time. – the_lotus Apr 08 '14 at 15:36
  • Hi. This is not the real code I'm trying to write, it's simplified, but the behaviour I'm trying to understand appears in this simplified example. The cloner is pretty much like this one: http://stackoverflow.com/a/78612/2651069. And of course, I know better ways to copy a list, this is just for simplification purposes! – Tao Gómez Gil Apr 08 '14 at 15:45

1 Answers1

0

Setting 'myList' in ClassY back to the original doesn't change 'myList' in the 'Main' method. Have 'RevertChanges' take a list parameter:

Public Sub RevertChanges(ByRef changedList As List(Of Double))
   myList = myOriginalList 
   changedList = myList
End Sub
Dave Doknjas
  • 6,126
  • 1
  • 13
  • 25
  • I know, what I want to understand is why adding a new element to myList in ClassY affects myList in the Main method, but setting myList in ClassY back to the original does not affect myList in the Main method. – Tao Gómez Gil Apr 08 '14 at 15:42
  • 1
    In the 'ChangeList' method, 'myList' is still the same object as 'myList' in 'Main'. In 'RevertChanges', the two lists diverge - the one in ClassY points to a different list. – Dave Doknjas Apr 08 '14 at 15:46
  • Aha! That's what I supposed... but I still don't understand why! Is it because the myList in ClassY is a pointer to the myList in Main, but after the assignment is a point to another object? Yes, I think I get it... – Tao Gómez Gil Apr 08 '14 at 15:59
  • 1
    Even though this is not strictly correct, it may help to think of the object variables as 'addresses' and the real objects as 'houses' - if two variables have the same 'address', then changing the contents of a house changes what is seen at both addresses since the address is the same. Change one address to point to a different house, and there is now no correspondence between the two. – Dave Doknjas Apr 08 '14 at 16:11
  • Thanks a lot! I'll mark this as the correct answer. – Tao Gómez Gil Apr 08 '14 at 16:18