可以使深克隆有兩種方式:通過實施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