Search code examples
c#genericseventsunsubscribe

Unsubscribe from an event of a generic class whose type parameter is specified within a generic method


How do I unsubscribe from an event of a generic class whose type parameter is specified within a generic method as follows?

public class ListLayoutControl : Control
{
    NotifyCollectionChangedEventHandler handler = null;

    public void AttachTo<T, U>(T list) where T : INotifyCollectionChanged, ICollection<U>
    {
        handler = delegate (object sender, NotifyCollectionChangedEventArgs e)
        {
            UpdateLayout(list.Count);
        };
        list.CollectionChanged += handler;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // unsubscribe ??
        }
        base.Dispose(disposing);
    }
}

Solution

  • Capture unsubscribe in separate delegate and execute it on dispose:

    private Action _unsubscribeHandler;
    public void AttachTo<T, U>(T list) where T : INotifyCollectionChanged, ICollection<U>
    {
        NotifyCollectionChangedEventHandler handler = delegate (object sender, NotifyCollectionChangedEventArgs e)
        {
            UpdateLayout(list.Count);
        };
        list.CollectionChanged += handler;
        _unsubscribeHandler = () => {
            list.CollectionChanged -= handler;     
        };
    }
    
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _unsubscribeHandler?.Invoke();
        }
        base.Dispose(disposing);
    }
    

    If it's possible to call AttachTo multiple times with different lists - collect unsubscribe handlers in List<Action> and on dispose execute them all.