EventHandler如何知道allow = operator仅用于定义类?

时间:2009-05-02 00:06:46

标签: c# event-handling

我开始提出一个问题,在输入问题时,找到了答案,但我没有删除,我认为A)得到确认,B)帮助他人可能会有所帮助。

如果我有一个事件,并且应用程序中的几个地方添加了侦听器,那么一次删除所有侦听器的最佳方法是什么?例如,我可以......

myPage.OnPageOpened += OpenPage;

以后在我的代码中......

myPage.OnPageOpened -= OpenPage;

但是如果我有未知的第三方订阅者并且我想按下一个神奇的重置按钮来清除所有内容并从头开始呢?

您可以在EventHandler的任何位置使用+ =和 - =运算符,因为运算符重载是公共的。 =重载运算符是私有的,只能在定义类中调用。

所以在定义类中我可以用它来清除我的EventHandler。

OnPageOpened = null;

为了公开这个功能,我可以......

public void ClearPageOpenedEvents() {
   OnPageOpened = null;
}

这是对的吗?

3 个答案:

答案 0 :(得分:1)

这是实现它的方法,但是类之外的东西怎么知道类应该删除它的所有事件监听器?如果有人延长/使用您的代码会持续期待该事件,该怎么办?

答案 1 :(得分:1)

是的,你是对的。原因是编译器在封面下创建了一个private delegate对象,如下所示:

private EventHandler pageOpened;

public EventHandler PageOpened
{
    add { pageOpened += value; }
    remove { pageOpened -= value; }
}

在您的课程中,您可以引用私有delegate实例,这就是您可以执行作业的原因。如果您需要这些功能,您肯定希望公开一种清除目标的方法;你不想公开delegate本身。

答案 2 :(得分:0)

您可以在事件中使用赋值运算符,因为这是添加和删除事件的工作方式。使用Reflector可以了解如何在C#中完成事件。

给出简单的

public class MyClass
{
  public event EventHandler MyEvent;
}

编译时生成以下代码

public class MyClass
{
  private EventHandler MyEvent;

  public event EventHandler MyEvent;
}

因此,当您引用MyEvent时,您指的是私有委托变量MyEvent+=-=运算符是“特殊的”(因为它们不是运算符)并且更改为调用为事件创建的addremove方法(它使用赋值运算符本身。)

[MethodImpl(MethodImplOptions.Synchronized)]
public void add_MyEvent(EventHandler value)
{
  this.MyEvent = (EventHandler) Delegate.Combine(this.MyEvent, value);
}

[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_MyEvent(EventHandler value)
{
    this.MyEvent = (EventHandler) Delegate.Remove(this.MyEvent, value);
}