答えは、具体的にクローニング方法で達成しようとしているものによって異なります。
実際のプロパティをコピーせずに現在のクラスの新しいインスタンスを作成する場合(サンプルコードと説明に基づいて行うことに興味があるような音です)、簡単な解決策は次のとおりです。
Public Class Bar
Inherits Foo
Public Sub New()
MsgBox("Test")
End Sub
End Class
あなたは私を強くお勧めしますOption Strict On
を、持っている場合は、メインのコードを:あなたがバーで、これはメッセージ(またはデバッグまたは出力のいくつかの並べ替え)を加えることによって呼び出されることをテストすることができ
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Activator.CreateInstance(Me.GetType)
End Function
End Class
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のコンストラクタは呼び出されません。浅いコピーやコピーの参照を扱うが好きあなたにない場合は、最後に
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
、:私たちは、このようにMemberwiseCloneを使用すると、私たちは常にクローン後のクリーンアップを実行するために相続で使用することができますオーバーライドメソッドを追加しますあなたは安いが、非常に効果的なトリックを使って深いコピーを実行することができます。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:ありがとう+1。私はこれに同意し、常にこれをプロダクトコードに従いますが、サンプルをまとめて投げるだけで、うまくいくと思いました。 –