Я пытаюсь найти способ добавить делегатов со значениями параметров, но без лямбда-выражений. Я не могу найти архитектуру, которая позволяет это, подходящую для моих нужд. Посмотрите на следующий пример:
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, EventHandler ea = (sender,args) => EventMethod(this, holder); del.handler += ea; del.Execute(); del.handler -= ea;





Удаление обработчиков подписки основано на сравнении ссылок, поэтому, пока вы создаете один делегат из лямбда-выражения и сохраняете его, вы можете удалить его:
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;
}
В более сложном сценарии, когда действие подписки происходит в другом месте, чем отмена подписки, вы должны сохранить ссылку на обработчик в поле.
Просто сохраните делегата в переменную, а затем подпишитесь/отмените подписку.