Is it possable in vb.net to have a method that constructs an object of any derived class in the bass class? In this code x.Clone should return a Bar object. Is the only way to dulpicate the code in both class's with both different object types.
Module Module1
Sub Main()
Dim x As New Bar
Dim y As Bar = x.Clone
End Sub
End Module
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Clone = Me.new() 'fails to compile as not in a constructor
Clone = new Foo 'constructs a new foo in the derived class
End Function
End Class
Public Class Bar
Inherits Foo
'additional implementation
'but no addition fields
End Class
The answer depends on specifically what you are trying to accomplish in the cloning method.
If you want to create a new instance of the current class without actually copying any of the properties (which is sounds like you may be interested in doing based on the sample code and description), then the simple solution is:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Activator.CreateInstance(Me.GetType)
End Function
End Class
You can test that this is called by adding a message (or some sort of debug or output) in Bar:
Public Class Bar
Inherits Foo
Public Sub New()
MsgBox("Test")
End Sub
End Class
If you have Option Strict On
, which I strongly recommend, the code in main would be:
Sub Main()
Dim x As New Bar
Dim y As Bar = DirectCast(x.Clone, Bar)
End Sub
However, if you are interested in copying the member values from the current class, you can use MemberwiseClone:
Public Class Foo
Implements ICloneable
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone
End Function
End Class
However, this will only create a shallow copy, will copy references, and will not invoke the constructor on Bar. When we use MemberwiseClone in this manner, we always add an overridable method that can be used by inheritors to perform post-clone cleanup:
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
Finally, if shallow copying or dealing with copied references is not to you liking, you can perform a deep copy using a cheap, but very effective trick: serialization and deserialization using the 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
This requires that the classes be serializable, but that is easy to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With