Why must someone be subscribed for an event to occur?

Some text before the code so that the question summary isn’t mangled.

class Tree
{
    public event EventHandler MadeSound;

    public void Fall() { MadeSound(this, new EventArgs()); }

    static void Main(string[] args)
    {
    	Tree oaky = new Tree();
    	oaky.Fall();
    }
}

I haven’t used events much in C#, but the fact that this would cause a NullRefEx seems weird. The EventHandler reference is considered null because it currently has no subsribers – but that doesn’t mean that the event hasn’t occurred, does it?

EventHandlers are differentiated from standard delegates by the event keyword. Why didn’t the language designers set them up to fire silently in to the void when they have no subscribers? (I gather you can do this manually by explicitly adding an empty delegate).

class expose event, how to know if someone subscribed it

My class implements interface, And I expose event to the outside world. I have a polling timer that send data using that event to subscriber using a custom eventArgs. I want to start the polling timer

Why is subscribed event always null?

I declare a subscription to event in: public class MainClass { public void btndel_bar_Click(object sender, RoutedEventArgs e) { SomeClass sc = new SomeClass(); sc.FieldUpdate += new SomeClass.FieldUpd

Why does QEvent::ShortcutOverride event occur?

I have a QMainWindow with an event filter installed. After I open and close a QDialog the keyboard arrow keys don’t respond since QMainWindow receives only ShortcutOverride events instead of KeyPress

entityAspect.setDeleted doesn’t fire the subscribed propertyChanged event

I am running into problem where i subscribe to propertyChanged event, the subscribed event does fire for entity Modification, but never fires for when setting entity to Deleted. what might i be doing

How to ensure an event is only subscribed to once

I would like to ensure that I only subscribe once in a particular class for an event on an instance. For example I would like to be able to do the following: if (*not already subscribed*) { member.Eve

How to test if an event was subscribed

I have an attached behavior that subscribes to a TabItem’s IsVisibleChanged method. I want to write a unit test to verify that this event is being subscribed in the attached behavior. Something like t

Difference between BooleanClause.Occur.Must and BooleanClause.Occur.SHOULD in lucene

Can anyone explain the difference between the BooleanClause.Occur.Must and BooleanClause.Occur.SHOULD in lucene in BooleanQuery with an example?

Difference between Occur.SHOULD and Occur.MUST in SOLR

I don’t get the distinction between Occur.SHOULD and Occur.MUST in add method of org.apache.lucene.search.BooleanQuery. Can anybody explain?

IllegalArgumentException when Event occur, javafx

I have a fxml file which has registered a Controller. The Controller implements EventHandler and so the method handle(ActionEvent e). If the registered event occur the code in the handler method is pr

How to verify event subscribed using Moq

I am using MVVM pattern and silverlight 4.0 and Moq for testing. In the view model constructor, am passing an IEventAggregator object. This object is used to subscribe to an event called SelectionChan

Answers

Well, the canonical form is:

void OnMadeSound()
{
    if (MadeSound != null)
    {
        MadeSound(this, new EventArgs());
    }
}

public void Fall() {  OnMadeSound(); }

which is very slightly faster that calling an empty delegate, so speed won out over programming convenience.

Very Zen, eh?

You have to test for null when you want to raise an event:

protected void OnMyEvent()
{
    if (this.MyEvent != null) this.MyEvent(this, EventArgs.Empty);
}

It would be nice if you didn’t have to bother with this, but them’s the breaks.

James provided a good technical reasoning, I would also like to add that I have seen people use this an advantage, if no subscribers are listening to an event, they will take action to log it in the code or something similar. A simpl example, but fitting in this context.

You need to understand what your event declaration is actually doing. It’s declaring both an event and a variable, When you refer to it within the class, you’re just referring to the variable, which will be null when there are no subscribers.

What is the point of raising an event if no one is listening? Technically, its just how C# chose to implement it.

In C#, an event is a delegate with some special feathers. A delegate in this case can be viewed as a linked list of function pointers (to handler methods of subscribers). When you ‘fire the event’ each function pointer is invoked in turn. Initially the delegate is a null object like anything else. When you do a += for the first subscribe action, Delegate.Combine is called which instantiates the list. (Calling null.Invoke() throws the null exception – when the event is fired.)

If you still feel that “it must not be”, use a helper class EventsHelper as mentioned here with old and improved ‘defensive event publishing’ http://weblogs.asp.net/rosherove/articles/DefensiveEventPublishing.aspx

Another good way I’ve seen to get around this, without having to remember to check for null:

class Tree
{
    public event EventHandler MadeSound = delegate {};

    public void Fall() { MadeSound(this, new EventArgs()); }

    static void Main(string[] args)
    {
        Tree oaky = new Tree();
        oaky.Fall();
    }
}

Note the anonymous delegate – probably a slight performance hit, so you have to figure out which method (check for null, or empty delegate) works best in your situation.

Thank you for the responses. I do understand why the NullReferenceException happens and how to get around it.

Gishu said

What is the point of raising an event if no one is listening?

Well, maybe it’s a terminology thing. The appeal of an “event” system seems to me that all the responsibility of the fallout of the event that took place should be on the watchers and not the performer.


Perhaps a better thing to ask is: If a delegate field is declared with the event keyword in front of it, why doesn’t the compiler translate all instances of:

MadeSound(this, EventArgs.Empty)

to

if (MadeSound != null) { MadeSound(this, EventArgs.Empty); }

behind the scenes in the same manner that other syntax shortcuts are? The number of boilerplate OnSomeEvent null checking methods that people have to write manually must be colossal.

The recommended pattern is (.net 2.0+)

public class MyClass
{
    public event EventHandler<EventArgs> MyEvent; // the event

    // protected to allow subclasses to override what happens when event raised.
    protected virtual void OnMyEvent(object sender, EventArgs e)
    {
        // prevent race condition by copying reference locally
        EventHandler<EventArgs> localHandler = MyEvent;
        if (localHandler != null)
        {
            localHandler(sender, e);
        }
    }
    public void SomethingThatGeneratesEvent()
    {
        OnMyEvent(this, EventArgs.Empty);
    }
}

I see a lot of recommendations for an empty delegate{} in an initializer, but I totally disagree with it. If you follow the above pattern you only check the event != null in one place. The empty delegate{} initializer is a waste because it’s an extra call per event, it wastes memory, and it still can fail if MyEvent was set to null elsewhere in my class.

* If your class is sealed, you wouldn’t make OnMyEvent() virtual.

Using an extension method would be helpful in this scenario.

public static class EventExtension
{
    public static void RaiseEvent<T>(this EventHandler<T> handler, object obj, T args) where T : EventArgs
    {
        if (handler != null)
        {
            handler(obj, args);
        }
    }
}

It can then be used like below.

public event EventHandler<YourEventArgs> YourEvent;
...
YourEvent.RaiseEvent(this, new YourEventArgs());