Search code examples
vb.netinheritanceicloneable

How do I make a derived class cloneable?


I am attempting to create a base class and a derived class that both implement ICloneable. It seems to me that the base class Clone method should take care of all the base class properties and the derived class Clone method all of the derived class properties and use the base class's Clone method. The result is something like this:-

Public Class MyBaseClass
    Implements ICloneable

    Private my_base_var As Integer

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim new_base_class As MyBaseClass = New MyBaseClass
        new_base_class.my_base_var = my_base_var
        Return new_base_class
    End Function

End Class

Public Class MySubClass
    Inherits MyBaseClass
    Implements ICloneable

    Private my_sub_var As Integer

    Public Overloads Function Clone() As Object Implements System.ICloneable.Clone
        Dim new_sub_class As MySubClass = CType(MyBase.Clone, MySubClass)    ' (1)
        new_sub_class.my_sub_var = Me.my_sub_var
        Return new_sub_class
    End Function

End Class

This results in a run-time exception Unable to cast object of type MyBaseClass to type MySubClass at line (1), which I confess did not surprise me. Replacing that line with

    Dim new_sub_class As MySubClass = MyBase.Clone

produced a compilation error. It seems to me that I need some way of converting a MyBaseClass to MySubClass in order to get the base class's members set up with the base class's Clone. A less appealing alternative would be to copy the base class's members in the sub-class's Clone. Does anyone know what to do here?

I have looked at the question here but can't translate that into VB.Net. If the solution given here is necessary, then I'll give up the idea. In the fullness of time I plan to make the base class MustInherit, if that makes any difference.


Solution

  • A possible implementation could look like this:

    Public Class MyBaseClass
        Implements ICloneable
        Private my_base_var As Integer = 1
    
        Public Overridable Function Clone() As Object implements ICloneable.Clone
            Dim theClone = Create()
            theClone.my_base_var = my_base_var
            Return theClone
        End Function
    
        Protected Overridable Function Create() As MyBaseClass
            Return New MyBaseClass()
        End Function
    End Class
    
    Public Class MySubClass
        Inherits MyBaseClass
        Private my_sub_var As Integer = 1
    
        Public Overrides Function Clone() As Object
            Dim theClone = DirectCast(MyBase.Clone(), MySubClass)
            theClone.my_sub_var = Me.my_sub_var
            Return theClone
        End Function
    
        Protected Overrides Function Create() As MyBaseClass
            Return New MySubClass()
        End Function
    End Class