2

Is there a way to deny downcast of Base to Derived when Base is holding an instance of Derived? By default it's allowed.

Public Class Base
End Class
Public Class Derived
    Inherits Base
End Class

Public Class Program
    Public Shared Sub Main()
        TakesOnlyBase(New Derived)
    End Sub

    Public Shared Sub TakesOnlyBase(ByVal b As Base) 'Not allowed to make changes in Derived part on the instance
        Dim d As Derived = CType(b, Derived) 'it works since the variable `b` is holding an instance of Derived. How to forbid this cast?
        '...
    End Sub
End Class

The easiest way would be implement conversion function in Derived and just throw an exception.

Public Shared Widening Operator CType(ByVal b As Base) As Derived 'Compiler error: Conversion operators cannot convert from a base type.
    Throw New System.Exception("Not allowed")
End Operator

But conversion from a base type is not allowed. Any other possibilities to override default conversion?

Any other solutions? Thanks for your help.

  • that's the *power* of casts (... and it comes with great responsibility ;) ) ... so no I don't think there is a way (other then reflecting/throwing runtime exceptions) to stop the compiler from accepting those - you have to look outside of most OOP languages (and .NET is 100% mainstream) if you want type-saftey – Random Dev Sep 19 '15 at 20:57
  • Then it sounds like you don't really want an inheritance relationship - maybe look at just having the `Base` class and some kind of encapsulation/factories to allow creation of a "`Base` that has `Derived` behaviour". – Damien_The_Unbeliever Sep 20 '15 at 09:14
  • @Carsten Catching a conversion call in runtime will be acceptable solution. Unfortunately overriding CType from base type is not allowed so what's else? Thanks. PS Can't agree, I don't think outside OOP is stronger type safety. – Robert White Sep 20 '15 at 09:32
  • @Damien Base and Derived behaves very similar and have a lot of common code. Derived adds some additional functionality. Breaking the inheritance will produce double code which would be difficult to maintain. – Robert White Sep 20 '15 at 09:39
  • Perhaps check [Code Contracts](https://msdn.microsoft.com/en-us/library/dd264808(v=vs.110).aspx). (.NET 4.0+) I do not have practical experience with them yet (I am at 3.5), but it is possible that besides runtime checking, you could be able to implement some static checks, I quote: `• Static verification: The static checker can decide whether there are any contract violations without running the program. It checks for implicit contracts, such as null dereferences and array bounds, and explicit contracts.` Focus on preconditions (`Requires`) – miroxlav Sep 20 '15 at 09:55
  • 1
    It won't double the code if you *remove* `Derived`, just have a single class containing the code, but then use some *other* mechanism to achieve the different runtime behaviours. That's what I was trying to suggest. – Damien_The_Unbeliever Sep 20 '15 at 10:05

0 Answers0