非静态私有或受保护事件存在哪些用例?

时间:2009-09-25 20:33:02

标签: c# .net vb.net

.NET中的受保护或私有(非静态)事件真正起作用的目的是什么?

似乎任何私有或受保护事件都可以通过虚拟方法更轻松地处理。我可以(有点)在静态事件中看到这个需要,但不能用于正常事件。

您之前是否有过一个用例,清楚地表明非静态保护或私人事件的需要或优势?

5 个答案:

答案 0 :(得分:7)

这是我实施过的一个有点奇怪但真实世界的场景。您有机器生成的和用户生成的部分类的一半。机器生成的一半包含希望在某些事件发生时通知用户生成的一半的代码。但是,用户生成的一半可能不关心做任何事情,或者它可能会做很多事情。机器生成的一半似乎很粗鲁,要求用户生成的一半实现一个特定的方法,以便处理他们没有兴趣收听的消息。

要解决此问题,机器生成的一半可能会触发私人事件。如果用户生成的一半关心,它可以订阅该事件。如果没有,它可以忽略它。

现在,C#3中的部分方法更加优雅地解决了这个问题,但这不是当天的选择。

答案 1 :(得分:6)

在我看来,私有事件在哪里有用的一个好例子是在组件/控件构建中,通常你可能有一个由一个或多个其他组件组成的组件,包含组件可以订阅的私有事件是一个方便易用的观察者模式实现。

编辑:

让我举个例子......

假设您正在编写一个Grid类型控件,并且在此控件内部,您很可能会有一堆包含的类,这些类是动态创建的Rows,Cols,header等,例如,假设您要通知这些包含的类的东西他们关心的事情已经发生了,比如Skinning的变化或类似的东西,你不一定想把它作为一个事件暴露给网格用户,这是私人活动很方便,只需要一个或两个处理程序,当你创建你的行或col的每个实例或任何附加处理程序的实例,否则你只需要编写自己的观察器机制,而不是很难,但为什么当你没有,你可以只使用多播事件。

答案 2 :(得分:1)

嵌套类型可以访问封闭类型的private和protected事件。我已经使用此功能在Silverlight应用程序中通知父控件(封闭类型)中状态更改的子控件(嵌套类型)。

答案 3 :(得分:0)

很抱歉拖了一个旧帖子,但我在其中一个项目中使用私人活动而不受惩罚,而且我个人认为这是解决设计问题的好方法:

这是缩写代码:

public class MyClass
{
  private event EventHandler _myEvent;

  public ExternalObject { get; set; }

  public event EventHandler MyEvent
  {
    add
    {
      if (_myEvent.GetInvocationList().Length == 0 && value != null)
        ExternalObject.ExternalEvent += HandleEvent;
      _myEvent+= value;
    }
    remove
    {
      _myEvent-= value;
      if (_myEvent.GetInvocationList().Length == 0)
        ExternalObject.ExternalEvent -= HandleEvent;
    }
  }

  private void HandleEvent(object sender, EventArgs e)
  {
     _myEvent.Raise(this, EventArgs.Empty); // raises the event.
  }
}

基本上,MyEvent只在ExternalObject.ExternalEvent的事件处理程序中引发,所以如果MyEvent没有处理程序,那么我不需要将处理程序附加到外部事件,通过保存堆栈帧来略微加速代码。

答案 4 :(得分:0)

不仅当前实例可以访问私有成员。其他相同类型的实例也可以!这样可以实现此访问控制可能有用的一些场景。

我在想一个树结构,其中所有节点都继承某种类型,而private / protected事件允许将叶子事件传播给它们的父节点。由于它们是相同的类型,父母可以注册到孩子的私人事件。然而,树结构的任何客户端都不能。

我绝对可以在存储系统等目录中看到一个用例,其中每个目录需要将其最后修改日期传播到其父目录。