3

I have this piece of code in my super simple drawing program over here:

if (isMovingRectangle())
{
    selectedRectangle.BoundingBox.Offset(
    currentMousePos.X - mousePosWhenDown.X,
    currentMousePos.Y - mousePosWhenDown.Y);

    Invalidate();
}

I execute these statements every time when the MouseMove event occurs, but why doesn't the Offset method effect the location of the selectedRectangle???? Thank you so much for your answers.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Blip
  • 1,158
  • 1
  • 14
  • 35

1 Answers1

9

Rectangle is a value type.
Calling Offset() either returns a new Rectangle value or modifies the copy returned from the property, depending on which Rectangle you're using.

You need to assign the new Rectangle value back to the property.

In the System.Drawing.Rectangle struct, the Offset() method mutates the value, so you need to save that:

var rect = selectedRectangle.BoundingBox;
rect.Offset(...);
selectedRectangle.BoundingBox = rect;

For more information, see the evils of mutable structs.

Community
  • 1
  • 1
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • And how do I do that? Code? – Blip Dec 29 '13 at 14:32
  • The issue isn't unique to mutable *structs*, but applies to mutable classes as well. When a property of object Foo returns a reference to a mutable object, nothing about the return type will indicate whether or not the returned object will be attached to Foo's state (or any other object's state for that matter). Code which expects to modify something returned from a property is broken unless the property is documented as representing attached state. Open-field structs never encapsulate attached state; other mutable types sometimes do, but assuming that they will is dangerous at best. – supercat Dec 29 '13 at 19:27
  • 2
    The method "Offset" is poorly written, it should return a "Rectangle" object as a result, which would make it obvious that value copy is being made. You do not see a "String" method like this. – Michael Erickson Jan 08 '19 at 23:45