答案具體取決於您在克隆方法中想要完成的工作。
如果你想在沒有實際複製任何屬性的情況下創建當前類的新實例(這聽起來像你可能有興趣根據示例代碼和描述做),那麼簡單的解決方案是:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Activator.CreateInstance(Me.GetType)
End Function
End Class
您可以測試,這是所謂的加入在酒吧消息(或某種調試或輸出的):
Public Class Bar
Inherits Foo
Public Sub New()
MsgBox("Test")
End Sub
End Class
如果你有Option Strict On
,我強烈建議,該代碼在主將是:
Sub Main()
Dim x As New Bar
Dim y As Bar = DirectCast(x.Clone, Bar)
End Sub
不過,如果你有興趣的複製從當前類的成員的值,可以使用MemberwiseClone:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone
End Function
End Class
然而,這隻會造成一個淺拷貝,將複製引用,將不會調用Bar上的構造函數。當我們以這種方式使用MemberwiseClone,我們隨時補充,可以通過繼承來執行克隆後的清理可重寫的方法:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Dim oObject As Foo
oObject = DirectCast(Me.MemberwiseClone, Foo)
oObject.PostCloneCleanup()
Return oObject
End Function
Protected Overridable Sub PostCloneCleanup()
End Sub
End Class
Public Class Bar
Inherits Foo
Public Sub New()
MsgBox("Test")
End Sub
Protected Overrides Sub PostCloneCleanup()
MsgBox("PostCloneCleanup")
End Sub
End Class
最後,如果淺複製或處理複製引用對您並不順心,您可以執行使用價格便宜,但非常有效的一招了深刻的副本:序列化和反序列化使用BinaryFormmater:
Public Function CreateDeepCopy(Of T)(ByVal oRecord As T) As T
If oRecord Is Nothing Then
Return Nothing
End If
If Not oRecord.GetType.IsSerializable Then
Throw New ArgumentException(oRecord.GetType.ToString & " is not serializable")
End If
Dim oFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Using oStream As IO.MemoryStream = New IO.MemoryStream
oFormatter.Serialize(oStream, oRecord)
oStream.Position = 0
Return DirectCast(oFormatter.Deserialize(oStream), T)
End Using
End Function
這就要求類可序列化,但是這是很容易做到。
+1但我不喜歡VB的這種風格;即使編譯器沒有強制它,你應該用括號來限定你的函數調用,以區別於屬性訪問:也就是說,寫'Me.GetType()'而不是'Me.GetType'等。 –
@KonradRudolph:Thanks for +1。我同意並始終在生產代碼中遵循這一點,但只是將一個快速樣本放在一起,我認爲它會很好。 –