A question on the RECT struct

D

Dom

is there a difference between the following:

Rectangle r = new Rectangle (10,20,30,40);
Rectangle r = Rectangle.FromLTRB(10,20,30,40);

Also, I guess I'm not sure why Structs are created with a NEW keyword,
anyway. Aren't they located on the stack, like values, and isn't NEW
used to create space on the heap?

Dom
 
M

Mattias Sjögren

is there a difference between the following:

Rectangle r = new Rectangle (10,20,30,40);
Rectangle r = Rectangle.FromLTRB(10,20,30,40);

Yes. In the first case 30 and 40 will be the width and height
respectively of the rectangle. In the FromLRTB case it will be the
Right and Bottom coordinates.

Also, I guess I'm not sure why Structs are created with a NEW keyword,
anyway. Aren't they located on the stack, like values, and isn't NEW
used to create space on the heap?

No, using the new keyword doesn't imply heap allocation. And structs
aren't always located on the stack.


Mattias
 
D

Dom

Yes. In the first case 30 and 40 will be the width and height
respectively of the rectangle. In the FromLRTB case it will be the
Right and Bottom coordinates.


No, using the new keyword doesn't imply heap allocation. And structs
aren't always located on the stack.

Mattias

Thanks for the reply, but it raised other questions.

1. Ok, I got the order of the arguments wrong, but my point sill
stands. When would I use the first statement and when would I use the
second, even after I get the args correct.

Structs are not ALWAYS located on the heap? When are they, and when
are they not?

Dom
 
P

Peter Duniho

Dom said:
1. Ok, I got the order of the arguments wrong, but my point sill
stands. When would I use the first statement and when would I use the
second, even after I get the args correct.

You would use FromLRTB() if you want to provide exact coordinates for
the corners. You would use the constructor if you want to provide the
top-left coordinate along with a width and a height.

Which one you want to use would usually depend on what information you
have for the purpose of initialize the Rectangle. It is quite common to
have a rectangular area described either way, and so the Rectangle
struct offers both ways to initialize it.

You use the one that is appropriate to your needs.

I thought Mattias made that pretty clear.
Structs are not ALWAYS located on the heap? When are they, and when
are they not?

Mattias wrote "structs aren't always located on the stack". It is also
true that they are not always located on the heap. As with the simple
value types, structs exist wherever you put them. If you have them
contained in a class, they are allocated in the heap with the rest of
the class. If you have them declared as local variables, they are
allocated on the stack with the rest of the local variables.

Hopefully Jon's article clarifies anything else that's not immediately
obvious.

Pete
 
D

Dom

You would use FromLRTB() if you want to provide exact coordinates for
the corners. You would use the constructor if you want to provide the
top-left coordinate along with a width and a height.

Which one you want to use would usually depend on what information you
have for the purpose of initialize the Rectangle. It is quite common to
have a rectangular area described either way, and so the Rectangle
struct offers both ways to initialize it.

You use the one that is appropriate to your needs.

I thought Mattias made that pretty clear.


Mattias wrote "structs aren't always located on the stack". It is also
true that they are not always located on the heap. As with the simple
value types, structs exist wherever you put them. If you have them
contained in a class, they are allocated in the heap with the rest of
the class. If you have them declared as local variables, they are
allocated on the stack with the rest of the local variables.

Hopefully Jon's article clarifies anything else that's not immediately
obvious.

Pete

I hope I'm not a pest, but I guess the question I have is better put
this way: Since there are already 3 overloads for the Rectangle
constructor, why isn't there just a fourth that takes the LTRB args?
I'm just confused about the two calls, one to a constructor, one to a
method.
 
P

Peter Duniho

Dom said:
I hope I'm not a pest, but I guess the question I have is better put
this way: Since there are already 3 overloads for the Rectangle
constructor, why isn't there just a fourth that takes the LTRB args?
I'm just confused about the two calls, one to a constructor, one to a
method.

Here's the declaration for the constructor that takes the top-left
coordinates and the size:

public Rectangle(int x, int y, int width, int height);

Here's the declaration for the constructor that takes the top-left and
bottom-right coordinates:

public Rectangle(int xLeft, int yTop, int xRight, int yBottom);

Here's some code that uses these constructors:

// initialize with top-left and size:
Rectangle rectA = new Rectangle(10, 20, 30, 30);

// initialize with top-left and bottom-right:
Rectangle rectB = new Rectangle(10, 20, 40, 50);

Now, imagine you're the compiler. In the above code example, how do you
know which constructor goes with which assignment?

That should illustrate the issue, but just in case:

The reason that the constructor exists for one and not the other is that
both are method signatures that takes four integers and return a
Rectangle. You can't have two constructors with identical signatures,
so at least one of the methods cannot be a constructor. It has to be a
plain static method that returns a Rectangle.

Now, a valid question might be: why not forego the constructor
altogether and make things consistent by making all of the
initialization methods be plain static methods.

IMHO, the answer to that is that a constructor really is a preferable
way to initialize an object (it's a lot more discoverable, especially
via Intellisense, for one), and so it's worth making as many of the
initialization methods be constructors.

That's one possible answer. I don't know if that's the actual reason
for the current design, but it seems plausible to me.

Pete
 
D

Dom

Here's the declaration for the constructor that takes the top-left
coordinates and the size:

public Rectangle(int x, int y, int width, int height);

Here's the declaration for the constructor that takes the top-left and
bottom-right coordinates:

public Rectangle(int xLeft, int yTop, int xRight, int yBottom);

Here's some code that uses these constructors:

// initialize with top-left and size:
Rectangle rectA = new Rectangle(10, 20, 30, 30);

// initialize with top-left and bottom-right:
Rectangle rectB = new Rectangle(10, 20, 40, 50);

Now, imagine you're the compiler. In the above code example, how do you
know which constructor goes with which assignment?

That should illustrate the issue, but just in case:

The reason that the constructor exists for one and not the other is that
both are method signatures that takes four integers and return a
Rectangle. You can't have two constructors with identical signatures,
so at least one of the methods cannot be a constructor. It has to be a
plain static method that returns a Rectangle.

Now, a valid question might be: why not forego the constructor
altogether and make things consistent by making all of the
initialization methods be plain static methods.

IMHO, the answer to that is that a constructor really is a preferable
way to initialize an object (it's a lot more discoverable, especially
via Intellisense, for one), and so it's worth making as many of the
initialization methods be constructors.

That's one possible answer. I don't know if that's the actual reason
for the current design, but it seems plausible to me.

Pete

Got it. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top