Is there a "preferred" way to update properties based on other properties?

A

Adam Clauss

Let's say I have a class that represents a rectangle:

class Rectangle
{
private int width;
private int height;
private int area;

public int Width
{
get { return width; }
set { width = value; }
}

public int Height
{
get { return height; }
set { height= value; }
}

public int Area
{
get { return area; }
}
}

Obviously, area does not represent anything based on that. How to best
keep area in sync is the purpose of this question. One way would be to
simply get rid of the variable area, and make the property calculate it:

public int Area
{
get { return Width * Height }
}

But, for the sake of argument, lets pretend Width * Height was actually
a more expensive calculation, and we would prefer to cache the value
when it changes, rather than recalculate it every time Area gets called.

One option then, would be for the Width and Height properties to update
area, something like:
public int Width
{
get { return width; }
set
{
width = value;
UpdateArea(); // some method that performs the area calculation -
it's implementation is not relevant
}
}

Another option, assuming you were following a pattern similar to typical
..NET UI components (maybe other components too), would be to add events
for each of the properties changing:

public EventHandler WidthChanged;

public int Width
{
get { return width; }
set
{
if (width != value)
{
width = value;
WidthChanged(); // ignore unsafe event invocation, just making
the point
}
}

If there is such an event defined, is there a "good" way to update
Area? Should width/height directly know that they affect area and
therefore call UpdateArea(). Or, should the Rectangle class register an
event handler to it's own event (WidthChanged/HeightChanged) and invoke
UpdateArea() from there.

Any thoughts on the "best pattern"? Is there even a general rule, or is
it more just a case-by-case basis? Or should a class almost NEVER have
a reason to subscribe to its own event?

-Adam
 
R

Random

If there is such an event defined, is there a "good" way to update
Area?  Should width/height directly know that they affect area and
therefore call UpdateArea().  Or, should the Rectangle class register an
event handler to it's own event (WidthChanged/HeightChanged) and invoke
UpdateArea() from there.

Personally, I like a pattern where you somehow mark the variable in
question as "dirty" and when it's needed, recaculate it, storing the
results. Below is what I'm suggesting, using a nullable type to mark
area as dirty or valid:

class Rectangle
{
int width;
int height;
int? area;

public int Width
{
get
{
return width;
}
set
{
width = value;
area = null;
}
}

public int Height
{
get
{
return height;
}
set
{
height = value;
area = null;
}
}

public int Area
{
get
{
if (!area.HasValue)
{
area = Width * Height;
}
return area.Value;
}
}
}
 
A

Arne Vajhøj

Let's say I have a class that represents a rectangle:

class Rectangle
{
private int width;
private int height;
private int area;

public int Width
{
get { return width; }
set { width = value; }
}

public int Height
{
get { return height; }
set { height= value; }
}

public int Area
{
get { return area; }
}
}

Obviously, area does not represent anything based on that. How to best
keep area in sync is the purpose of this question. One way would be to
simply get rid of the variable area, and make the property calculate it:

public int Area
{
get { return Width * Height }
}

But, for the sake of argument, lets pretend Width * Height was actually
a more expensive calculation, and we would prefer to cache the value
when it changes, rather than recalculate it every time Area gets called.

One option then, would be for the Width and Height properties to update
area, something like:
public int Width
{
get { return width; }
set
{
width = value;
UpdateArea(); // some method that performs the area calculation - it's
implementation is not relevant
}
}

Another option, assuming you were following a pattern similar to typical
.NET UI components (maybe other components too), would be to add events
for each of the properties changing:

public EventHandler WidthChanged;

public int Width
{
get { return width; }
set
{
if (width != value)
{
width = value;
WidthChanged(); // ignore unsafe event invocation, just making the point
}
}

If there is such an event defined, is there a "good" way to update Area?
Should width/height directly know that they affect area and therefore
call UpdateArea(). Or, should the Rectangle class register an event
handler to it's own event (WidthChanged/HeightChanged) and invoke
UpdateArea() from there.

Any thoughts on the "best pattern"? Is there even a general rule, or is
it more just a case-by-case basis? Or should a class almost NEVER have a
reason to subscribe to its own event?

The "set the dirty flag" method should be the one that creates
the least work - and all this is only relevant if it is a lot of
work.

For the majority of cases, then just doing the calc in the get
should be fine.

Arne
 
R

RayLopez99

Let's say I have a class that represents a rectangle:
   public int Area
   {
     get { return area; }
   }

}

public int Height
{
get { return height; }
set { height= value; }
}

I thought you were going to ask if Height=value; is proper, and I've
seen it done this way too, though I usually set the private variable
to value.

RL
 
P

Patrice

I would second Random response.

Additionaly :
- if you compute immediately Area (remember you said us it was costly) and
that the consumer of the class changes both the Width and Height than you'll
call this costly method twice and additionaly the result could be never
actually used.

With the "dirty" pattern, if not used you don't even spend time to compute
it. It will be computed again but just when (and if) needed...
 

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