1

There is probably a very simple solution for this but my Google Foo fails me :(

I got a plain old object with auto-properties. What I want to do is to change some flag on the property if any of the properties is changed. This can obviously done by messing with all the setters like so ...

private bool _changed;
private string _foo;
public string Foo
{
    get => _foo;
    set { _foo = value; _changed = true;  }
}

But for obvious reasons this is both cumbersome and error prone (these objects have tens of properties). So is there some way to do this generically?

Cheers!

FrankyBoy
  • 1,865
  • 2
  • 18
  • 32
  • 1
    shouldn't be the setter `set { _changed = _foo != value; _foo = value; }` – fubo Aug 16 '18 at 12:23
  • @fubo fair enough, point remains the same ... lots of boilerplate – FrankyBoy Aug 16 '18 at 12:33
  • @rechandler yes, kinda ... the postsharp solution there is neat, I think I'll try to replicate something similar with Castle.Core (can wrap these objects in interfaces no problem). – FrankyBoy Aug 16 '18 at 12:39

2 Answers2

3

There is no built-in solution. You could implement a function for your setters, but it still requires that all setters are correctly calling this function.

Here's an example:

private bool _changed;
private void SetValue<T>(ref T field, T value)
{
    if (!Equals(field, value))
    {
        field = value;
        _changed = true;
    }
}

private string _foo;
public string Foo
{
    get => _foo;
    set => SetValue(ref _foo, value);
}
jeroenh
  • 26,362
  • 10
  • 73
  • 104
  • Thanks. As I feared. I actually might try to do something with Castle.Core (these classes should only be used through an interface anyhow), or maybe a different solution altogether (i.e. force the consumer to call a specfic method to get mutable versions of the object, at which point it gets pretty easy). – FrankyBoy Aug 16 '18 at 12:37
-2

Have your class extend the INotifyPropertyChanged interface. It requires a

protected void OnPropertyChanged(PropertyChangedEventArgs e) function.

Stick your _changed = true in the propertyChange function and it should work :)

    Class X : INotifyPropertyChanged{
    private bool _changed;
    private string _foo;
    public string Foo
    {
        get => _foo;
        set { _foo = value; _changed = true;  }
    }
    protected void OnPropertyChanged(string propertyName){
        _changed = true;
    }


    }
Prodigle
  • 1,757
  • 12
  • 23
  • That does not really fix the point I am making ... compare `public string Foo{ get; set; }`. Also not a generic solution at all, you still got to touch every property. – FrankyBoy Aug 16 '18 at 12:34
  • I don't understand? If you call any setter for the class the function will run. It applies to all properties? – Prodigle Aug 16 '18 at 13:34
  • 1
    @Prodigle, no the OnPropertyChanged event is not "automatically" called. INotifyPropertyChanged is an interface you have to implement, intended for data binding WPF e.a.. You have to manually call the OnPropertyChanged in every setter to make it work. – jeroenh Aug 16 '18 at 19:37