Question

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.
Was it helpful?

Solution

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

OTHER TIPS

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top