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.