Как переопределить набор в С# автоматических свойств

Я хочу использовать автоматически реализованные свойства, но в то же время я хочу вызывать метод каждый раз, когда свойство изменяется.

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

Предоставляет ли предыдущий код рекурсивный вызов свойства? Если это так, как это реализовать?

Ответы

Ответ 1

Если вы предоставляете свой собственный get/set, вам необходимо предоставить собственное хранилище для переменной.

private float _inverseMass;

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

Ответ 2

Вместо этого используйте поле поддержки:

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

private float _inverseMass;

Я когда-то читал где-то, что ребята из С# решили, что они хотят покрыть широкие сценарии использования этими автоматическими свойствами, но для особых случаев вам нужно вернуться к старым старым полям поддержки.

(Честно говоря, я считаю, что Джон Скит рассказал им, как их реализовать)

Ответ 3

Вы не можете сделать это на С#.

Его либо автоматическое свойство, либо свойство с полем поддержки.

Ответ 4

Вам нужно было бы разбить вышеприведенное для частных/общественных участников, чтобы у вас не возникали рекурсивные проблемы:

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

Однако вы заглянули в интерфейс INotifyPropertyChanged? Он делает в значительной степени то, что вы ищете, и в зависимости от того, что вы пишете, он может поддерживаться изначально.

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"); }
  }
}

Ответ 5

Это не компилируется, поэтому трудно сказать, рекурсивный или нет.

Вы не можете указать только одну часть автоматического свойства. Вам нужно будет использовать резервное поле в этом случае:

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

Хотя, аспектно-ориентированная структура программирования, такая как PostSharp, может помочь вам в этом.

Ответ 6

Правильные ответы даны выше, но если вы захотите сделать это быстро в Visual Studio, вместо этого вы можете использовать фрагменты кода, чтобы сгенерировать для вас свойство.

Прочитайте эту статью, которая должна объяснить ее немного лучше: http://www.roelvanlisdonk.nl/?p=1007

Если вы хотите, вы даже можете создать свой собственный фрагмент кода, чтобы добавить повторяющийся код. Вы даже можете использовать его для быстрого создания реализации INotifyPropertyChanged, как указано выше.

Ответ 7

Используйте приватную переменную в качестве резервного поля для общедоступного свойства.

private float inverseMass;

public float InverseMass{

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

}

Ответ 8

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