0

I have something that looks similar to the following:

public class MyClass
{
    private List<MyOjectMapping> mappings;

    public void Start()
    {
        foreach (var mapping in mappings)
        {
            mapping.ObjectA.PropertyA.PropertyChanged += (s, e) =>
            {
                // do something with mapping.ObjectB
            };
        }
    }

    public void Stop()
    {
        // unhook events
    }
}

public class MyObject : INotifyPropertyChanged
{
    public object PropertyA;
    public object PropertyB;
}

public class MyOjectMapping
{
    public object SomeSortOfKey;
    public MyObject ObjectA;
    public MyObject ObjectB;
}

As you can see, I'm trying to perform some action on the foreach iterator inside the lambda event handler. This works, but doing it this way, I can't figure out how to unhook the events in the Stop() method.

How should I go about hooking up the PropertyChanged event so that I can unhook it later and still access the foreach iterator?

Thanks

Dominic B.
  • 1,897
  • 1
  • 16
  • 31
CatBusStop
  • 3,347
  • 7
  • 42
  • 54
  • Its similar to that question, but it differs in that I am hooking up the events inside a loop and want to use the iterator value. – CatBusStop May 09 '14 at 10:07
  • 1
    How that is different? Answer is you have to store the delegate and remove it later. that's it. – Sriram Sakthivel May 09 '14 at 10:09
  • @Sriram: well, you actually need to store (at least) a pair of `Tuple`, or (more generally) a list of detach delegates. – vgru May 09 '14 at 10:23

1 Answers1

3

If you want to use multiple anonymous event handlers and still be able to detach them later, you can simply store detach actions in a separate list, similar to:

// these actions should be invoked during cleanup
private readonly List<Action> _cleanupActions = new List<Action>();

public void Start()
{
    foreach (var m in mappings)
    {
        // you need both closures in order to reference them inside
        // the cleanup action
        var mapping = m;
        PropertyChangedEventHandler handler = (s, e) => { /* ... */ };

        // attach now
        mapping.PropertyChanged += handler;

        // add a cleanup action to detach later
        _cleanupActions.Add(() => mapping.PropertyChanged -= handler);

}

public void Stop()
{
    // invoke all cleanup actions
    foreach (var action in _cleanupActions)
        action();
}

This is neat as it allows cleanup actions of arbitrary complexity, and it captures correct pairs of objects and their event handlers.

vgru
  • 49,838
  • 16
  • 120
  • 201