NullReferenceException при настройке членов объектов - PullRequest
1 голос
/ 09 ноября 2009

Я получаю исключение NullReferenceException при запуске следующей программы. Я думаю, что проблема заключается в том, что я создаю Line, который содержит класс Point.

using System;

class Driver
{
    static void Main()
    {
        Point pOne = new Point();
        Point pTwo = new Point(2, 1);

        Console.Write("Point pOne: ");
        PrintPoint(pOne);

        Console.Write("Point pthree: ");
        PrintPoint(pTwo);

        Line lOne = new Line(pOne, pTwo);

        Console.WriteLine("Line lOne: ");
        PrintLine(lOne);

        //Rectangle rOne = new Rectangle();
        Rectangle rOne = new Rectangle(lOne);

        Console.WriteLine("Rectangle rOne: ");
        PrintRectangle(rOne);

        Console.ReadLine();
    }

    // The PrintPoint method
    // purpose: display the coordinates of a Point
    // Parameters: a Point object
    // returns: none
    static void PrintPoint(Point p)
    {
        Console.Write("({0},{1})", p.GetXCoord(), p.GetYCoord());
    }

    // the PrintLine method
    // purpose: display the endpoints of a line
    // Parameters: a Line object
    // returns: none
    static void PrintLine(Line aline)
    {
        // notice how we get the point objects from the line
        // and then print their coordinates
        Point p1 = aline.GetStartPoint();
        Point p2 = aline.GetEndPoint();
        Console.Write("      \t");
        PrintPoint(p1);
        Console.Write(" - ");
        PrintPoint(p2);
    }

    static void PrintRectangle(Rectangle aRec)
    {
        Line Left = aRec.getLeft();
        Line Top = aRec.gettop();
        Line Right = aRec.getRight();
        Line Bottem = aRec.getBottem();

        Console.Write("\t Left: ");
        PrintLine(Left);
        Console.Write("\n\t Top: ");
        PrintLine(Top);
        Console.Write("\n\t Right: ");
        PrintLine(Right);
        Console.Write("\n\t Bottem: ");
        PrintLine(Bottem);

    }
}

class Rectangle
{
    private Line left;
    private Line top;
    private Line right;
    private Line bottem;


    public Rectangle()
  {
        Point zero = new Point();

        left.setEndPoint(zero);
        left.SetStartPoint(zero);

        top.setEndPoint(zero);
        top.SetStartPoint(zero);

        right.setEndPoint(zero);
        right.SetStartPoint(zero);

        bottem.setEndPoint(zero);
        bottem.SetStartPoint(zero);

    }

    public Rectangle(Line enter)
    {
        Point stDgl = new Point();
        Point endDgl = new Point();

        stDgl = enter.GetStartPoint();
        endDgl = enter.GetEndPoint();

        //stDgl
        int a = stDgl.GetXCoord();
        int b = stDgl.GetYCoord();

       //endDgl
        int c = endDgl.GetXCoord();
        int d = endDgl.GetYCoord();

        Point endright = new Point();

        endright.SetXCoord(c);
        endright.SetYCoord(b);

        Point endleft = new Point();

        endleft.SetXCoord(a);
        endleft.SetYCoord(d);

        //LEFT
        left.SetStartPoint(stDgl); // **NullReferenceException**
        left.setEndPoint(endleft); 

        //TOP
        top.SetStartPoint(endleft);
        top.setEndPoint(endDgl);

        //RIGHT
        right.SetStartPoint(endDgl);
        right.setEndPoint(endright);

        //BOTTEM
        bottem.SetStartPoint(endright);
        bottem.setEndPoint(stDgl);
    }

    public Line getLeft()
    {
        return left;
    }

    public Line gettop()
    {
        return top;
    }

    public Line getRight()
    {
        return right;
    }

    public Line getBottem()
    {
        return bottem;
    }

}

// the Line class  
class Line
{
    // data members - notice that they are Point objects
    private Point startPoint;
    private Point endPoint;

    // default constructor
    // purpose: initialize data members to zero
    // Parameters: none
    // returns: none
    public Line()
    {
        // notice how we call methods in the Point class
        **startPoint.SetXCoord(0);**         ***NullReferenceException***
        startPoint.SetYCoord(0);
        endPoint.SetXCoord(0);
        endPoint.SetYCoord(0);
    }

