搞乱泛型和图形建模

时间:2010-11-23 23:18:14

标签: c# generics inheritance graph

我是C#和.NET的新手。我正在尝试使用异构数据建模图表。我的意思是我希望能够做到这样的事情:

// Simple graph modeling using generics
public class Node<T>
{
  private T data;
  public Node(T data)
  {
    this.data = data;
  }
}

public class Edge<T, U>
{
  private T source;
  private U destination;

  public Edge(T source, U destination)
  {
    this.source = source;
    this.destination = destination;
  }
}

以这种方式构建:

Node<Person> p = new Node<Person>(new Person("Red John"));
Node<Computer> c = new Node<Computer>(new Computer("MyComputer"));
graph.AddNode(p);
graph.AddNode(c);
graph.AddEdge(new Edge<Person, Computer>(p, c));

但是图形类定义当然不允许我这样做:

public class Graph<T> where T : CommonBaseClass

我也尝试为人和计算机定义基类,但当然它不起作用。任何帮助/想法建议?我需要异构数据,因为我必须合并不同节点的列表。

感谢您的帮助!

3 个答案:

答案 0 :(得分:4)

在这种情况下,让泛型类派生自非泛型类可能很方便。这样,您可以通过简单的Node类来引用所有类型的节点:

public class Node 
{ 
    public Node(object data) 
    { 
        this.Data = obj;
    }

    public object Data { get; protected set; }
}

public class Node<T> : Node
{
    public Node(T data) : base(data) { }

    new public T Data 
    {
        get { return (T)base.Data; }
    }
}

如果类型object过于原始,则可以改为使用通用约束:

public class Node
{
    public Node(IGraphData data)
    {
        this.Data = obj;
    }

    public IGraphData Data { get; protected set; }
}

public class Node<T> : Node where T : IGraphData
{
    public Node(T data) : base(data) { }

    new public T Data
    {
        get { return (T)base.Data; }
    }
}

public class Edge
{
}

public class Edge<T, U> : Edge
    where T : Node where U : Node
{
    // ...
}

现在,您的Graph课程可以允许任何类型的NodeEdge

public class Graph
{
    public void AddNode(Node node) { /* ... */ }
    public void AddEdge(Edge edge) { /* ... */ }
}

答案 1 :(得分:2)

您可以使用接口(比如IGraphItem)而不是公共基类,并让Nodes和Edges都实现IGraphItem。

然后图表可以更改为:

public class Graph<T> where T : IGraphItem

如果我误解了这个问题,请告诉我,我不是100%肯定这就是你所问的......

答案 2 :(得分:1)

您可以interface

执行此操作
public interface INode
{
    List<INode> Nodes { get; set; }
}

public class Person : INode
{
    public List<INode> Nodes { get; set; }

    private string _name;

    public Person(string name)
    {
        _name = name;
    }
}

public class Computer : INode
{
    public List<INode> Nodes { get; set; }

    private int _number;

    public Computer(int number)
    {
        _number = number;
    }
}

并使用:

var person = new Person("P1");
var computer = new Computer(1);

person.Nodes.Add(computer);
computer.Nodes.Add(person);