2009-11-09 10 views
1

Je reçois une exception NullReferenceException lorsque j'exécute le programme suivant. Je pense que le problème vient du fait que je crée un Line qui contient la classe Point.NullReferenceException lors de la définition des membres d'objets

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

C'est "bas", pas "bas". – Joe

+0

haha ​​chiffres juste :) – Wallter

Répondre

9

Vous essayez de définir des membres d'objets avant de les avoir créés. Par exemple:

class Line 
{ 
    private Point startPoint; 
    private Point endPoint; 

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

Au début du constructeur, startPoint sera une référence nulle. Vous devez créer un nouvel objet Point et attribuer la référence à startPoint, comme ceci:

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

Je suggère également de modifier les méthodes get/définies aux propriétés dès que vous sentez à la hauteur - de cette façon votre code ressemblent beaucoup plus à du C# idiomatique qu'à Java.

+4

Je pense que son problème est qu'il s'attend à ce que le constructeur à chaîne au constructeur par défaut, ce qui bien sûr ne le fait pas ... –

+1

@Reed: Cela peut aider avec le constructeur Rectangle, mais il n'aide pas avec le constructeur de ligne que j'ai montré ici. –

+0

Très vrai :) J'ai remarqué l'autre, mais je pense que c'est en partie un manque de compréhension de la façon dont la construction fonctionne. –

2

vous devez appeler nouveau sur ces objets Point avant de les utiliser autrement, ils restent nuls qui lance cette exception de référence null ...

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

Lorsque vous faites ceci:

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

Vous êtes en fait en créant un nouveau constructeur. Celui-ci sera exécuté, mais votre constructeur par défaut ne fonctionnera pas.

Je suppose que vous vous attendez à ce que le constructeur par défaut public Rectangle() fonctionne également. Vous pouvez facilement accomplir cela en utilisant le chaînage du constructeur. Cela éliminerait votre exception de référence NULL et vous donnerait le comportement que vous attendez, je pense.

Cependant, je recommande également de lire certains des conseils dans d'autres messages, en particulier Tony the Pony's - le fournir de bonnes suggestions, telles que l'utilisation des propriétés.