开发者

Messing up with generics and graph modelling

I'm pretty new with C# and .NET. I'm trying to model a graph with heterogeneous data. I mean i would like to be able to do something like this:

// 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;
  }
}

Building it this way:

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));

But of course the graph class definition won't let me开发者_如何转开发 do this:

public class Graph<T> where T : CommonBaseClass

I've also tried defining a base class for both person and computer, but of course it's not working. Any help/idea suggestion? I need heterogeneous data because i have to merge list of different nodes.

Thanks for helping!


In cases like this, it can be convenient to have your generic classes derive from non-generic classes. That way, you can refer to all types of Nodes through a simple Node class:

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; }
    }
}

If type object is too primitive, you can use generic constraints instead:

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
{
    // ...
}

Now, your Graph class can allow any type of Node and Edge:

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


You could use an interface (say IGraphItem) instead of a common base class, and have both Nodes and Edges implement IGraphItem.

Then Graph could be changed to:

public class Graph<T> where T : IGraphItem

Let me know if I've misunderstood the question, I'm not 100% sure this is what you were asking about...


Yoy can do this by 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;
    }
}

And use:

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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