I\'m struggling with some Generic constraint issues when trying to implement a library that allows inheritance and hoping someone can help.
I\'m trying to build up a cl
OK, let’s examine the first one. The error is:
The type 'V' cannot be used as type parameter 'V' in the generic type or method 'Test.Generic_Route'. There is no implicit reference conversion from 'V' to 'Test.Generic_Visit'.
It complains about this declaration:
public abstract class Generic_TSPRoute : Generic_Route
where V : Concrete_TSPVisit
where E : Concrete_TSPNode
This establishes two definitions:
V
is a Concrete_TSPVisit
(or a descendent of it)
E
is a Concrete_TSPNode
(or a descendent of it)
Now let’s see what Generic_Route
lets us put in:
public class Generic_Route
where V : Generic_Visit
where E : GenericElement
The second constraint is fine because Concrete_TSPNode
is a GenericElement
. The first one is problematic: Remember that E
is a Concrete_TSPNode
or a descendent of it, therefore Generic_Visit
could be:
Generic_Visit
, or
Generic_Visit
However, we also know from earlier that V
is a Concrete_TSPVisit
(or a descendent of it).
Concrete_TSPVisit
inherits from Generic_TSPVisit
Generic_TSPVisit
inherits from Generic_Visit
Notice something? This requires it to be a Generic_Visit
. It is emphatically not allowed to be Generic_Visit
.
In other words, imagine I write this:
var route = new Generic_TSPRoute();
According to your hierarchy, Concrete_TSPVisit
is a Generic_Visit
and therefore has a property that looks like
public Concrete_TSPNode Element { get; set; }
If I retrieve a value from this property, it is only guaranteed to be a Concrete_TSPNode
but not necessarily a Concrete_TSPNode_Subclass
.
I’ll leave this answer because it explains the reason for the compiler error, but Enigmativity’s answer actually provides the solution to the problem.