Home c# Nice way to add an event to a property change

Nice way to add an event to a property change

Author

Date

Category

There is a class that contains a property, and an event that should occur when this property changes:

class A
{
  public Value {get; set; }
  public event EventHandler ValueChanged;
}

There are two other classes that can change this property and should be notified if the property was not changed by them. Or rather, even this: they can be notified in any case, but it should be possible to find out who exactly initiated the change.

The problem is that in Value {set; } only a new value is passed, and you won’t be able to find out the initiator. And the only way out that I see is to replace Value {get; set;} to set (newValue, initiator); get ();


Answer 1, authority 100%

There is also a DependencyProperty. It seems to be considered a more advanced mechanism than the .NET component model entities. Although it is also not entirely clear how this could help.

I would make the property read-only, and change its value through a method with two parameters. Before that, I would have thought about how well the application is designed. Knowing who changed the property of the object that triggered the event is contrary to the idea of ​​events as such. Maybe you just don’t want to throw a property change event if the value hasn’t actually changed?


Answer 2, authority 95%

C # already has a mechanism for this kind of notifications – INotifyPropertyChanged.

An example of interaction of such a class and notifying all subscribers when any property of an object changes:

public class MyClass: INotifyPropertyChanged
{
  private string imageFullPath;
  protected void OnPropertyChanged (PropertyChangedEventArgs e)
  {
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler! = null)
      handler (this, e);
  }
  protected void OnPropertyChanged (string propertyName)
  {
    OnPropertyChanged (new PropertyChangedEventArgs (propertyName));
  }
  public string ImageFullPath
  {
    get {return imageFullPath; }
    set
    {
      if (value! = imageFullPath)
      {
        imageFullPath = value;
        OnPropertyChanged ("ImageFullPath");
      }
    }
  }
  public event PropertyChangedEventHandler PropertyChanged;
}

It is also perfectly possible to do separate processing for any specific properties (ImageFullPath in the case of this example):

protected void OnImageFullPathChanged (EventArgs e)
{
  EventHandler handler = ImageFullPathChanged;
  if (handler! = null) handler (this, e);
}
public event EventHandler ImageFullPathChanged;

Answer 3, authority 50%

The first way you yourself described is to actually make a property change through a method with two parameters.

A more “confusing” way – add an initiator object to the event, and when the event is called from the setter, go up the stack and use Reflection to define the class from which the call is made. I don’t know if this is what you need, but I used a similar approach in some places. It is bad, first of all, because of its unpredictable behavior when called from lambdas and other anonymous things.

A slightly better behavior can be achieved by setting additional attributes on potential change initiators (classes or methods) and searching the stack for the class (or method, depending on what is needed) that makes the call.

P.S. about reading the call stack you can read here .

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions