.NET 事件 - 阻止订阅者订阅事件

发布于 2024-08-21 21:45:13 字数 283 浏览 12 评论 0原文

假设我有一个公开事件的“处理器”接口 - OnProcess。通常由实现者进行处理。因此我可以安全地订阅此事件并确保它会被解雇。但是一个处理器不进行处理 - 因此我想阻止订阅者订阅它。我可以这样做吗?换句话说,在下面的代码中我希望最后一行抛出异常:

var emptyProcessor = new EmptyProcessor();
emptyProcessor.OnProcess += event_handler; // This line should throw an exception.

Let's say I have a "Processor" interface exposing an event - OnProcess. Usually the implementors do the processing. Thus I can safely subscribe on this event and be sure it will be fired. But one processor doesn't do processing - thus I want to prevent subscribers to subscibe on it. Can I do that? In other words in the code below I want the last line to throw an exception:

var emptyProcessor = new EmptyProcessor();
emptyProcessor.OnProcess += event_handler; // This line should throw an exception.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

他是夢罘是命 2024-08-28 21:45:13
class EmptyProcessor : IProcessor {

    [Obsolete("EmptyProcessor.OnProcess should not be directly accessed", true)]
    public event EventHandler OnProcess { 
        add { throw new NotImplementedException(" :( "); }
        remove { }
    }
}

在这种情况下,Obsolete 上的 true 参数会导致编译时异常。所以:

EmptyProcessor processor1 = new EmptyProcessor();
IProcessor processor2 = new EmptyProcessor();

processor1.OnProcess += handler;  // <-- compile-time error
processor2.OnProcess += handler;  // <-- run-time error
class EmptyProcessor : IProcessor {

    [Obsolete("EmptyProcessor.OnProcess should not be directly accessed", true)]
    public event EventHandler OnProcess { 
        add { throw new NotImplementedException(" :( "); }
        remove { }
    }
}

In this situation, the true parameter on Obsolete causes a compile-time exception. so:

EmptyProcessor processor1 = new EmptyProcessor();
IProcessor processor2 = new EmptyProcessor();

processor1.OnProcess += handler;  // <-- compile-time error
processor2.OnProcess += handler;  // <-- run-time error
沉溺在你眼里的海 2024-08-28 21:45:13

您可以使用自定义 add/remove 方法来实现它,但我认为这是一个不好的做法。

看,您有一个接口,一个由不同类实现的契约
OnProcess 是此合同的一部分,并且没有任何特殊之处。

当一个人想要在同一组操作下使用不同的类时,通常会使用接口。接口允许您像这样编写代码:

IProcessor proc = GetProcessorAnyhow ();
proc.DoSomething ();

无需知道编译类型的具体类型。

但是,按照您的方法,

IProcessor proc = GetProcessorAnyhow ();
proc.OnProcess += (sender, e) => { };

可能会在没有任何明显原因的情况下失败,尽管它看起来像是绝对合法的代码。
始终确保错误代码看起来错误

您可能犯了以下设计错误之一:

  • OnProcess 放入 IProcessor 中,而它可能不是每个处理器的合同;
  • EmptyProcessor实现IProcessor,而实际上它不能满足契约

You can implement it with custom add/remove methods but I believe this is a bad practice.

Look, you have an interface, a contract to be implemented by different classes.
OnProcess is part of this contract and is not special in any way.

One usually uses interfaces when she wants to work with different classes under the same set of operations. Interfaces allow you to code like this:

IProcessor proc = GetProcessorAnyhow ();
proc.DoSomething ();

without knowing concrete type at compile type.

However, with your approach,

IProcessor proc = GetProcessorAnyhow ();
proc.OnProcess += (sender, e) => { };

may fail without any apparent reason, although it looks like absolutely legitimate code.
Always make sure that wrong code looks wrong.

You may have done one of the following design mistakes:

  • Put OnProcess in IProcessor whereas it may not be each processor's contract;
  • Made EmptyProcessor implement IProcessor, whereas actually it can't satisfy the contract.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文