我已经做了一些阅读,似乎不能围绕在我的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"
所以我知道复制一个类会复制指针而不是内容。我在危险类中使用了iclonable接口,但不能说我用对了。Hazards变量是一个Hazard类列表。我该如何克隆这个类呢?
实现IClonable
并不意味着它取代了常规赋值,它仍然只是复制引用。你甚至没有复制项,你复制了列表,这意味着你仍然只有一个列表,但是有两个引用。
要使用Clone
方法,您必须为列表中的每个项目调用它:
rdNew.Hazards = rd.Hazards.Select(Function(x) x.Clone()).Cast(Of Hazard).ToList()
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
我知道这是旧的
rdNew.Hazards = rd.Hazards.ToList()
即使它已经是一个列表,ToList也会在它的基础上创建一个新的列表。
在VB 2019中,这将创建一个浅拷贝,但这在某些情况下很有用。这意味着列表是新的,但是rd.Hazards
和rdNew.Hazards
的元素都指向相同的东西。
如果您编辑任何特定的危险,将在两者中看到更改。
如果您在一个列表中添加了一个危险,则另一个列表将不包含该危险。
如果你从一个列表中删除了一个危险,另一个列表中仍然有它。
如果Hazard是一个基本类型(如字符串或整数),那么编辑项目将不会反映在其他列表中。