Подтвердить что ты не робот

Подписаться на событие в С#?

Можно ли в С# подключить одно событие к другому, так что излучение первого события будет выдавать второе? Единственный способ, который я вижу, - создать функцию заглушки, которая выдает второе событие и связывает первое событие с этой функцией. Компилятор не хочет подключать событие к событию или событию к функции anonymouse/lambda, которая вызывает другое событие:

class Ui { public event EventHandler OnClick; }
class Logic { public event EventHandler OnExit; }
var ui = new Ui();
var logic = new Logic();
ui.OnClick += logic.OnExit; // Not working.
ui.OnClick += ( a, b ) => logic.OnExit; // Not working either :(.

Может быть, у него есть какой-нибудь декоратор или какая-то черная магия, которая позволяет цепочки событий без функций-заглушек?

4b9b3361

Ответ 1

Вы не можете этого сделать, потому что вы вообще ничего не можете сделать для события из-за объекта, которому он принадлежит, кроме добавления и удаления обработчиков. В частности, вы не можете перечислить существующих зарегистрированных обработчиков, и вы не можете их поднять. В вашем случае "копирование" события по сути является тем же самым, что и маскировка, и позволит вам обойти это ограничение; поэтому он не допускается.

См. этот последний ответ для более подробного объяснения того, почему все так, как они есть. Мне просто не хочется переписывать все это здесь..

В вашем конкретном случае, если вы владеете обоими классами, обходным путем является необходимость их непосредственного взаимодействия - сообщите Ui о соответствующем экземпляре Logic и добавьте обработчики событий в Logic.OnClick в Ui.OnClick.add., Конечно, это вводит сцепление; вы можете уменьшить его до некоторой степени, используя более общие интерфейсы, но вы не можете полностью избавиться от него.

Как примечание, OnClick не является хорошим именем для события .NET. Общее руководство по именованию говорит, что оно должно быть просто ClickOnClick должно быть именем метода protected virtual, который его повышает).

Ответ 2

Вы можете сделать это, спрятав базовое событие для логики, а затем контролируя вызовы Add/Remove, для которых требуется параметр пользовательского интерфейса.

public class UI {
  public EventHandler OnClick;
}
public class Logic {
  private event EventHandler _onExit;
  public void AddOnExit(UI ui, EventHandler e) {
    ui.OnClick += e;
    _onExit += e;
  }
  public void RemoveOnExit(UI ui, EventHandler e) {
    ui.OnClick -= e;
    _onExit -= e;
  }
}