首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对象的深拷贝

对象的深拷贝
EN

Stack Overflow用户
提问于 2013-03-23 06:30:12
回答 2查看 22K关注 0票数 9

我能得到一些帮助来执行一个对象的深拷贝吗?

这是我的代码:

代码语言:javascript
复制
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

字段也是我自己写的一门课。

要返回深度副本,需要修改Clone()函数吗?

EN

回答 2

Stack Overflow用户

发布于 2015-03-09 19:07:28

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

代码语言:javascript
复制
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

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

注意事项:为了使用BinaryFormatter.Serialize,传入的类和它公开为属性的任何其他类必须标记为。

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

代码语言:javascript
复制
<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附带了它在争议中的份额,因为如果它正在执行深度或浅层克隆,则不会向调用方指示。实际上,不需要接口就可以将方法添加到类中。

票数 9
EN

Stack Overflow用户

发布于 2013-03-23 06:49:05

(顺便说一句,我可能会给你的班级起别的名字,而不是“类”)。

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

  1. 确保字段类还实现了深度复制Clone()方法。如果您还没有这样做,那么这可能涉及到它的Clone()方法创建一个类型为Field的新对象,然后根据当前对象填充其每个属性。如果您的Field类具有其他类/复杂类型(例如您自己创建的类)的属性,那么它们也应该实现Clone(),您应该对它们调用Clone()来创建新的深度副本。
  2. 在类的Clone()方法中,您将创建一个类类型的新对象,例如通过调用其构造函数
  3. 将新对象的Name属性设置为当前对象的Name属性
  4. 创建一个新的List(Of Field),为了示例起见,我们将其命名为listA
  5. 迭代当前列表,并将每个列表项的克隆分配给listA。例如:
代码语言:javascript
复制
For Each item in _ListOfFields
    listA.Add(item.Clone())
End
  1. 之后,可以将新列表(listA)分配给在Clone()方法中创建的对象。

有另一种(可能更好)的手动方法,就是用VB.NET描述的这里

如果您想欺骗一点,那么您只需序列化您现有的对象,然后将其反序列化为一个新的对象,如技术这里

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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15584053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档