impmja
impmja

Reputation: 191

C# properties issue

The other day I bumped into a little problem regarding C#'s properties.

Let's say I have this setup:

public class Point
{
 public float X;
 public float Y;
}

public class Control
{
 protected Point m_Position = new Point();

 public Point Position
 {
  get { return m_Position; }
  set 
  { 
    m_Position = value; }
    // reorganize internal structure..
    reorganize();
  }

  protected reorganize()
  {
   // do some stuff
  }
}

This is all fine, but when it comes to usage, I could write something like:

Control myControl = new Control();
myControl.Position.X = 1.0f;

The thing is, my Control class won't recognize that the Position has been changed because set() hasn't been called.

Is there a way to make Control aware of any Position changes?

Upvotes: 6

Views: 230

Answers (5)

OneSHOT
OneSHOT

Reputation: 6953

This should fix it! I have added a line into your getter that tests to see if the point is null and if it is instantiate it before returning.

public class Point
{
 public float X;
 public float Y;
}

public class Control
{
 protected Point m_Position = new Point();

 public Point Position
 {
  get 
  { 
      if (m_Position == null) m_Position = new Point();
      return m_Position; 
  }
  set 
  { 
    m_Position = value; 
    // reorganize internal structure..
    reorganize();
  }

  }

  protected reorganize()
  {
   // do some stuff
  }
}

HTH

Upvotes: -3

Klaus Byskov Pedersen
Klaus Byskov Pedersen

Reputation: 120917

The statement myControl.Position.X = 1.0f; actually calls the getter and not the setter of your Position property. A way to do what you want to do could be by exposing the X and Y values directly on your class, like so:

public class Control  
{  
 protected Point m_Position = new Point();  

 public float PositionX
 {  
  get { return m_Position.X; }  
  set   
  {   
    m_Position.X = value; }  
    // reorganize internal structure..  
    reorganize();  
  }  

  ... Same thing for PositionY

  protected reorganize()  
  {  
   // do some stuff  
  }  
}

Another way would be to implement some event on the Position class that is raised every time X or Y change. This would entail making X and Y into properties on the Point object, and raising an event each time they are changed. Your control would then have to subscribe to that event.

Upvotes: 2

Captain Sensible
Captain Sensible

Reputation: 5027

1) Make Point.X and Point.Y private. 2) Add properties for X and Y to Point. 3) Add an event to Point that is raised when either X or Y are modified. 4) Register Control as a listener for the events that are raised by Point.

Upvotes: 1

Tom Cabanski
Tom Cabanski

Reputation: 8018

There are a number of options in this case:

  1. Make the X and Y properties of your Point class immutable. That is, require the user to create a new Point whenever X or Y changes.
  2. Setup an event on the Point class and subscribe to it on the Position class. Whenever the Point's X or Y changes, fire the event. The Position class can handle side-effects in the event handler.

In this case, I would suggest option #1

Upvotes: 7

Danvil
Danvil

Reputation: 22981

You could make public class Point a public struct Point. This way, the compiler will force you to write

myControl.Position = new Point() { X = 1.0f, Y = myControl.Position.Y; }

and the property setter is called.

Upvotes: 0

Related Questions