РЕДАКТИРОВАТЬ: есть четвертый вариант, то есть, чтобы избежать всей этой чепухи и делать то, что предлагает Джон Скит в своем ответе.
Как то так?
public static EventHandler ToEventHandler(this ClickMenuItem clickMenuItem)
{
if (clickMenuItem == null)
return null;
return (sender, e) => clickMenuItem(sender, e);
}
и наоборот:
public static ClickMenuItem ToClickMenuItem(this EventHandler eventHandler)
{
if (eventHandler == null)
return null;
return (sender, e) => eventHandler(sender, e);
}
Обратите внимание, что компилятор определяет, в какие типы делегатов преобразовать лямда-выражения.
РЕДАКТИРОВАТЬ: Если вы предпочитаете, вы также можете использовать анонимных делегатов.
EventHandler eventHandler = delegate(object sender, EventArgs e)
{
clickMenuItem(sender, e);
};
return eventHandler; // can be inlined, type-inference works fine
Третья альтернатива, конечно, это написать класс закрытия самостоятельно. Я бы не стал этого рекомендовать, но он дает вам представление о том, что делает компилятор с анонимными методами. Что-то вроде:
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);
}
}
}