我有下面的类,它有一个公共事件调用LengthChanged
:如何引用在C#中的事件
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
课程一无所知。我已经提出了两个方案,其中没有一个是真正的满足:
定义的接口
ILengthChanged
与LengthChanged
事件,然后确保Dimension
实现ILengthChanged
。然后,我必须为我定义的每个接口提供一个Observer
方法的实现。这绝不够通用。我真的希望能够简单地传递对System.EventHandler
事件的引用。使用
System.Action<System.EventHandler>
回调在Observer
方法注册和注销事件处理程序,就像这样:类Foo { 公共无效观察员(System.Action寄存器, System.Action注销) { 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
事件签名的事件。
如果人们像埃里克·梅杰没能拿出更清洁的解决方案,我怀疑事实上,没有其他办法可以做到这一点。很伤心......谢谢你的快速回复,Jon。 – 2011-01-21 09:09:48