How to avoid anonymous methods in a "dynamic" event subscription?

How can I reorganize a method

private void ListenToPropertyChangedEvent(INotifyPropertyChanged source, string propertyName) { source.PropertyChanged += (o, e) => { if (e.PropertyName == propertyName) MyMagicMethod(); }; } 

if i would like to avoid using an anonymous method here?

+6
source share
3 answers

Implement a closure that is explicitly created by the lambda explicitly:

 private void ListenToPropertyChangedEvent(INotifyPropertyChanged source, string propertyName) { var listener = new MyPropertyChangedListener(propertyName); source.PropertyChanged += listener.Handle; } class MyPropertyChangedListener { private readonly string propertyName; public MyPropertyChangedListener(string propertyName) { this.propertyName = propertyName; } public void Handle(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == this.propertyName) { // do something } } } 
+4
source

You can handle this by having one event handler for all instances that uses the dictionary of instances that you follow:

 private Dictionary<INotifyPropertyChanged, List<string>> sourceMap = new Dictionary<INotifyPropertyChanged, List<string>>(); private void ListenToPropertyChangedEvent(INotifyPropertyChanged source, string propertyName) { if (sourceMap.ContainsKey(source)) sourceMap[source].Add(propertyName); else { source.PropertyChanged += source_PropertyChanged; sourceMap[source] = new List<string> { propertyName }; } } void source_PropertyChanged(object sender, PropertyChangedEventArgs e) { var source = sender as INotifyPropertyChanged; var list = sourceMap[source]; if (list.Contains(e.PropertyName)) MyMagicMethod(); } 

There is no error checking or removal in this version, but it demonstrates the technique. This is especially valuable if you listen to multiple properties from the same source . This is because it adds only one PropertyChanged event handler for each instance.

+1
source

I'm not sure exactly what you are trying to achieve or why you do not want to use anonymous methods, but you could do something more general:

  private PropertyChangedEventHandler GetHandler (Func<PropertyChangedEventArgs, bool> test, Action toInvoke) { return new PropertyChangedEventHandler( (o, e) => { if (test(e)) toInvoke(); }); } 

Then you can use it like this:

  source.PropertyChanged += GetHandler ( p => p.PropertyName == propertyName, MyMagicMethod ); 

Thus, your test and group of target methods can be easily replaced. Your event handler is also strongly typed, not anonymous.

0
source

Source: https://habr.com/ru/post/891612/


All Articles