NullReferenceException durante l'impostazione membri di oggetti
-
19-09-2019 - |
Domanda
mi stanno un NullReferenceException quando si esegue il seguente programma. Credo che il problema viene dal fatto che sto creando un Line
, che contiene la classe 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;
}
}
Soluzione
Si sta cercando di impostare i membri di oggetti prima di aver creato. Ad esempio:
class Line
{
private Point startPoint;
private Point endPoint;
public Line()
{
startPoint.SetXCoord(0);
...
All'inizio del costruttore, startPoint
sarà riferimento null. È necessario creare un nuovo oggetto Point
e assegnare il riferimento a startPoint
, in questo modo:
startPoint = new Point();
startPoint.SetXCoord(0); // etc
Ho anche suggerisco di cambiare ottenere metodi / Set per proprietà, non appena si sente all'altezza -. In questo modo il codice sarà molto più simile idiomatica C # di Java
Altri suggerimenti
Quando si esegue questa:
public Rectangle(Line enter)
{
// ...
In realtà si sta creando un nuovo costruttore. Questo verrà eseguito, ma il vostro costruttore di default non verrà eseguito.
Sto indovinando vi aspettate il public Rectangle()
costruttore predefinito per aver eseguito pure. Si può facilmente ottenere questo risultato utilizzando il costruttore concatenamento.
public Rectangle(Line enter) : this() // Call the default constructor as well
{
// ...
Questo sarebbe eliminare il vostro un'eccezione di riferimento null, e vi darà il comportamento credo che vi aspettate.
Tuttavia, mi piacerebbe anche raccomando di leggere alcuni dei consigli in altri post, in particolare Tony del pony -. il fornire alcuni buoni suggerimenti, come l'utilizzo di proprietà
è necessario chiamare nuovo su quegli oggetti Point prima di utilizzarli altrimenti restano nulla che getta tale eccezione riferimento null ...
startPoint = new Point();
endPoint = new Point();