简体   繁体   中英

On how to properly use the following classes on graphs in C#

At the moment, I am trying to learn C# through implementing various algorithms. I asked this question on how to represent a graph in C# , and the user michaelb suggested to use classes. I tried to construct a graph with these classes in the following code.

I'm used to classes having a constructor, in which I can set the fields of the object I'm creating, but these classes only seem to have the default no-arguments constructors. I have three questions:

Are the "entities" in the classes even fields, eg does public Node From; constitute a field in the Edge class?

Isn't it weird that the classes Edge and Node refer to each other? It looks like a two-fold self-referential loop, in which they are defined in terms of each other.

When I try to run my code, I get the error at the step G.Nodes.Add(v1); that says System.NullReferenceException . What did I do wrong, and what would be the proper way of using these classes?

Thanks.

using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        Graph G = new Graph();
        Node v1 = new Node();
        Node v2 = new Node();
        Node v3 = new Node();
        G.Nodes.Add(v1);
        G.Nodes.Add(v2);
        G.Nodes.Add(v3);
        Edge e1 = new Edge();
        Edge e2 = new Edge();
        e1.From = v1;
        e1.To = v2;
        e2.From = v2;
        e2.To = v3;
        v1.EdgesOut.Add(e1);
        v1.EdgesIn.Add(e1);
        v2.EdgesOut.Add(e2);
        v3.EdgesIn.Add(e2);

        Console.WriteLine(G);
        Console.ReadKey();

    }
}

class Edge
{
    public Node From;
    public Node To;
}

class Node
{
    public List<Edge> EdgesIn;
    public List<Edge> EdgesOut;
}

class Graph
{
    public List<Node> Nodes;
}

1 - Whether the fields are public or not or even designed as properties is entriely up to you. But yes, they are fields or members alright.

2 - No these classes neither contain 'defintions' nor 'things'. They simply contain references . Perfectly fine. Think of the usualy TreeNode class which itself contains a List<Node> Nodes and a Node ParentNode .. Self- referential , yes and as you noticed null at first, but no problem.

3 - Yes, the default constructors are indeed a bit shabby for those classes. Therefore you go missing the instantiation of the List<T> fields. Either add this

  Graph G = new Graph();
  ..
  G.Nodes = new List<Node>();  //  <<<---
  G.Nodes.Add(v1);

..etc, or improve on the classes by providing a real contructor with the missing line!

public Graph() {Nodes = new List<Node>();}

How a constructor is designed and also how many of them you write is again up to you and what you want/need/like..

with regard to errors, missing G.Nodes = new List<Node>(); G.Nodes.Add(v1); G.Nodes.Add(v2); G.Nodes.Add(v3); G.Nodes = new List<Node>(); G.Nodes.Add(v1); G.Nodes.Add(v2); G.Nodes.Add(v3);

and

v1.EdgesOut = new List<Edge>(); v1.EdgesOut.Add(e1);

...

Ditto for the following

Yes From constitute a field in the Edge class

public is only there for accessibility

Yes Edge and Node refer to each other, but this is not a problem, because at the creation of such an object, the program places null references in the front of the lists and classes.

The programmer must create new objects and point to these objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM