如何在C#中引用事件

我有以下类,它有一个名为LengthChanged公共事件:

 class Dimension { public int Length { get { return this.length; } set { if (this.length != value) { this.length = value; this.OnLengthChanged (); } } protected virtual void OnLengthChanged() { var handler = this.LengthChanged; if (handler != null) { handler (this, System.EventArgs.Empty); } } public event System.EventHandler LengthChanged; private int length; } 

我希望能够在一个名为Observer的方法中注册/取消注册此事件的处理程序,该方法对Dimension类一无所知。 我想出了两个场景,其中没有一个真的令人满意:

  1. 使用LengthChanged事件定义ILengthChanged接口,然后确保Dimension实现ILengthChanged 。 然后我必须为我定义的每个接口提供Observer方法的一个实现。 这绝不是通用的。 我真的希望能够简单地传入对System.EventHandler事件的引用。

  2. 使用System.Action回调在Observer方法中注册和取消注册事件处理程序,就像这样:

    class Foo {public void Observer(System.Action register,System.Action unregister){register(this.MyEventHandler);

      // keep track of the unregister callback, so that we can unregister // our event handler later on, if needed... } private void MyEventHandler(object sender, System.EventArgs e) { ... } 

    }

然后会像这样调用:

 Foo foo = ...; Dimension dim = ...; foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x); 

并且在执行时,最终将使用内部事件处理程序MyEventHandler连接LengthChanged事件。 但这不是很优雅。 我本来希望能够写这个:

 Foo foo = ...; Dimension dim = ...; foo.Observer (dim.LengthChanged); 

但我不知道如何实现这一目标。 也许我错过了一些非常明显的东西? 我想一些dynamic魔术可以做到这一点,不知何故,但这不会强制执行编译时类型检查:我不希望Observer的用户传入对不满足System.EventHandler事件签名的事件的引用。

不幸的是,没有办法做到这一点。 事件通常不是.NET中的一等公民 – 尽管F#试图在那里推广它们。

传入subscribe / unsubscribe代理或使用指示事件名称的字符串。 (后者通常较短,但在编译时显然不太安全。)

这些是Reactive Extensions采用的方法 – 如果有更简洁的方法,我相信他们会使用它:(

事件不应该传递给另一个方法。 但是,您可以将委托传递给另一个方法。 也许,你要找的只是一个简单的公共代表而不是事件。

如果您将活动更改为此

 public System.EventHandler LengthChanged; 

您可以像这样简单地将LengthChanged传递给Observer

 Foo foo = ...; Dimension dim = ...; foo.Observer (dim.LengthChanged);