Почему этот конкретный родовой тип не может быть заменен конкретным типом, выполняющим тот же контракт? - PullRequest
0 голосов
/ 11 мая 2018

Почему в реализации class Node универсальный тип IEdge<Node> не может быть заменен конкретной реализацией 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 используется в качестве входного параметра в void AddIncoming(TEdgeN edge), чтобы показать, что в этом сценарии out TEdgeN не решает проблему. В противном случае это может быть решено с использованием out TEdgeN, что позволило бы covariant type TEdgeN.

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

Хотя приведенное выше, IEdge<NodeGood> для типа TEdgeN допустимо, мне интересно, почему EdgeBad является недопустимым типом TEdgeN, например:

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

Я полностью осознаю, я что-то наблюдаю, но не должен:

class EdgeBad : IEdge<NodeBad>{}

допустимый тип для TEdgeN в

class NodeBad : INode<TNodeN,TEdgeN>

Я уверен, но предположим, что компилятор жалуется из-за циклических общих ограничений в INode и IEdge при разрешении NodeBad:

  • Чтобы убедиться, что NodeBad является допустимым типом для TNodeN, необходимо знать, что EdgeBad является допустимым типом для TEdgeN
  • Чтобы проверить EdgeBad является допустимым типом для TEdgeN, необходимо знать, что NodeBad является допустимым типом для TNodeE
  • Чтобы убедиться, что NodeBad является допустимым типом для TNodeE, потребуется, чтобы он был действительным типом для TNodeN, поскольку TNodeE используется как тип TNodeN в ограничении interface IEdge
...