This is a common misunderstanding of generic types. It is common for people to associate inheritance with generics because the syntax is similar but that simply isn't the case. Let's eliminate generics for a minute and just look at a simple example.
Class BaseType
End Class
Class DerivedType : Inherits BaseType
End Class
Class DerivedType2 : Inherits BaseType
End Class
Dim myDerived As DerivedType = New DerivedType2
I think we can agree that this is not valid. You are attempting to assign a DerivedType2
to DerivedType
and they aren't compatible. They do share the same base type BaseType
but that changes nothing. However this is valid.
Dim myObj As BaseType = New DerivedType2
Because DerivedType2
derives from BaseType
they are compatible. That's exactly how all types work, even generic types. Where people get confused is thinking generic types share a base type because their type parameters do, that is not true. A(Of ISpark)
implements the IMagic(Of ISpark)
interface which itself has no base type. B(Of MySpark)
derives from A(Of MySpark)
which implements the IMagic(Of MySpark)
interface which itself has no base type. They don't share any base type in common, nor even any interface. Hence you cannot assign one instance to another. B(Of MySpark)
does not derive from A(Of ISpark)
.
To dive further into this topic I recommend you read about covariance and contravariance. It is applicable when working with generic interfaces (but not classes) and when you want to support mixing type parameters that may be base and derived types. There are restrictions on what you can do but the interface itself must identify the co-/contra-variance.
In your specific case you're dealing with the base/derived classes so variance won't help here. However you can switch over to using the interfaces and things start working again.
Dim MyB As IMagic(Of ISpark) = New B(Of MySpark)
Think of classes as the implementation of an interface and only use them when you need a specific instance (generally when creating them). The remainder of the time use the interface and, assuming the interface variance is correct, things will work as expected.