как переопределить набор в C # автоматических свойств - PullRequest
18 голосов
/ 04 января 2012

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

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

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

Ответы [ 8 ]

24 голосов
/ 04 января 2012

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

private float _inverseMass;

public float inverseMass
{
    get { return _inverseMass; }
    set
    {
        _inverseMass = value;
        onMassChanged();
    }
}
8 голосов
/ 04 января 2012

Вместо этого используйте вспомогательное поле:

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

private float _inverseMass;

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

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

5 голосов
/ 04 января 2012

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

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"); }
  }
}
4 голосов
/ 04 января 2012

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

Это либо автоматическое свойство, либо свойство с отступающим полем.

1 голос
/ 04 января 2012

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

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

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

1 голос
/ 04 января 2012

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

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

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

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

0 голосов
/ 04 января 2012
public float inverseMass
{
    get;
    set
    {
        if (inverseMass != value)
        {
            inverseMass = value;
            onMassChanged();
        }
    }
}  
0 голосов
/ 04 января 2012

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

private float inverseMass;

public float InverseMass{

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

}
...