我有两种类型的节点,一种是MyLinkNode,它用作基础,另一种是继承MyLinkNode的GraphNode。
我尝试使用MyLinkNode创建MyQueue。在我尝试将GraphNode添加到MyQueue之前,一切正常。我不能将MyQueue与GraphNode一起使用,因为它更大。
另一种方法是为GraphNode创建另一个队列,但这意味着如果我有更多类型的节点,我将需要创建大量的类。 有什么建议吗?
public class MyQueue<T> where T : MyLinkNode<T>
{
private T Head;
private T Last;
public MyQueue(){ ... }
public void Enqueue(T item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public class MyGraphQueue
{
//everything is the same with MyQueue besides the Node Type
//I don't want to create like this.
private GraphNode Head;
private GraphNode Last;
public MyGraphQueue(){ ... }
public void Enqueue(GraphNode item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public class MyLinkNode<T>
{
public T data { get; set; }
public MyLinkNode<T> Next { get; set; }
public MyLinkNode<T> Prev { get; set; }
}
public class GraphNode<T> : MyLinkNode<T>
{
public GraphNode()
{
this.adjacencyNodes = new List<GraphNode<T>>();
this.isVisited = false;
}
public List<GraphNode<T>> adjacencyNodes;
public bool isVisited { get; set; }
}
public void BFS<T>(GraphNode<T> v)
{
MyQueue<GraphNode<T>> queue = new MyQueue<GraphNode<T>>(); // error, can't implicit convert GraphNode to MyLinkNode<T>
MyGraphQueue queue = new MyGraphQueue(); //It's how I do now.
}
答案 0 :(得分:1)
MyQueue<T> where T : MyLinkNode<T>
无法接受MyLinkNode<string>
因为这里T
是字符串。但是,显然string
不会从MyLinkNode
我认为解决方案比你想象的要简单。
只需设置队列中值的类型(T
),并在内部使用MyLinkNode<T>
:
public class MyQueue<T>
{
private MyLinkNode<T> Head;
private MyLinkNode<T> Last;
public void Enqueue(MyLinkNode<T> item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public void BFS(GraphNode v)
{
MyQueue<string> queue = new MyQueue<string>(); // no error anymore
queue.Enqueue(v);
}
答案 1 :(得分:0)
这并不奇怪。你需要
public class MyQueue<T, S> where T : MyLinkNode<S>
{
private T Head;
private T Last;
public MyQueue() { }
public void Enqueue(T item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public void BFS(GraphNode v)
{
MyQueue<GraphNode, string> queue = new MyQueue<GraphNode, string>();
}
答案 2 :(得分:0)
这是标准的泛型继承问题。您需要将Queue需要的内容与泛型类型分开。只需为队列约束添加另一个基类。
这将使队列保证所有具有类型T的项目,并且不需要所有具体类型的额外类型或多个类定义。 Eric Lippert有一篇很好的文章here,说明为什么在泛型系统中需要这个限制。
public class CallingClass
{
public void BFS(GraphNode v)
{
MyQueue<GraphNode> queue = new MyQueue<GraphNode>(); // error, can't implicit convert GraphNode to MyLinkNode<T>
// MyGraphQueue queue = new MyGraphQueue(); //It's how I do now.
}
}
public class QueueItem
{
public QueueItem Next { get; set; }
public QueueItem Prev { get; set; }
}
public class MyQueue<T> where T : QueueItem
{
private T Head;
private T Last;
public MyQueue() { }
public void Enqueue(T item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public class MyLinkNode<T>: QueueItem
{
public T data { get; set; }
}
public class GraphNode : MyLinkNode<string>
{
public GraphNode()
{
this.adjacencyNodes = new List<GraphNode>();
this.isVisited = false;
}
public List<GraphNode> adjacencyNodes;
public bool isVisited { get; set; }
}
答案 3 :(得分:-1)
问题来自你的第一行。
使用:
public class MyQueue<T> where T : MyLinkNode<string> { }
而不是:
public class MyQueue<T> where T : MyLinkNode<T> { }
它会正常工作。