4

每个人都知道私有事件处理程序可以监听来自其他类的事件。(文档中的示例总是只使用私有处理程序。)

事件处理程序只不过是另一个类中的私有方法,而不是调用事件。因此,从其类外部调用处理程序会破坏封装。还是我错过了什么?

示例代码,为了完整起见:

 class Caller    {
    public event EventHandler MyEvent;
    public void RaiseMyEvent()
    {
       MyEvent(this, EventArgs.Empty);
    }
}

class Receiver
{
    private void MyPrivateHandler(Object sender, EventArgs e)
    {
        Console.WriteLine("I'm a private method!");
    }

    public void Subscribe(Caller caller)
    {
        caller.MyEvent += this.MyPrivateHandler;
    }
}

订阅后,我们可以轻松地从外部receiver.Subscribe(caller); 调用类中的私有方法: .receivercaller.RaiseMyEvent();

这是一个纯粹的学术问题,甚至是学术问题。而且,我个人觉得这个功能非常方便、实用,而且非常喜欢。这真的很酷:我们可以显式地授予其他类调用我们私有方法的权利。(我们也可以取消订阅它,并用代表和事件制作很多令人着迷的东西。)无论如何,它仍然违反了封装的纯洁性......或者不是?

PS:感谢 Matthew Watson 指出以下细微差别:订阅事件时,该事件可以独占调用私有处理程序。而如果我们将其公开(或通过公共包装方法调用),则任何人都可以调用它。在可访问性方面有很大差异。

PPS:是的——我从未在教科书中看到过这个问题。如果你知道,请留下参考。

4

3 回答 3

0

显然,当您从任一类之外执行 caller.RaiseMyEvent() 时,您不必知道谁将处理该事件。

事实上,我不认为Receiver中的Subscribe-method应该是公开的,这种违背了目的。如果接收者有兴趣处理事件,它应该订阅自己,它不应该让其他人订阅它。这样您就可以隐藏订阅状态和处理它的方法。

在 Receiver 类中没有直接调用此私有方法,您不应该对此进行任何假设。接收者类在任何时候都可以取消订阅。

它摆弄封装,但我认为它并不完全违反它。它基本上是一个广播系统。

如果某个电视台建议人们出去偷一个苹果,而他们却真的做了,那该怪谁呢?电视台还是偷东西的人?我会认为是后者。事件也是如此,提出事件的人不必担心其影响。

于 2013-04-23T08:04:57.913 回答
0

私有事件处理程序是私有的,因为您只想为用户提供将其用作事件的选项。

private void MyPrivateHandler(Object sender, EventArgs e)
{
    Console.WriteLine("I'm a private method!");
}

public void Subscribe(Caller caller)
{
    caller.MyEvent += this.MyPrivateHandler;
}

public void Subscribe(Caller caller)
{
    caller.MyEvent += (sender,e)=>{Console.WriteLine("I'm a anonymous method!"); }
}
于 2013-04-23T08:16:02.863 回答
0

虽然有点离题,但它与您的问题有关,您可能会觉得它很有趣:关于自定义添加和删除 C# 事件处理程序的博客文章的链接。评论值得一读。一条相关评论引用了来自 MSDN 杂志的这个答案(Stephen Toub 的“Event Acessors”)到博客文章问题。

于 2013-06-05T07:50:09.917 回答