Not exactly. Since enums are really just integers, you can do something like this:
Enum BaseTypes
A = 1
B
C
End Enum
'start with an arbitrarily high number to avoid colliding with BaseTypes
Enum DerivedTypes
D = 10
E
F
End Enum
'ditto
Enum OtherDerivedTypes
G = 20
H
I
End Enum
You can pass the derived types into a method expecting the base type by casting them as the base type, e.g. (BaseTypes)DerivedTypes.E
This will only work of course assuming you don't do any non-virtual case statements or bound-checking in your BaseClass
and your derived classes each override the relevant methods, like so:
Base class:
Private Overridable Sub HandleValue(ByVal val As BaseTypes)
Select Case val
Case BaseTypes.A
'do something
Exit Select
Case BaseTypes.B
'do something else
Exit Select
End Select
End Sub
Derived class:
Private Overloads Overrides Sub HandleValues(ByVal val As BaseTypes)
Select Case DirectCast(val, DerivedTypes)
Case DerivedTypes.D
'do something D-ish
Exit Select
Case DerivedTypes.E
'do something E-like
Exit Select
Case Else
'what we got wasnt a DerivedType, pass it off to the base
MyBase.HandleValues(val)
Exit Select
End Select
End Sub
Note this only works for a linear inheritance chain - e.g. it breaks down if there are sibling derived classes on the same level, since it becomes very difficult for them to properly hand off enum values to the correct sibling, rather than a parent who simply deals with a more limited scope.
Generally I would not recommend this approach for open-ended extensibility. As you can see, it is a maintenance nightmare. If you have a well-defined, scoped use set that will be mostly set in stone, then this is workable.