Why can this concrete generic type not be replaced by a concrete type fulfilling the same contract?

84 Views Asked by At

Why can in the implementation class Node the generic type of IEdge<Node> not be replaced by the concrete implementation class Edge:IEdge<Node>.

// For interface definitions INode and IEdge
interface INode<TNodeN, TEdgeN>
where TNodeN : INode<TNodeN, IEdge<TNodeN>>
where TEdgeN : IEdge<TNodeN>{
void AddIncoming(TEdgeN edge); //TEdgeN used as in, (Thanks Evk - see comments!)
}

interface IEdge<TNodeE>
where TNodeE : INode<TNodeE, IEdge<TNodeE>>{}

TEdgeN is used as input parameter in void AddIncoming(TEdgeN edge) to show that in this scenario out TEdgeN does not solve the problem. Otherwise this could be solved using out TEdgeN, which would allow a covariant type TEdgeN.

// This compiles
class EdgeGood : IEdge<NodeGood>{}
class NodeGood : INode<NodeGood, IEdge<NodeGood>>{}

While the above, IEdge<NodeGood> for type TEdgeN is valid, I am wondering why EdgeBad is an invalid type TEdgeN, e.g:

//This does not compile ...
class NodeBad : INode<NodeBad,EdgeBad>{} // error type NodeBad
class EdgeBad : IEdge<NodeBad>{} // error type NodeBad 

I am fully aware, I am overseeing something, but, shouldn't:

class EdgeBad : IEdge<NodeBad>{}

be a valid type for TEdgeN in

class NodeBad : INode<TNodeN,TEdgeN>

I am sure, but assume the compiler complains, because of the cyclic generic constraints in INode and IEdge when resolving NodeBad:

  • To verify NodeBad is a valid type for TNodeN, it would need to know that EdgeBad is a valid type for TEdgeN
  • To verifiy EdgeBad is a valid type for TEdgeN, it would need to know that NodeBad is a valid type for TNodeE
  • To verify NodeBad is a valid type for TNodeE it would need that it is a valid type for TNodeN as TNodeE is used as type TNodeN in the constraint of interface IEdge
0

There are 0 best solutions below