简体   繁体   中英

C# Best Practice - Event subscription

Very basic question, so I'm just looking for a best practice to follow.

My class has a few events which should be subscribed to. (eg DiscoveryCompleted). Within the method I do check if the event is null or not, however I'm not sure if I should raise an exception, if so what type. NotImpletementedException?

If the exception is unhandled it doesnt look very elegant.

Your thoughts?

My thought is this is precisely what the NotImplementedException was created for. You should never encounter a NotImplementedException in production code, but it makes it painfully clear during testing that you have a code path that has, well, not been implemented.

Kinda like a TODO comment, but more in-your-face :)

Although, I might question whether having an event handler that must be subscribed to, and not having a default subscriber, doesn't indicate a design issue.

EDIT

I think I misunderstood your initial question slightly, based on your comment. As others have stated (and I questioned), you should not be throwing an exception when you don't have a subscriber to an event handler; simply don't try to call it. If no one cares that event x happened, you can't really do anything about that.

It's not your code's responsibility to care whether anyone cares that it happened, but simply to notify them that it happened if they do care.

EDIT 2 - now with more code

public interface INeedToKnowAboutSomethingImportant 
{
    void WhenSomethingImportantHappens(SomethingImportantHappenedEventArgs args);
}


public class DoesSomethingImportant 
{
    private readonly INeedToKnowAboutSomethingImportant _needyDependency;
    public DoesSomethingImportant(INeedToKnowAboutSomethingImportant needyDependency)
    {
        _needyDependency = needyDependency;
    }

    protected void SomethingImportantHappened(object sender, EventArgs e)
    {
        //Handle internally
        _needyDependency.WhenSomethingImportantHappens(new SomethingImportantHappenedEventArgs(e));
    }
}

Following this pattern, you don't have to worry about whether anyone is subscribed to your event handlers. You have to fulfill the dependency, but it doesn't matter AT ALL what you fill it with because whatever it is, it will have that method for you to call.

Events should be optionally subscribed to. If your class has to call a method, pass a delegate on its constructor instead.

You should not throw NotImplementedException when you check your event. Just check, and execute if not null.

Take for instance. You put an element on your page, but you do not intend to implement any events on the button. The button check for Click event, don't find one, and throws NotImplementedException.

Now that is just wrong.

Event is something that's raised when a certain point the program is hit. Then you can have code that is "triggered" by it. The main path of the code should not be affected whether an event is present or not. If the main path of your code cannot continue without the event being triggered, then you need to use a Method instead.

My suggestion is: 1) Create an event. 2) Subscribe the event with handlers that you are going to implement later. 3) Throw the NotImplementedException in the handler.

As for exception is unhandled, you should never be handling NotImplementedException anyway :P... (And you shouldn't be throwing NotImplementedException for null reference to events).

You should not worry about the event object being null. If no one has subscribed to the event then nothing. If you need another function to run outside of your event raising class, then you need to use another pattern besides the observer pattern. As Eduardo suggested you can pass in a delegate, you might also consider a builder pattern.

I would not throw if an event has no subscribers.

In the "On" method that raises the event you will need a null test (note the race condition prevention). Elsewhere your class should not assume that the event has subscribers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM