MhdSyrwan
MhdSyrwan

Reputation: 1633

how to override set in C# of automatic properties

I want to use auto-implemented properties, but at the same time I want to call a method every time the property is changed.

public float inverseMass
{
    get;
    set
    {
        onMassChanged();
        inverseMass = value;
    }
}

Does the previous code make a recursive call to the property? If it does, how to implement this?

Upvotes: 37

Views: 43735

Answers (8)

Uwe Keim
Uwe Keim

Reputation: 40746

Use a backing field instead:

public float inverseMass
{
    get
    {
        return _inverseMass;
    }
    set
    {
        _inverseMass = value;
        onMassChanged();
    }
}

private float _inverseMass;

I once read somewhere that the C# guys decided that they wanted to cover the broad of the usage scenarios with those automatic properties, but for special cases you have to go back to good old backing fields.

(To be honest, I believe that Jon Skeet told them how to implement them)

Upvotes: 11

Richard
Richard

Reputation: 1142

The correct answers are given above, but in case you wanted to do this quickly in Visual Studio, you can use Code Snippets instead to generate the property for you.

Have a read of this article which should explain it a bit better: http://www.roelvanlisdonk.nl/?p=1007

If you want, you can even create your own code snippet to add the repetitive code. You could even use it to quickly generate the INotifyPropertyChanged implementation as mentioned above.

Upvotes: 1

Brad Christie
Brad Christie

Reputation: 101614

You would need to break the above out in to private/public members so you don't get recursive problems:

private float _inverseMass;
public float inverseMass
{
  get { return this._inverseMass; }
  set { this._inverseMass = value; onMassChanged(); }
}

However, have you looked in to the INotifyPropertyChanged interface? It does pretty much what you're looking for, and depending on what you're writing it could be supported natively.

public class MyClass : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  private void NotifyPropertyChanged(String property)
  {
    var event = this.PropertyChanged;
    if (event != null)
    {
      event(this, new PropertyChangedEventArgs(property));
    }
  }

  private float _inverseMass;
  public float inverseMass
  {
    get { return this._inverseMass; }
    set { this._inverseMass = value; NotifyPropertyChanged("inverseMass"); }
  }
}

Upvotes: 6

c1xwy
c1xwy

Reputation: 1

public float inverseMass
{
    get;
    set
    {
        if (inverseMass != value)
        {
            inverseMass = value;
            onMassChanged();
        }
    }
}  

Upvotes: -3

Shyju
Shyju

Reputation: 218872

Use a private variable as your back up field for the public property.

private float inverseMass;

public float InverseMass{

   set
   {
        onMassChanged();
        inverseMass=value;
   }
   get
   {
      return inverseMass;
   }

}

Upvotes: 0

vcsjones
vcsjones

Reputation: 141678

That doesn't compile, so it's hard to say if it's recursive or not.

You cannot specify only one part of an automatic property. You will need to use a backing-field in this case:

private float _inverseMass;
public float inverseMass 
{ 
    get { return _inverseMass; }
    set 
    { 
        onMassChanged(); 
        _inverseMass = value; 
    } 
}

Though, an aspected-oriented programming framework like PostSharp may be able to help you with this.

Upvotes: 1

Euphoric
Euphoric

Reputation: 12849

You can't do that in C#.

Its either automatic property or property with backing field.

Upvotes: 6

Gary
Gary

Reputation: 5732

If you provide your own get/set then you need to provide your own storage for the variable.

private float _inverseMass;

public float inverseMass
{
    get { return _inverseMass; }
    set
    {
        _inverseMass = value;
        onMassChanged();
    }
}

Upvotes: 38

Related Questions