2013-01-22 106 views
4

我已经做了一些阅读,似乎无法包装我的头,最好的方法是克隆VB2010项目中的List(类)。我有一个像这样克隆一个列表(类)

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 

所以可以说我有一个城市我的工作,还有,我要创建的情况下,作为一个基地之一的道路,它的危害,然后添加其他相关的三类但以先前的道路危害为起点,然后调整田地。

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" 

所以我知道复制一个类将复制指针而不是内容。我在危险类中使用了ICloneable接口,但不能说我正确地使用它。 Hazards变量是Hazard类的列表。我将如何去克隆那个课程?

+1

你需要复制只是列表,或者你还需要在每一个对象复制清单? – cdhowie

+1

看起来你想要一个**深度克隆**? – Styxxy

+0

我想要整个东西的副本。换句话说,危害的所有成员都被复制到新道路上。危害包含字符串,双打,整数和一个枚举。我认为一个克隆就是它的名字,所以我不只是指向原来的危险类。 – sinDizzy

回答

9

实施IClonable并不意味着它取代了常规的作业,它仍然只是复制参考。而且你甚至不复制项目,你正在复制列表,这意味着你仍然只有一个列表,但有两个引用。

要使用Clone方法,你必须把它在列表中的每个项目:

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

好的,让我试试。我看到的所有示例代码都必须使用变量而不是列表,这就是为什么我进行了调查。 – sinDizzy

+0

在我的测试中,这似乎是工作。如果我发现任何问题,我会回复。 – sinDizzy

1
Imports System.IO 
Imports System.Xml.Serialization   

Public Function CopyList(Of T)(oldList As List(Of T)) As List(Of T) 

      'Serialize 
      Dim xmlString As String = "" 
      Dim string_writer As New StringWriter 
      Dim xml_serializer As New XmlSerializer(GetType(List(Of T))) 
      xml_serializer.Serialize(string_writer, oldList) 
      xmlString = string_writer.ToString() 

      'Deserialize 
      Dim string_reader As New StringReader(xmlString) 
      Dim newList As List(Of T) 
      newList = DirectCast(xml_serializer.Deserialize(string_reader), List(Of T)) 
      string_reader.Close() 

      Return newList 
     End Function