@iRumba

Как отписаться от события, если в качестве подписки лямбда выражение?

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

Объект.Событие += (sender,e) =>
{
sender.Событие -= ...... ;
}

Как мне это осуществить не создавая делегат явно?

Ведь есть же возможность получить дескриптор функции из самой функции, подобно this внутри объекта, для получения дескриптора этого объекта?
  • Вопрос задан
  • 6122 просмотра
Решения вопроса 2
BasmanovDaniil
@BasmanovDaniil
Геймдизайнер-телепат
Храните ссылку на анонимный метод.
public delegate void TestEventHandler(object sender, object e);
public event TestEventHandler TestEvent;

TestEventHandler test = null;
test = (sender, e) => { TestEvent -= test; };
TestEvent += test;
Ответ написан
Проще всего запомнить ссылку и не извращаться:
// создаем переменную типа 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();

Но вариант со ссылками лучше.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Dier_Sergio_Great
@Dier_Sergio_Great
Увлеченный человек
EventHandler handler = (s, e) => MessageBox.Show("Woho");

button.Click += handler;
button.Click -= handler;
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
17 июн. 2021, в 23:09
800 руб./в час
17 июн. 2021, в 22:01
35000 руб./за проект
17 июн. 2021, в 20:24
22000 руб./за проект