每个人都知道私有事件处理程序可以侦听来自其他类的事件。 (文档中的示例始终只使用私有处理程序。)
事件处理程序只不过是另一个类中的私有方法而不是调用事件。因此,从类外部调用处理程序会破坏封装。或者我错过了什么?
示例代码,为了完整性:
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);
之后,我们可以从receiver
轻松地在caller.RaiseMyEvent();
课程中调用私有方法。{/ 1}。
这是一个纯粹的学术问题,甚至是学术问题。而且,我个人觉得这个功能非常方便,实用,而且非常喜欢它。这真的很酷:我们可以明确地授予其他类调用私有方法的权利。 (我们也可以取消订阅,并为代表和活动制作许多引人入胜的内容。)无论如何,它仍然违反了封装的纯度......或者不是?
P.S。:感谢Matthew Watson指出以下细微差别:订阅事件时,私有处理程序可以由此事件专门调用。如果我们公开(或通过公共包装方法调用),它可以被任何人调用。它在可访问性方面有很大差异。
P.P.S:是的 - 我从未在教科书中看到过这个问题。如果您知道,请留下参考。答案 0 :(得分:0)
显然,当你从任何一个类的外部做caller.RaiseMyEvent()时,你不必知道谁将会处理这个事件。
事实上,我认为接收方中的订阅方法不应该是公开的,这种方式会失败。如果Receiver有兴趣处理该事件,它应该自己订阅,不应该让其他人订阅它。通过这种方式,您可以保留订阅状态以及隐藏它的方法。
在Receiver-class中没有直接调用这个私有方法,你不应该假设它。接收器类在任何时候都可以取消订阅。
它摆弄了封装,但我不认为它完全违反了它。它基本上是一个广播系统。
如果某个电视台建议人们外出偷苹果而他们实际上是这样做的,谁应该受到指责呢?电视台还是偷的人?我会想到后者。 事件也是如此,提出事件的人不应该担心这些事件。
答案 1 :(得分: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!"); }
}
答案 2 :(得分:0)
虽然有点偏离主题,但它与您的问题有关,您可能会发现它很有趣:a link to a blog post about customizing the adding and removing of C# event handlers。评论值得一读。一篇相关评论引用了MSDN杂志中的answer ("Event Acessors" by Stephen Toub),以及博客文章问题。