可以使深克隆有两种方式:通过实施ICloneable(并调用Object.MemberwiseClone方法),或通过二进制序列化。
第一种方式
第一个(可能更快,但并不总是最好的)方法是实现每种类型ICloneable接口。下面的示例说明。 C类实现ICloneable,并且因为这个类引用了其他类D和E,所以后者也实现了这个接口。在C的Clone方法中,我们调用其他类型的Clone方法。
Public Class C
Implements ICloneable
Dim a As Integer
' Reference-type fields:
Dim d As D
Dim e As E
Private Function Clone() As Object Implements System.ICloneable.Clone
' Shallow copy:
Dim copy As C = CType(Me.MemberwiseClone, C)
' Deep copy: Copy the reference types of this object:
If copy.d IsNot Nothing Then copy.d = CType(d.Clone, D)
If copy.e IsNot Nothing Then copy.e = CType(e.Clone, E)
Return copy
End Function
End Class
Public Class D
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone()
End Function
End Class
Public Class E
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone()
End Function
End Class
现在,当你调用了一个C的实例的克隆方法,你会得到该实例的深克隆:
Dim c1 As New C
Dim c2 As C = CType(c1.Clone, C) ' Deep cloning. c1 and c2 point to two different
' locations in memory, while their values are the
' same at the moment. Changing a value of one of
' these objects will NOT affect the other.
注意:如果班d和E引用类型,你必须像我们对类C所做的那样实施他们的克隆方法。等等。
警告: 1将上述样品是有效的,只要不存在循环引用。例如,如果C类具有自参照(例如,是C型的场),实施ICloneable接口并不容易,因为在C克隆方法可以进入无限循环。
2,另外一个需要注意的事情是,MemberwiseClone方法是Object类的一个受保护的方法。这意味着您只能从类的代码中使用此方法,如上所示。这意味着你不能将它用于外部类。
因此,在实现ICloneable是有效的,只有当两个警告以上不存在。否则,你应该使用二进制序列化技术。
第二种方式
的二进制序列可用于不上面列出的问题深克隆(特别是循环引用)。下面是使用二进制序列进行深克隆的通用方法:
Public Class Cloning
Public Shared Function DeepClone(Of T)(ByVal obj As T) As T
Using MStrm As New MemoryStream(100) ' Create a memory stream.
' Create a binary formatter:
Dim BF As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))
BF.Serialize(MStrm, obj) ' Serialize the object into MStrm.
' Seek the beginning of the stream, and then deserialize MStrm:
MStrm.Seek(0, SeekOrigin.Begin)
Return CType(BF.Deserialize(MStrm), T)
End Using
End Function
End Class
下面是如何使用此方法:
Dim c1 As New C
Dim c2 As C = Cloning.DeepClone(Of C)(c1) ' Deep cloning of c1 into c2. No need to
' worry about circular references!
假设你想要的通用clone()方法,因为你不希望实现ICloneable的一切? – 2009-04-28 22:11:00
这是克隆一个特定的对象。这个对象是我们的应用程序中的核心数据对象。这回答了你的问题了吗? – 2009-04-28 22:18:24