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

Я пытаюсь найти способ добавить делегатов со значениями параметров, но без лямбда-выражений. Я не могу найти архитектуру, которая позволяет это, подходящую для моих нужд. Посмотрите на следующий пример:

public class MyDelegateClass
{
  public class ArgsHolder : EventArgs
  {
    public object[] data;
    public ArgsHolder(params object[] data)
    {
        this.data = data;
    }
  }

  public event EventHandler handler;
  public void Execute()
  {
        ArgsHolder holder = new ArgsHolder(5, 3); // this is the problem
        handler?.Invoke(this, holder);
  }
}

public class OutsideClass
{ 
  public void Start()
  {
    MyDelegateClass del = new MyDelegateClass();
    del.handler += new EventHandler(EventMethod);
    del.Execute();
    del.handler -= new EventHandler(EventMethod);
  }

  private void EventMethod(object sender, EventArgs args)
  {
    ArgsHolder holder = (ArgsHolder)args;
    print(args.data[0] + " " + args.data[1]
  }
}

Проблема в том, что MyDelegateClass устанавливает значения, которых можно было бы избежать с помощью такого лямбда-выражения:

public class OutsideClass
{ 
  public void Start()
  {
    MyDelegateClass del = new MyDelegateClass();
    ArgsHolder holder = new ArgsHolder(5,3);
    del.handler += (sender,args) => EventMethod(this, holder);
    del.Execute();
    del.handler -= (sender,args) => EventMethod(this, holder); // this is now the problem
  }

  private void EventMethod(object sender, EventArgs args)
  {
    ArgsHolder holder = (ArgsHolder)args;
    print(args.data[0] + " " + args.data[1]
  }
}

Это будет работать, но теперь я не могу удалить необходимое событие, потому что объекты-подписчики в моем проекте динамические. Надеюсь, я был достаточно точен в разработке проблемы под рукой :)

Просто сохраните делегата в переменную, а затем подпишитесь/отмените подписку.

eocron 20.12.2020 15:27

Если непонятно, что написал eocron, EventHandler ea = (sender,args) => EventMethod(this, holder); del.handler += ea; del.Execute(); del.handler -= ea;

xanatos 20.12.2020 16:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Удаление обработчиков подписки основано на сравнении ссылок, поэтому, пока вы создаете один делегат из лямбда-выражения и сохраняете его, вы можете удалить его:

public void Start()
{
  MyDelegateClass del = new MyDelegateClass();
  ArgsHolder holder = new ArgsHolder(5,3);
  
  EventHandler eventHandler = (sender,args) => EventMethod(this, holder);

  del.handler += eventHandler;
  del.Execute();
  del.handler -= eventHandler;
}

В более сложном сценарии, когда действие подписки происходит в другом месте, чем отмена подписки, вы должны сохранить ссылку на обработчик в поле.

Другие вопросы по теме