c# - 私有(private)事件处理程序是否会破坏封装?

标签 c# events delegates encapsulation

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

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

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

 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 类中的私有(private)方法:caller.RaiseMyEvent();.

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

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

P.P.S:是的 - 我从未在教科书中看到过这个问题。如果你知道一个,请留下引用。

最佳答案

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

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

在 Receiver 类中没有直接调用这个私有(private)方法,你不应该对此做任何假设。接收者类在任何时候都可以自行取消订阅。

它对封装进行了调整,但我不认为它完全违反了封装。它基本上是一个广播系统。

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

关于c# - 私有(private)事件处理程序是否会破坏封装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16163867/

相关文章:

c# - 调用另一个 WCF 服务的 WCF 服务很慢

c# - WPF标签下的可点击按钮

c# - 使用 PageMethods 从 Javascript 代码调用 C# bool 函数

c# - 有和没有 "new"的接线事件之间的区别

c# - 如何从此代码重构我们的类型参数?

c# - WPF XAML 解析错误。 "Data at the root level is invalid."

c# - 在引发事件的方法上编写代码契约

node.js - 如何让我的 NodeJS 应用程序永远循环运行

ios - 如何跟踪值何时更改以及拖动何时停止?

cocoa - 在 Carbon Objective C++ 应用程序中使用 Cocoa delegate