【发布时间】:2013-04-16 08:15:30
【问题描述】:
每个人都知道私有事件处理程序可以监听来自其他类的事件。 (文档中的示例总是只使用私有处理程序。)
事件处理程序只不过是另一个类中的私有方法,而不是调用事件。因此,从其类外部调用处理程序会破坏封装。还是我错过了什么?
示例代码,为了完整性:
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();。
这是一个纯粹的学术问题,甚至是学术问题。而且,我个人觉得这个功能非常方便、实用,而且非常喜欢。这真的很酷:我们可以显式地授予其他类调用我们私有方法的权利。 (我们也可以取消订阅它,用代表和事件制作很多有趣的东西。)不管怎样,它仍然违反了封装的纯洁性……还是不?
P.S.:感谢 Matthew Watson 指出以下细微差别:订阅事件时,该事件可以独占调用私有处理程序。而如果我们将其公开(或通过公共包装方法调用),任何人都可以调用它。可访问性有很大不同。
P.P.S:是的 - 我从未在教科书中看到过这个问题。如果你知道,请留下参考。
【问题讨论】:
-
它不会破坏封装,就像调用一个公共方法会继续调用一个私有方法,IMO。
-
马修·沃森:不完全一样。如果我们从公共方法(当然在同一个类中)调用私有处理程序,那么任何人都可以调用这个公共方法,因此,处理程序。而当订阅事件时,私有处理程序可以被该事件独占调用。
-
是的,但这只是因为具有私有方法的类正在这样做。这是一个在
Receiver类之外无法观察到的实现细节。另一个类没有办法直接调用MyPrivateHandler(当然,除了使用反射)。 -
当然。顺便说一句,它回答了“如何从类外部调用私有方法”的问题,尽管是以一种特殊的方式。再一次,正式的隐私有一个洞。非常有用且真正为明确声明的米老鼠而设计,它仍然是一个洞:)
标签: c# events delegates encapsulation