在C#中订阅事件到事件?

时间:2009-10-29 21:25:36

标签: c#

在C#中是否可以将一个事件连接到另一个事件,因此发出第一个事件会发出第二个事件?我能看到的唯一方法是创建一个将发出第二个事件并将第一个事件连接到此函数的存根函数。编译器不希望将事件或事件连接到调用另一个事件的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 :(.

也许它是一些可用的装饰器或一些黑魔法,允许链接没有存根函数的事件?

2 个答案:

答案 0 :(得分:9)

你不能这样做,因为除了添加和删除处理程序之外,你通常不能对拥有它的对象外部的事件做任何事情。特别是,您无法列出现有的注册处理程序,也无法提出它。在你的情况下,“复制”事件基本上是伪装的相同的东西,并允许你绕过这个限制;因此,这是不允许的。

请参阅我的this recent answer以更深入地解释为什么事情就像他们一样 - 我只是不想在这里重新安排它。

对于您的特定情况,如果您拥有这两个类,则解决方法是让它们专门合作 - 让Ui知道关联的Logic实例,并将事件处理程序添加到{{1}在Logic.OnClick实现中。当然,这引入了耦合;你可以通过使用更通用的接口在某种程度上减少它,但你无法完全摆脱它。

作为旁注,Ui.OnClick.add不是.NET事件的好名字。常见的命名指南说它应该只是OnClick(并且Click应该是引发它的OnClick方法的名称。

答案 1 :(得分:3)

您可以通过隐藏Logic的基础事件然后控制需要UI参数的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;
  }
}