C# 如何在C中引用事件#
我有一个类,它有一个名为C# 如何在C中引用事件#,c#,events,reference,callback,event-handling,C#,Events,Reference,Callback,Event Handling,我有一个类,它有一个名为LengthChanged的公共事件: class Dimension { public int Length { get { return this.length; } set { if (this.length != value) { this.length = valu
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
的方法中注册/取消注册此事件的处理程序,该方法对维度
类一无所知。我提出了两种方案,没有一种是真正令人满意的:
LengthChanged
事件定义一个接口ilelengthchanged
,然后确保Dimension
实现ilelengthchanged
。然后,我必须为我定义的每个接口提供一个Observer
方法的实现。这绝对不够一般。我真的希望能够简单地传入对System.EventHandler
事件的引用System.Action
回调在Observer
方法中注册和注销事件处理程序,如下所示:class-Foo
{
公共无效观察员(系统行动登记册,
系统操作(取消注册)
{
登记册(此为MyEventHandler);
//跟踪注销回调,以便我们可以注销
//稍后,如果需要,我们的事件处理程序。。。
}
私有void MyEventHandler(对象发送方,System.EventArgs e)
{
...
}
}
然后会像这样调用:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);
当执行时,它确实会将LengthChanged
事件与内部事件处理程序MyEventHandler
连接起来。但这不是很优雅。我希望能够写下以下内容:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
但我不知道如何才能做到这一点。也许我错过了一些很明显的东西?我想一些
dynamic
magic可以在某种程度上实现这一点,但这不会强制执行编译时类型检查:我不希望Observer
的用户传入不满足System.EventHandler
事件签名的事件引用。不幸的是,没有真正的方法可以做到这一点。尽管F#试图在.NET上推广这些活动,但一般来说,这些活动并不是.NET的头等公民
传入订阅/取消订阅委托或使用指示事件名称的字符串。(后者通常较短,但在编译时显然不太安全。)
这些是需要采取的方法-如果有更干净的方法,我相信他们会使用:(事件不应该被传递到另一个方法中。但是,您可以将委托传递到另一个方法中。也许,您正在寻找的只是一个简单的公共委托,而不是事件 如果您将活动更改为此
public System.EventHandler LengthChanged;
您可以像这样简单地将长度更改传递给观察者
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
您可以创建自定义访问器
public event EventHandler NewEvent
{
add { Dimension.LengthChanged += value; }
remove { Dimension.LengthChanged -= value; }
}
请。谢谢你的建议。不,我不能传递委托而不是事件;该事件可能实现
add
和remove
设置器,并且必须定义为一个完整的C#事件
@Pierre,我明白了。在这种情况下,我要做的是声明一个委托包装器类。构造函数该类的属性接受委托。该类具有virtual AddHandler()和virtual RemoveHandler()。它还具有Invoke()方法调用委托。若要使其看起来更优雅,可以定义运算符+=、-=、+和-,调用AddHandler和RemoveHandler。用此包装类替换维度的LengthChanged事件。对于需要“添加”和“删除”的情况setters,只需重写包装类的AddHandler和RemoveHandler方法。只需我的2美分。我也做了类似的。很好的解决方案…我必须仔细考虑一下。+1对于这个不错的破解。如果像Erik Meijer这样的人不能想出更干净的解决方案,我怀疑确实没有其他方法可以做到。这很遗憾……谢谢你的支持我们的快速回复,乔恩。