How to convert delegate to identical delegate?

后端 未结 5 2037
你的背包
你的背包 2021-02-18 19:04

There are two descriptions of the delegate: first, in a third-party assembly:

public delegate void ClickMenuItem (object sender, EventArgs e)

s

5条回答
  •  走了就别回头了
    2021-02-18 19:13

    EDIT: There's a fourth option, i.e. to avoid all this nonsense and do what Jon Skeet suggests in his answer.

    Something like this?

    public static EventHandler ToEventHandler(this ClickMenuItem clickMenuItem)
    {
        if (clickMenuItem == null)
            return null;
    
       return (sender, e) => clickMenuItem(sender, e);
    }
    

    and the reverse:

    public static ClickMenuItem ToClickMenuItem(this EventHandler eventHandler)
    {
       if (eventHandler == null)
           return null;
    
       return (sender, e) => eventHandler(sender, e);
    }
    

    Note that the compiler infers which delegate-types to convert the lamda-expressions to.

    EDIT: If you prefer, you can use anonymous-delegates too.

    EventHandler eventHandler =  delegate(object sender, EventArgs e)
                                 { 
                                    clickMenuItem(sender, e); 
                                 };
    return eventHandler; // can be inlined, type-inference works fine
    

    The third alternative of course, is to write a closure-class yourself. I wouldn't really recommend this, but it gives you an idea of what the compiler does with the anonymous methods. Something like:

    public static class ClickMenuItemExtensions
    {
        public static EventHandler ToEventHandler(this ClickMenuItem clickMenuItem)
        {
            if (clickMenuItem == null)
                return null;
    
            // new EventHandler not required, included only for clarity 
            return new EventHandler(new Closure(clickMenuItem).Invoke);
        }
    
        private sealed class Closure
        {
            private readonly ClickMenuItem _clickMenuItem;
    
            public Closure(ClickMenuItem clickMenuItem)
            {
                _clickMenuItem = clickMenuItem;
            }
    
            public void Invoke(object sender, EventArgs e)
            {
                _clickMenuItem(sender, e);
            }
        }
    }
    

提交回复
热议问题