Calling Default Constructor from Parameterized Constructor
Asked Answered
F

4

6

I would like my default constructor to create & initialize all the objects shown in my code snippet. Then I would like my parameterized constructor to call the default constructor, thus creating and initializing those objects, that can then be used in the parameratized constructor without getting a NullReferenceException.

In this situation, I'm not really sure what the best (most efficient, less code, etc.) way to use constructors is. I'd prefer to use constructor chaining.

Again, I have a very elementary understanding of constructors, so if this is not possible, then please just tell me so, and tell me what you would do in this situation.

class Rectangle
{
    public Line left { get; set; }
    public Line top { get; set; }
    public Line right { get; set; }
    public Line bottom { get; set; }

    public Rectangle() : this(new Line()) { }

    public Rectangle(Line diagnonal) 
    {
        left = new Line();
        top = new Line();
        right = new Line();
        bottom = new Line();

        Point beginningDiagonalPoint = new Point();
        Point endingDiagonalPoint = new Point();

        beginningDiagonalPoint = diagnonal.startPoint;
        endingDiagonalPoint = diagnonal.endPoint;

        int begXC = beginningDiagonalPoint.xCoord;
        int begYC = beginningDiagonalPoint.yCoord;

        int endXC = endingDiagonalPoint.xCoord;
        int endYC = endingDiagonalPoint.yCoord;

        Point rightSideEnd = new Point();

        rightSideEnd.xCoord = endXC;
        rightSideEnd.yCoord = begYC;

        Point leftSideEnd = new Point();

        leftSideEnd.xCoord = begXC;
        leftSideEnd.yCoord = endYC;

        // ----------- right side definitions -------------
        right.startPoint = endingDiagonalPoint;
        right.endPoint = rightSideEnd;

        // ------------ left side definitions --------------
        left.startPoint = beginningDiagonalPoint;
        left.endPoint = leftSideEnd;

        // ------------ top side definitions -------------
        top.startPoint = leftSideEnd;
        top.endPoint = endingDiagonalPoint;

        // ------------ bottom side definitions -----------
        bottom.startPoint = rightSideEnd;
        bottom.endPoint = beginningDiagonalPoint;
    }
}
Ferromagnesian answered 2/12, 2009 at 4:52 Comment(0)
L
3

Usually when you chain constructors it's the other way around: the default constructor calls the more specific constructors with the default values. Say, you have a Point constructor that takes the x and y coordinates. Then you have the default Point constructor call the other one with x = 0 and y = 0. This way you only have to write the code to set the values once.

Here are some things you can improve in your code:

  1. You initialize beginningDiagonalPoint and endingDiagonalPoint to new points and then you overwrite them with references to diagnonal.startPoint and diagnonal.endPoint. You are creating two new points and then discarding them. You don't need to create those new points.

  2. You create new Points and new Lines with the default constructor and then manually set their fields. You could create a point constructor that receives the two coordinates and sets them, and a line constructor that receives the two end points and sets them. Your code would look like this:

     Point rightSideEnd = new Point(endXC, begYC);
     Point leftSideEnd = new Point(begXC, endYC);
    
     right = new Line(endingDiagonalPoint, rightSideEnd);
     left = new Line(beginningDiagonalPoint, leftSideEnd);
     top = new Line(leftSideEnd, endingDiagonalPoint);
     bottom = new Line(rightSideEnd, beginningDiagonalPoint);
    
Loci answered 2/12, 2009 at 5:5 Comment(0)
O
23

I just added

: this()

after the parametrized constructor. It was a bit of guess, but it seems to work.

Ortolan answered 7/2, 2014 at 9:44 Comment(3)
that simply awesomeVendee
unfortunately, it seems to call the base constructor BEFORE executing any code in the custom constructorRanchman
Don't call it base construction, because using : base() wont call the parameter less constructor (of THIS class - if inherited it will call the constructor of the base class). And yes, that is the intended behaviour - If that is not what you wanted then you are initialising incorrectly .Composite
B
3

Your paramaterised constructor already initialises all your properties. So, I think all you need to do is pass some sort of default into the paramaterised constructor from your default constructor.

You need to answer this question yourself: what is a default or empty Rectangle? I'm going to assume it's a zero sized one.

So, presuming a Line takes two points as parameters, I'd do this:

public Rectangle() : this(new Line(new Point(0,0), new Point(0,0))) { }

And in a less condensed format:

public Rectangle() 
    : this(
          new Line(
              new Point(0,0), 
              new Point(0,0)
          )
      ) 
{ }
Bozen answered 2/12, 2009 at 5:1 Comment(0)
L
3

Usually when you chain constructors it's the other way around: the default constructor calls the more specific constructors with the default values. Say, you have a Point constructor that takes the x and y coordinates. Then you have the default Point constructor call the other one with x = 0 and y = 0. This way you only have to write the code to set the values once.

Here are some things you can improve in your code:

  1. You initialize beginningDiagonalPoint and endingDiagonalPoint to new points and then you overwrite them with references to diagnonal.startPoint and diagnonal.endPoint. You are creating two new points and then discarding them. You don't need to create those new points.

  2. You create new Points and new Lines with the default constructor and then manually set their fields. You could create a point constructor that receives the two coordinates and sets them, and a line constructor that receives the two end points and sets them. Your code would look like this:

     Point rightSideEnd = new Point(endXC, begYC);
     Point leftSideEnd = new Point(begXC, endYC);
    
     right = new Line(endingDiagonalPoint, rightSideEnd);
     left = new Line(beginningDiagonalPoint, leftSideEnd);
     top = new Line(leftSideEnd, endingDiagonalPoint);
     bottom = new Line(rightSideEnd, beginningDiagonalPoint);
    
Loci answered 2/12, 2009 at 5:5 Comment(0)
V
1

Your example nearly does what you are asking for. The way you've done it, though, it's the default constructor that calls the paramaterized contructor, giving it a default parameter to work with. There's nothing wrong with doing it this way, it's just not what you said you were looking for.

Also, it's conventional for public properties to begin with capital letters (Left, Right, Top, Bottom instead of left, right, top, bottom). Notice that all the .NET library classes do it this way.

Vc answered 2/12, 2009 at 5:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.