Проще всего запомнить ссылку и не извращаться:
// создаем переменную типа EventHandler
EventHandler handler = null;
// создаем анонимный метод для обработки события и передаем его переменной
handler = (sender, e) =>
{
MessageBox.Show("Hello!");
// удаляем обработчик
((Button)sender).Click -= handler;
};
// добавляем обработчик
button1.Click += handler;
Плохое решение может выглядеть так:
// добавляем обработчик
button1.Click += (sender, e) =>
{
MessageBox.Show("Hello!");
// получаем поле EventClick
var f = typeof(Control).GetField
(
"EventClick",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static
);
// получаем значение EventClick для sender
var k = f.GetValue(sender);
// получаем свойство
var p = sender.GetType().GetProperty
(
"Events", BindingFlags.NonPublic | BindingFlags.Instance
);
// получаем значение свойства Events для sender
var events = (EventHandlerList)p.GetValue(sender, null);
// удаляем обработчик из списка событий
events.RemoveHandler(k, events[k]);
};
В собственных классах проще получить список делегатов при помощи
GetInvocationList (внутри класса):
public class Toster
{
public event EventHandler AnyEvent;
public void AnyEventHarakiri()
{
foreach (Delegate d in this.AnyEvent.GetInvocationList())
{
this.AnyEvent -= (EventHandler)d;
}
}
}
var t = new Toster();
t.AnyEvent += (sender, e) => { };
t.AnyEventHarakiri();
Но вариант со ссылками лучше.