Event unsubscription via anonymous delegate

This question already has an answer here:

  • Unsubscribe anonymous method in C# 11 answers

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

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

    Warning! Accepted answer from Steven is wrong , all it does is just masking a problem that resharper is warning about.

    Every time given code is executed

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

    you'll get a fresh (since you may capture different listView ) instance of anonymous delegate saved to func , an instance that's not subscribed to any events yet, so in turn this code

    listView.PreviewTextInput -= func;
    

    will effectively do nothing, since you cant unsubscribe from an event you're not subscribed to. This will lead to mind-boggling bugs like event handlers 'called twice', memory leaks etc.

    Actually, Jon Skeet says it may work in some cases:

    The C# specification explicitly states (IIRC) that if you have two anonymous functions (anonymous methods or lambda expressions) it may or may not create equal delegates from that code.

    eg when compiler doesn't generate new instance every time, you'll see nice behavior.

    But that's not reliable and certainly wouldn't work in case described in starter question with captured variable listView .

    So my suggestion is:

    Use anonymous functions as event handlers ONLY if you will never have to unsubscribe.

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

    上一篇: 为事件处理程序使用lambda表达式的最佳实践

    下一篇: 通过匿名代理进行事件取消订阅