开发者

.NET events - blocking subscribers from subscribing on an event

开发者 https://www.devze.com 2022-12-20 22:50 出处:网络
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 f

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.


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


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.
0

精彩评论

暂无评论...
验证码 换一张
取 消