通过匿名代理进行事件取消订阅

这个问题在这里已经有了答案:

  • 在C#11中取消订阅匿名方法的答案

  • 你可以将lamdba提取到一个变量中:

    EventHandler func = (sender, e) =>
        listView_PreviewTextInput(sender, e, listView);
    
    if (((bool)e.NewValue))
    {
        listView.PreviewTextInput += func;
    }
    else
    {
        listView.PreviewTextInput -= func;
    }
    

    警告! 从Steven接受的答案是错误的 ,它所做的只是掩盖了resharper警告的问题。

    每次给定的代码被执行

     EventHandler func = (sender, e) =>
         listView_PreviewTextInput(sender, e, listView);
    

    你会得到一个全新的(因为你可能捕获不同的listView )匿名委托的实例保存为func ,一个尚未订阅任何事件的实例,所以这个代码

    listView.PreviewTextInput -= func;
    

    将无效,因为您无法退订您未订阅的活动。 这将导致令人难以置信的错误,例如事件处理程序“两次调用”,内存泄漏等。

    事实上,乔恩Skeet说它可能在某些情况下工作:

    C#规范明确指出(IIRC)如果您有两个匿名函数(匿名方法或lambda表达式),它可能会或可能不会从该代码创建相同的委托。

    例如,当编译器每次都不会生成新的实例时,您会看到很好的行为。

    但这并不可靠,并且在使用捕获的变量listView进行初始问题描述的情况下肯定不起作用。

    所以我的建议是:

    只有在不需要退订的情况下,才可以使用匿名函数作为事件处理程序。

    链接地址: http://www.djcxy.com/p/51439.html

    上一篇: Event unsubscription via anonymous delegate

    下一篇: Using foreach iterator value inside EventHandler