1

I'm a bit confused why i can't return my interface type to my generic variable when it is restricted to that interface type.

Here is what i have setup for my generics:

public class Graph<T, T2> 
    where T : ISegment 
    where T2 : INode

In this class i have the following lines:

T2 currNode = GetCurrentNode();
T segment = GetSegment();
T2 otherNode = segment.OtherNode(currNode);

My segment interface ISegment has the following definition for OtherNode(INode)

INode OtherNode(INode node);

Since I have put where T2 : INode for my class how come it gives me an error that says:

Cannot convert INode to T2

shouldn't this implicitly convert since I restricted my generic T2 to the interface INode?

WDUK
  • 1,412
  • 1
  • 12
  • 29

1 Answers1

1

shouldn't this implicitly convert since I restricted my generic T2 to the interface INode?

That allows the opposite conversion, from T2 to INode. As you can see in segment.OtherNode(currNode), currNode is of type T2, and OtherNode accepts an INode.

The T2 : INode constraint doesn't mean T2 must be exactly the same as INode. It allows T2 to be any type that implements INode. This means that T2 could be any implementation of INode, let's say in this case it's this MyCoolNode class that I wrote, which OtherNode doesn't know about. Now the line basically says:

 MyCoolNode otherNode = segment.OtherNode(currNode);

OtherNode can't possibly return an instance of MyCoolNode! How would the assignment ever make sense?

To fix this, you can constrain T, the type of segment, more. You can say that the segment must be a segment connecting nodes of type T2. This would mean making ISegment generic:

public interface ISegment<TNode> where TNode: INode {
    TNode OtherNode(TNode node);
    ...
}

public class Graph<T, T2> 
    where T : ISegment<T2>
    where T2 : INode
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • So is this the more streamlined way to do it because the only other fix i found was to do an explicit (T2) cast when returning other node. I presume my explicit cast is slow or has issues i am not aware of.. – WDUK Jun 30 '21 at 02:45
  • Casting to `T2` will crash at runtime if `OtherNode` doesn't return the correct type. If you constrain to `ISegment` instead, you can't even use a segment type that returns the wrong node type in the first place. The compiler would complain if you do. @WDUK – Sweeper Jun 30 '21 at 02:47
  • Hmm this is confusing as its still telling me to cast. Where my `INode` interface now has a list of `List>();` when i try to get an element and assign to `T` in the class it says it cannot convert but an explicit cast exists. `Cannot convert ISegment to "T"` Not sure how to fix that. Do i have to change my INode interface to be generic aswell some how ? This is how it looks its pretty bare bones: https://imgur.com/3T4HhH8 – WDUK Jun 30 '21 at 03:03
  • @WDUK So your nodes also knows about the segments to which they are connected? I'm not sure whether putting generics on `ISegment` is a good idea then, or maybe your nodes _shouldn't_ know about the segments. Either way, this seems like another problem, a design problem. It is quite hard to tell you what the best design is without knowing what you are actually doing with your graph. Consider asking a new, more detailed question with more context. – Sweeper Jun 30 '21 at 03:10
  • Well its just a way point graph but my segments needed to be polymorphic since they might represent curves or straight lines so they are different geometric objects. My nodes were an interface because i wanted to represent any 3D mesh object as a node in my graph. – WDUK Jun 30 '21 at 03:12