如何使Action <param,param2>与事件的委托类型兼容?</param,param2>

时间:2009-10-16 06:23:36

标签: c# events delegates compatibility action

鉴于以下代码:

void LookupBox_Load(object sender, EventArgs e)
{
    Action d = delegate
        {
            if (!_p.AutoClose)
                CloseLookupBox();
        };

    if (this.ParentForm.MdiParent != null)
        this.ParentForm.MdiParent.Deactivate += delegate { d(); };
    else
        this.ParentForm.Deactivate += delegate { d(); };
}

有没有办法省略委托{d(); }?

void LookupBox_Load(object sender, EventArgs e)
{
    Action<object,EventArgs> d = delegate
        {
            if (!_p.AutoClose)
                CloseLookupBox();
        };

    if (this.ParentForm.MdiParent != null)
        this.ParentForm.MdiParent.Deactivate += d;
    else
        this.ParentForm.Deactivate += d;
}

注意:我想内联

3 个答案:

答案 0 :(得分:4)

绝对 - 将d的类型更改为:

EventHandler d = delegate
    {
        if (!_p.AutoClose)
            CloseLookupBox();
    };

匿名方法不仅适用于Func和Action ...

为了将来参考,您可以基于具有兼容签名的现有委托来创建新委托:

Action<object, EventArgs> d = ...;
EventHandler handler = new EventHandler(d);

但在这种情况下,这种额外的间接是毫无意义的:)

您也可以使用null-coalescing运算符使代码调用稍微简单:

Form form = ParentForm.MdiParent ?? ParentForm;
form.Deactivate += d;

由于您只使用d一次,您可以将其内联,将整个方法转换为:

Form form = ParentForm.MdiParent ?? ParentForm;
form.Deactivate += delegate
{
    if (!_p.AutoClose)
        CloseLookupBox();
};

答案 1 :(得分:2)

不是更好,但如果您使用的是C#3.0,则可以这样做:

if (this.ParentForm.MdiParent != null)
    this.ParentForm.MdiParent.Deactivate += (x,y) => d();
else
    this.ParentForm.Deactivate += (x,y) => d();

答案 2 :(得分:0)

您应该使用EventHandler<MyEventArgs>来定义这些而不是Action委托

  EventHandler<EventArgs> d = delegate        
       {            
            if (!_p.AutoClose)                
               CloseLookupBox();        
       };