C#泛型,其中T类:(继承类)

时间:2017-05-27 14:31:30

标签: c# inheritance data-structures generic-list

我有两种类型的节点,一种是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.

 }

4 个答案:

答案 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> { }

它会正常工作。