2009-10-16 4 views
1

Учитывая код ниже:Как сделать Action <param, param2> совместимым с типом делегата события?

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; 
} 

Примечание: Я хочу сделать это встроенный

ответ

4

Абсолютно - изменить тип d, чтобы начать с:

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

Анонимные методы не просто работают с Func и действий ...

Для дальнейшего использования, хотя, вы можете создать новый делегат на основе существующего один с совместимая подпись:

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

Но это дополнительное косвенность бессмысленно в этом случае :)

Вы также можете сделать т он код, вызывающий его немного проще тоже с помощью оператора нуль-коалесцирующий:

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

Как вы тогда только с помощью d один раз, вы можете INLINE его, превращая весь метод в:

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

Упс, ты прав; он использует ванильный EventHandler, поэтому я думаю, что общий не требуется. Использует ли общий ролик какой-либо штраф? – gn22

+0

Ну, вам нужно подписаться с нужным типом, так что вам придется создавать неограниченный экземпляр в любом случае ... –

+0

+1 для предложения коллаборации null. ваш ум действительно может понять намерения каждой программы. – Hao

2

Не намного лучше, но вы могли бы сделать, если вы используете C# 3.0:

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

Вы должны использовать EventHandler<MyEventArgs> определить те вместо от действий делегата

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