6

私はいくつかの読書をしましたが、私のVB2010プロジェクトで(クラスの)リストを複製するための最良のアプローチが何であるかについて頭を悩ませているようです。私はそのように関連している3つのクラスを持っています

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

私が取り組んでいる都市があるとしましょう。ベースとして 1 つの道路とその危険を作成し、次に別の道路を追加しますが、前の道路の危険を出発点として使用し、フィールドを微調整したい場合があります。 .

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 クラスのリストです。そのクラスのクローンを作成するにはどうすればよいですか?

4

3 に答える 3

12

実装IClonableは、通常の割り当てを置き換えることを意味するのではなく、参照をコピーするだけです。また、アイテムをコピーするのではなく、リストをコピーしているため、リストは 1 つしかありませんが、リストへの参照は 2 つしかありません。

メソッドを使用するCloneには、リスト内の各項目に対して呼び出す必要があります。

rdNew.Hazards = rd.Hazards.Select(Function(x) x.Clone()).Cast(Of Hazard).ToList()
于 2013-01-22T20:38:31.063 に答える
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
于 2013-08-27T16:12:45.810 に答える