    // parameterized constructor
    // purpose: initialize data members to p1 and p2
    // Parameters: Point objects p1 and p2
    // returns: none
    public Line(Point p1, Point p2)
    {
        startPoint = p1;
        endPoint = p2;
    }

    /*
            //LEFT
            Point endleft = new Point();

            endleft.SetXCoord(a);
            endleft.SetYCoord(d);

            left.SetStartPoint(stDgl);
            left.setEndPoint(endleft);
     * */


    // the GetStartPoint method
    // purpose: return the value of the starting point
    // Parameters: none
    // returns: the value of the starting point as a Point object
    public Point GetStartPoint()
    {
        return startPoint;
    }

    // the GetEndPoint method
    // purpose: return the value of the ending point
    // Parameters: none
    // returns: the value of the ending point as a Point object
    public Point GetEndPoint()
    {
        return endPoint;
    }

    // the SetStartPoint method
    // purpose: store the value of the starting point
    // Parameters: the value of the starting point as a Point object
    // returns: none
    public void SetStartPoint(Point p1)
    {
        startPoint = p1;
    }

    // the SetEndPoint method
    // purpose: store the value of the ending point
    // Parameters: the value of the ending point as a Point object
    // returns: none
    public void setEndPoint(Point p2)
    {
        endPoint = p2;
    }
}

// The Point class
class Point
{
    // data members
    private int xCoord;
    private int yCoord;

    // default constructor
    // purpose: initialize data members to zero
    // Parameters: none
    // returns: none
    public Point()
    {
        xCoord = 0;
        yCoord = 0;
    }

    // parameterized constructor
    // purpose: initialize data members to x an y
    // Parameters: two integers x and y
    // returns: none
    public Point(int x, int y)
    {
        xCoord = x;
        yCoord = y;
    }

    // the GetXCoord method
    // purpose: return the value of the x-coordinate
    // Parameters: none
    // returns: the value of the x-coordinate as an int
    public int GetXCoord()
    {
        return xCoord;
    }

    // the GetYCoord method
    // purpose: return the value of the y-coordinate
    // Parameters: none
    // returns: the value of the y-coordinate as an int
    public int GetYCoord()
    {
        return yCoord;
    }

    // the SetXCoord method
    // purpose: stores the value of the x-coordinate
    // Parameters: the value of the x-coordinate as an int
    // returns: none
    public void SetXCoord(int x)
    {
        xCoord = x;
    }

    // the SetYCoord method
    // purpose: stores the value of the y-coordinate
    // Parameters: the value of the y-coordinate as an int
    // returns: none
    public void SetYCoord(int y)
    {
        yCoord = y;
    }
}

Ответы [ 3 ]

9 голосов
/ 09 ноября 2009

Вы пытаетесь установить элементы объектов до того, как создали их. Например:

class Line
{
    private Point startPoint;
    private Point endPoint;

    public Line()
    {
        startPoint.SetXCoord(0);
        ...

В начале конструктора, startPoint будет пустой ссылкой. Вам необходимо создать новый Point объект и назначить ссылку на startPoint, например:

startPoint = new Point();
startPoint.SetXCoord(0); // etc

Я также предлагаю вам изменить методы get / set на свойства, как только вы почувствуете, что это так - ваш код будет больше похож на идиоматический C #, чем на Java.

5 голосов
/ 09 ноября 2009

Когда вы делаете это:

public Rectangle(Line enter)
{ 
   // ...

Вы на самом деле создаете новый конструктор. Этот будет работать, но ваш конструктор по умолчанию не будет работать.

Полагаю, вы ожидаете, что конструктор по умолчанию public Rectangle() также запустится. Вы можете легко сделать это, используя цепочку конструктора.

public Rectangle(Line enter) : this() // Call the default constructor as well
{ 
   // ...

Это устранило бы ваше исключение нулевой ссылки и дало бы вам поведение, которое, я думаю, вы ожидаете.

Тем не менее, я бы также рекомендовал прочитать некоторые из советов в других статьях, особенно Tony's Pony's - они предоставляют несколько хороших советов, таких как использование свойств.

2 голосов
/ 09 ноября 2009

Вы должны вызывать new для этих объектов Point, прежде чем использовать их, в противном случае они остаются нулевыми, что вызывает исключение нулевой ссылки ...

startPoint = new Point();
endPoint = new Point();
...