Question Asker Question Asker - 3 months ago 14
Vb.net Question

Set or override readonly property of baseclass

I want to make a

ReadOnly
property of a class change when a subclass is implemented of it (ie. the property depends on which class it belongs to).

Currently, I have:

Public MustInherit Class MyBaseClass

Public ReadOnly name As String

...

Sub New()
name = "None"
End Sub
End Class

Public Class MyClassV0_0 : Inherits MyBaseClass

Public Shadows ReadOnly name As String

...

Sub New()
name = "MyClass v0.0"
End Sub
End Class


I get these results when this is called in my main code:

Dim classInstance As MyBaseClass = New MyClassV0_0

Debug.Print(classInstance.name)


Debug prints:
None


However, I'm expecting
MyClass v0.0
to be printed instead. Is there a way for me to do this?

Note that I need
classInstance
to be
MyBaseClass
— if I had declared it as
MyClassV0_0
this problem wouldn't occur for me.

Answer

Shadows allows some member to be defined again by a derived when the base doesn't allow it to be overrided (And is used only when the instance is used as the derived type)

What you need here is to make the base member Overridable (or MustOverride here as the base class is MustInherit and it doesn't seem that the base class needs a default implementation) and Overrides it in the derived

For that, Name should be a property instead of a field

Public MustInherit Class MyBaseClass
    Public MustOverride ReadOnly Property Name As String
End Class

Public Class MyClassV0_0 : Inherits MyBaseClass
    Public Overrides ReadOnly Property Name As String = "MyClass v0.0"
End Class

If the name if the same for all instances of a class maybe it should be a Shared field but that also implies you'll access it from the class not from the instance

MyBaseClass.Name
MyClassV0_0.Name

What you can do to still have a field is have a private constructor and call that constructor from the derived class with the supplied value something like this :

Public MustInherit Class MyBaseClass
    Public ReadOnly Name As String

    Protected Sub New(name As String)
        Me.Name = name
    End Sub
End Class

Public Class MyClassV0_0 : Inherits MyBaseClass
    Private Sub New(name As String)
        MyBase.new(name) ' call base ctor which can initialize ReadOnly field
    End Sub

    Public Sub New()
        Me.New("MyClassV0.0") ' call private ctor of the current class
    End Sub
End Class