Jeremy Friesen
Jeremy Friesen

Reputation: 383

How to override properties in a derived class using generics

I have the following class setup and I don't understand why it won't compile.

I get the following error on "Public Overrides Property F As T"

Can someone explain how I can accomplish this goal? In the end I need to have Class A and Class B where B inherits from A. Where A has an overridable property F of type X, and B overrides F with a type that is derived from X. Any suggestions are appreciated. If this cannot be done, I'd be interested to know why (limitation of .NET?) and how I should go about this.

Public Class X
End Class

Public Class Y
    Inherits X
End Class

Public Class A
    Public Overridable Property F As X
End Class

Public Class A(Of T As X)
    Inherits A
    Public Overrides Property F As T
End Class

Public Class B
    Inherits A(Of Y)
    Public Overrides Property F As Y
End Class

Thank-you!

Upvotes: 0

Views: 683

Answers (2)

Jeremy Friesen
Jeremy Friesen

Reputation: 383

I finally found a solution that does what I'm after using the Shadows keyword.

Imports System

Public Module Module1
    Public Sub Main()
        Dim a As New A()
        Dim b As New B()

        a.F = New X()
        b.F = New Y()

        Dim c As New Container()
        c.Value = a

        Console.WriteLine(c)        

        c.Value = b

        Console.WriteLine(c)        
    End Sub
End Module

Public Class Container
    Public Value As A
    Public Overrides Function ToString() AS String
        Return Value.ToString()
    End Function
End Class

Public Class X
    Public Overrides Function ToString() AS String
        Return "X"
    End Function
End Class

Public Class Y
    Inherits X
    Public Overrides Function ToString() AS String
        Return "Y"
    End Function
End Class


Public Class A
    Public Overridable Property F As X
    Public Overrides Function ToString() AS String
        Return "A" + F.ToString()
    End Function
End Class

Public Class B
    Inherits A
    Public Shadows Property F As Y
    Public Overrides Function ToString() AS String
        Return "B" + F.ToString()
    End Function
End Class

Upvotes: 0

djv
djv

Reputation: 15774

New answer. I don't think it's possible (exactly as you requested it), namely B overrides F with a type that is derived from X, as you saw.

But you could hold Y in a private field in B and expose it through F. Then you'd need to cast F to Y to access whatever functionality Y provides over X. This can be done without changing A.

Public Class X
    Public Overridable Function Z() As String
        Return "X"
    End Function
End Class

Public Class Y
    Inherits X
    Public Overrides Function Z() As String
        Return "Y"
    End Function
    Public Function Foo() As String
        Return "Bar"
    End Function
End Class

Public Class A
    Public Overridable Property F As X
End Class

Public Class B
    Inherits A
    Private _f As Y
    Public Overrides Property F As X
        Get
            Return _f
        End Get
        Set(value As X)
            _f = DirectCast(value, X)
        End Set
    End Property
End Class

Usage:

Dim a As New A()
Dim x As New X()
Dim b As New B()
Dim y As New Y()

a.F = x
Console.WriteLine(a.F.Z)
' Console.WriteLine(DirectCast(a.F, Y).Foo()) ' InvalidCastException

b.F = y
Console.WriteLine(b.F.Z)
Console.WriteLine(DirectCast(b.F, Y).Foo()) ' OK

Output

X
Y
Bar

Upvotes: 1

Related Questions