I know there's tons of question on the matter. But I couldn't, for the life of me, make any sense of the answers or use them in my example. I am newish in vb .net and I can't really implement general examples to my specific one. What I have is basically this:
dim a as New list(of player)
EDIT: dim b as New list(of player) 'previously was: dim b as new player
Class player
Public name As String
'[more]
End Class
[....]
a.Add(New player)
b.Add(New player)
a(0).name="john"
b=a
a(0).name="jack"
msgbox(b(0).name) 'it will print jack instead of john
I now this can be done with ICloneable, but after reading up a lot on it I can't implement correctly. Thank you in advance
When you assign a(0)
to b
they are both pointing to the same object in memory. Even though you declared b
as New player
that new player was thrown away when you made the assignment to an existing player.
To prove this to yourself, try the opposite. Change the name
property of b
and you will see it is reflected in the name
property of a(0)
.
Private Sub OPCode()
Dim a As New List(Of player)
Dim b As player
a.Add(New player)
a(0).name = "john"
b = a(0)
b.name = "jack"
MsgBox(a(0).name) 'jack
End Sub
Now to Clone...
Class player
Implements ICloneable
Public name As String
'[more]
Public Function Clone() As Object Implements ICloneable.Clone
Dim p As New player
p.name = name
Return p
End Function
End Class
Your class now implements ICloneable
with the addition of the Clone
function. You can implement this however you wish as long as the signature of the function matches the interface signature for the Clone
method.
Notice that my implementation is creating a New
player and is assigning the name
property to the name
of the existing player. This New player is what is returned by the function. The New player will have a different location in memory so changes to the first player from the list and this new player will not affect each other.
Since the Clone
function returns an object, we need to cast it to player
(the underlying type) so it will match our declare of b
and we will be able to use the properties and methods of the player
class.
Private Sub OPCode()
Dim a As New List(Of player)
Dim b As player
a.Add(New player)
a(0).name = "john"
b = CType(a(0).Clone, player)
a(0).name = "jack"
MsgBox(b.name) 'john
End Sub
EDIT
To accomplish your goal using 2 lists, I created a new class called PlayerList
. It inherits List(Of Player)
and implements ICloneable
. You can now clone list a
and get completely separate lists with composed of separate player objects.
Public Class PlayerList
Inherits List(Of player)
Implements ICloneable
Public Function Clone() As Object Implements ICloneable.Clone
Dim newList As New PlayerList
For Each p As player In Me
Dim newP = CType(p.Clone(), player)
newList.Add(newP)
Next
Return newList
End Function
End Class
Private Sub OPCode()
Dim a As New PlayerList()
Dim b As PlayerList
a.Add(New player)
a(0).name = "john"
b = CType(a.Clone, PlayerList)
a(0).name = "jack"
MsgBox(b(0).name)
End Sub