2013-01-22 99 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