Pie*_*aud 7 c# events reference callback event-handling
我有以下类,它有一个名为的公共事件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;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够在一个名为的方法中注册/取消注册此事件的处理程序,该方法Observer对该Dimension类一无所知.我想出了两个场景,其中没有一个真的令人满意:
定义一个接口ILengthChanged与LengthChanged事件,然后确保Dimension器具ILengthChanged.然后我必须为Observer我定义的每个接口提供该方法的一个实现.这绝不是通用的.我真的希望能够简单地传递对System.EventHandler事件的引用.
使用System.Action<System.EventHandler>回调来注册和取消注册方法中的事件处理程序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)
{
...
}
Run Code Online (Sandbox Code Playgroud)
}
然后会像这样调用:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);
Run Code Online (Sandbox Code Playgroud)
并且在执行时,最终将LengthChanged使用内部事件处理程序连接事件MyEventHandler.但这不是很优雅.我本来希望能够写下这个:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何实现这一目标.也许我错过了一些非常明显的东西?我想有些dynamic魔术可以做到这一点,不知何故,但这不会强制执行编译时类型检查:我不希望用户Observer传入对不满足System.EventHandler事件签名的事件的引用.
Jon*_*eet 10
不幸的是,没有办法做到这一点.事件通常不是.NET中的一等公民 - 尽管F#试图在那里推广它们.
传入subscribe/unsubscribe代理或使用指示事件名称的字符串.(后者通常较短,但在编译时显然不太安全.)
这些是Reactive Extensions采用的方法- 如果有更简洁的方法,我相信他们会使用它:(
| 归档时间: |
|
| 查看次数: |
5849 次 |
| 最近记录: |