Câu trả lời tùy thuộc vào những gì bạn đang cố gắng thực hiện trong phương pháp nhân bản.
Nếu bạn muốn tạo phiên bản mới của lớp hiện tại mà không thực sự sao chép bất kỳ thuộc tính nào (có vẻ như bạn có thể quan tâm đến việc làm dựa trên mã mẫu và mô tả), thì giải pháp đơn giản là:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Activator.CreateInstance(Me.GetType)
End Function
End Class
bạn có thể kiểm tra điều này được gọi bằng cách thêm một tin nhắn (hoặc một số loại gỡ lỗi hoặc đầu ra) tại Bar:
Public Class Bar
Inherits Foo
Public Sub New()
MsgBox("Test")
End Sub
End Class
Nếu bạn có Option Strict On
, mà tôi khuyên, các mã trong chính sẽ là:
Sub Main()
Dim x As New Bar
Dim y As Bar = DirectCast(x.Clone, Bar)
End Sub
Tuy nhiên, nếu bạn quan tâm đến việc sao chép các giá trị thành viên từ lớp hiện tại, bạn có thể sử dụng MemberwiseClone:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone
End Function
End Class
Tuy nhiên, điều này sẽ chỉ tạo ra một bản sao cạn, sẽ sao chép tài liệu tham khảo, và sẽ không gọi hàm khởi tạo trên Bar. Khi chúng ta sử dụng MemberwiseClone theo cách này, chúng tôi luôn thêm một phương pháp overridable có thể được sử dụng bởi những người thừa kế thực hiện bài-clone dọn dẹp:
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
Cuối cùng, nếu sao chép cạn hoặc đối phó với sự tham khảo sao chép không phải là để bạn thích, bạn có thể thực hiện một bản sao sâu sử dụng một thủ thuật giá rẻ, nhưng rất hiệu quả: serialization và deserialization sử dụng 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
Điều này đòi hỏi các lớp học được serializable, nhưng đó là dễ dàng để làm.
+1 nhưng tôi không thích kiểu VB này; mặc dù trình biên dịch không ủy thác nó, bạn nên hội đủ điều kiện các cuộc gọi hàm của bạn với các dấu ngoặc đơn để phân biệt chúng với các truy cập thuộc tính: đó là, viết 'Me.GetType()' thay cho 'Me.GetType', v.v. –
@KonradRudolph: +1. Tôi đồng ý và luôn luôn làm theo điều này trong mã sản xuất, nhưng chỉ cần ném cùng một mẫu nhanh chóng, tôi figured nó sẽ là tốt. –