C# 取消订阅其类型参数在泛型方法中指定的泛型类的事件

C# 取消订阅其类型参数在泛型方法中指定的泛型类的事件,c#,generics,events,unsubscribe,C#,Generics,Events,Unsubscribe,如何取消订阅泛型类的事件,该泛型类的类型参数在泛型方法中指定,如下所示 public class ListLayoutControl : Control { NotifyCollectionChangedEventHandler handler = null; public void AttachTo<T, U>(T list) where T : INotifyCollectionChanged, ICollection<U> {

如何取消订阅泛型类的事件,该泛型类的类型参数在泛型方法中指定,如下所示

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);
    }
}
公共类ListLayoutControl:控件
{
NotifyCollectionChangedEventHandler处理程序=null;
公共无效附件(T列表),其中T:INotifyCollectionChanged,ICollection
{
handler=委托(对象发送方,NotifyCollectionChangedEventArgs e)
{
UpdateLayout(list.Count);
};
list.CollectionChanged+=处理程序;
}
受保护的覆盖无效处置(布尔处置)
{
如果(处置)
{
//退订??
}
基地。处置(处置);
}
}

在单独的委托中捕获取消订阅并在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);
}
private Action\u取消订阅处理程序;
公共无效附件(T列表),其中T:INotifyCollectionChanged,ICollection
{
NotifyCollectionChangedEventHandler处理程序=委托(对象发送方,NotifyCollectionChangedEventHandler)
{
UpdateLayout(list.Count);
};
list.CollectionChanged+=处理程序;
_取消订阅处理程序=()=>{
list.CollectionChanged-=处理程序;
};
}
受保护的覆盖无效处置(布尔处置)
{
如果(处置)
{
_取消订阅处理程序?.Invoke();
}
基地。处置(处置);
}

如果可以使用不同的列表多次调用
AttachTo
,请在
List
中收集unsubscribe处理程序并在dispose上全部执行它们。

这里的问题是我无法保留对泛型类的引用,因为它的类型参数是在泛型方法中定义的。所以没有关于取消订阅的参考。我是使用lambda还是委托并不重要。编辑为使用委托来阐明我的观点。@Sinatr无论使用匿名方法还是lambda都没有区别。使用匿名方法对于做同样的事情来说只是一种更加冗长和过时的语法,并且不会影响您取消订阅活动的能力。您只是链接到一个在lambda存在之前发布的问题/答案,这就是它使用匿名方法的原因。@Sinatr是的,我知道这一点,因此我回应了您完全错误的说法,即lambda与匿名方法不同。使用lambda和匿名方法解决这个问题没有什么不同。你得到了编辑问题的机会,只让他们的代码使用过时的语法来完成他们正在做的事情,这种语法在这种情况下没有任何优势,只是更加冗长,不必要。@Sinatr如果你使用lambda而不是匿名方法,那么这个答案将同样有效。你不能使用lambda的说法是完全错误的。你当然可以。是的,您需要将lambda存储在一个委托中(问题的原始版本已经在这样做了),但是您可以使用lambda和匿名方法(同样,如问题的第一个版本所示)轻松地进行存储。我知道你的评论并不是一个答案,它只是一个不正确的陈述。就像一个符咒。谢谢