对象的深层复制

时间:2013-03-23 06:30:13

标签: vb.net class object visual-studio-2012 deep-copy

我可以请一些帮助来执行对象的深层复制。

这是我的代码:

Option Explicit On
Option Strict On

<Serializable> Public Class [Class]
Private _Name As String
Private _ListOfFields As New List(Of Field)

Public Property Name As String
    Get
        Return _Name
    End Get
    Set(value As String)
        _Name = value
    End Set
End Property

Public Property ListOfFields As List(Of Field)
    Get
        Return _ListOfFields
    End Get
    Set(value As List(Of Field))
        _ListOfFields = value
    End Set
End Property

Public Function Clone() As [Class]
    Return DirectCast(Me.MemberwiseClone, [Class])
End Function

End Class

Field也是我自己编写的一个类。

我需要修改哪个Clone()函数才能返回深层副本?

2 个答案:

答案 0 :(得分:5)

(顺便说一下,我可能会把你的课命名为“Class”以外的东西)。

如果您想手动完成所有操作,则需要执行以下步骤:

  1. 确保您的Field类还实现了深层复制Clone()方法。如果您还没有这样做,那么这可能涉及其Clone()方法创建类型为Field的新对象,然后根据当前对象填充其每个属性。如果你的Field类具有其他类/复杂类型的属性(例如你自己创建的类),那么它们也应该实现Clone(),你应该在它们上面调用Clone()来创建新的深层拷贝
  2. 在您的Clone()类方法中,您将创建一个类型为[Class]的新对象,例如通过调用其构造函数
  3. 将新对象的Name属性设置为当前对象的Name属性
  4. 创建一个新的List(Of Field),我们将其称为listA,例如
  5. 迭代当前列表,并将每个列表项的克隆分配给listA。例如:

  6. For Each item in _ListOfFields
        listA.Add(item.Clone())
    End
    

    1. 之后,您可以将新列表(listA)分配给您在Clone()方法中创建的对象
    2. 有一种替代(可能更好)的手工方法,在VB.NET中描述here

      如果您想作弊,那么您可以序列化现有对象,然后将其反序列化为新对象,如技术here

      我会说序列化然后反序列化技术是“最简单的”。

答案 1 :(得分:5)

您可以通过调用此辅助函数来创建任何类的克隆:

Function DeepClone(Of T)(ByRef orig As T) As T

    ' Don't serialize a null object, simply return the default for that object
    If (Object.ReferenceEquals(orig, Nothing)) Then Return Nothing

    Dim formatter As New BinaryFormatter()
    Dim stream As New MemoryStream()

    formatter.Serialize(stream, orig)
    stream.Seek(0, SeekOrigin.Begin)

    Return CType(formatter.Deserialize(stream), T)

End Function

这可以通过将类中的所有信息序列化为可移植对象,然后重写它以便切断任何引用指针来实现。

  

注意:传入的类及其作为属性公开的任何其他类必须标记为<Serializable()>才能使用BinaryFormatter.Serialize

如果您想让自己的类公开clonable方法本身,您可以添加方法并实现ICloneable接口,如下所示:

<Serializable()>
Public Class MyClass : Implements ICloneable

    'NOTE - The Account class must also be Serializable
    Public Property PersonAccount as Account
    Public Property FirstName As String

    Function Clone(ByRef orig As MyClass) As MyClass Implements ICloneable.Clone

        ' Don't serialize a null object, simply return the default for that object
        If (Object.ReferenceEquals(orig, Nothing)) Then Return Nothing

        Dim formatter As New BinaryFormatter()
        Dim stream As New MemoryStream()

        formatter.Serialize(stream, orig)
        stream.Seek(0, SeekOrigin.Begin)

        Return CType(formatter.Deserialize(stream), T)

    End Function

End Class
  

注意:请注意ICloneable附带controversies的份额,因为它不会向调用者表明它是执行深度还是浅度克隆。实际上,您不需要界面就可以将该方法添加到您的班级。