Clone a List(Of Class)

sinDizzy picture sinDizzy · Jan 22, 2013 · Viewed 21.1k times · Source

I've done some reading and cant seem to wrap my head around what the best approach would be to clone a List(of class) in my VB2010 project. I have three classes that are related like so

Public Class City
    'here are many fields of type string and integer
    Public Roads As New List(Of Road)
End Class
Public Class Road
    'here are many fields of type string and integer
    Public Hazards As New List(Of Hazard)
End Class
Public Class Hazard
    Implements ICloneable

    'here are many fields of type string and integer and double
    Public Function Clone() As Object Implements System.ICloneable.Clone
        Return Me.MemberwiseClone
    End Function
End Class

So lets say I have a city I'm working on, there are cases where I want to create, as a base one road and its hazards, then add another road but using the prior roads hazards as a starting point and then tweak the fields.

Dim rd As New Road
'add road fields

dim hz1 as New Hazard
'add hazard fields
dim hz2 as New Hazard
'add hazard fields

'add the hazard objects to the road
rd.Hazards.Add(hz1)
rd.Hazards.Add(hz2)

'add the road to the city
myCity.Roads.Add(rd)


'here I want to start a new road based on the old road
Dim rdNew As New Road

'copy or clone the hazards from old road
rdNew.Hazards = rd.Hazards '<============

'over-write some of the hazard fields
rdNew.Hazards(0).Description = "temp"

So I know that copying a class will copy the pointer and not the contents. I used the ICloneable interface in the hazard class but cant say I'm using it right. The Hazards variable is a list of Hazard class. How would i go about cloning that class?

Answer

Guffa picture Guffa · Jan 22, 2013

Implementing IClonable doesn't mean that it replaces the regular assignment, it will still just copy the reference. And you aren't even copying the items, you are copying the list, which means that you still only have one list, but two references to it.

To use the Clone method you have to call it for each item in the list:

rdNew.Hazards = rd.Hazards.Select(Function(x) x.Clone()).Cast(Of Hazard).ToList()