tags:

views:

193

answers:

8

It sounds crazy but I created an event in the class and tried to raise it without having anyone registering to it. However it would give an exception. Is it necessary to have someone register to it before raising the exception? If so then what are the work arounds?

+13  A: 

yes, an event with no-one registered on it is null. The standard way of firing events is:

event EventHandler MyEvent;

private void FireMyEvent(EventArgs e) {
    var handler = MyEvent;
    if (handler != null)
        handler(this, e);
}

Eric Lippert has written a fantastic article on why this pattern is the 'correct' way of firing events

thecoop
Thanx for the link. makes it a complete answer. +1
Umair Ahmed
from the link:Why the temp?The temporary variable ensures that this is “thread safe”. If the event’s handlers are being modified on another thread it is possible for Foo to be non-null at the point of the check, then set to null on a different thread, and then the invocation throws.
Umair Ahmed
here temp is handler
Umair Ahmed
+1  A: 

Check for null.

if (Object.Event != null) Object.Event();

HTH Alex

AlexDuggleby
+3  A: 

In .NET, events are (by default) handled as multicast delegates. This means that until you assign the first event handler to the event, the event reference will evaluate as null.

This has lead to the typical way to raise an event being:

public event EventHandler Event;

protected virtual void OnEvent(EventArgs e)
{
    EventHandler @event = Event; // Copy immutable delegate for thread safety.
    if(@event != null) // Check for null.
        @event(e); // Raise event.
}
Programming Hero
It's best to copy Event to a temporary variable to prevent race conditions
thecoop
+1  A: 

If no one has subscribed to the event, the event object is null. It is a common practice to use a OnEvent-like method, for example (assuming your event is called MyEvent):

public event EventHandler<MyEventArgs> MyEvent;

void OnMyEvent(MyEventArgs args) {
    if(MyEvent != null) MyEvent(this, args);
}

When you have to raise the event, you simply call the OnMyEvent method.

Dario Solera
A: 

The simplest solution to that problem is to declare the event:

public event EventHandlerType MyEvent = delegate { };

In other words, add = delegate { }; to the end.

Now you don't need to write a load of junk each time you raise the event.

Daniel Earwicker
So can we set an event reference to null??If yes then you better check for nulls.
S M Kamran
Code in other classes can't assign a new value to a member declared as `event`. They can only use `+=` and `-=`. They cannot remove the empty delegate.
Daniel Earwicker
+5  A: 

Yes. If there are no subscribers, the event will be null and you will get a NullReferenceException when you call it. The correct way of doing the check is as thecoop has said, but there is a simple "shortcut":

public event EventHandler Event = delegate {};

This causes the event to have a default subscriber that does nothing, and so will not throw an exception if there are subscribers. There is a slight performance overhead of doing this, but it does remove the need to check for nulls.

adrianbanks
see this : http://stackoverflow.com/questions/170907/is-there-a-downside-to-adding-an-anonymous-empty-delegate-on-event-declaration for the performance considerations to using empty delegates.
Lee Treveil
+2  A: 

If an event gets raised and no one is registered to it - does it then make a sound?

(sry, would've written a comment, but didn't have enough rep to do so)

Dave
+1  A: 

Just to add you can use extension methods also.

        public static void RaiseSafe<T>(this EventHandler<T> eventHandler, object sender, T args)
        where T : EventArgs
    {
        if (eventHandler != null)
            eventHandler(sender, args);
    }

And use it like this:

MyEvent.RaiseSafe(this,new EventArgs());
Lee Treveil
In this case the temporary variable is redundant, as the act of passing the event handler to the method eliminates the race condition. The null check is still necessary though.
Phil Devaney
Interesting cheers.
Lee Treveil