2

If a class fires events in its methods, the class does not have to know what or who subscribes its events. It is not also important if there is any subscriber.

In the code below, if there is not any subscriber to OnTrigger event, an exception occures.

public class EventTrigger
{
    public static void Main(string[] args)
    {
        (new EventTrigger()).Trigger();
    }

    public delegate void Delegate1();
    public event Delegate1 OnTrigger;

    void Trigger()
    {
        OnTrigger();
    }
}

I can call the event like this;

if (OnTrigger != null)
{
    OnTrigger();
}

But it seems weird to me, because the triggerer does not have to know about subscription.

My question is:

Do I have to check if the event reference is null whenever I use it.

  • 1
    Here is an interesting discussion on the topic: http://stackoverflow.com/questions/248072/evil-use-of-extension-methods – qxn Mar 01 '12 at 16:44
  • I am not alone in the universe. It makes me feel good. But I think it is not a good approach too. Not because it is done by extension methods. Because it also requires more keyboard input and makes dirtier. – Alperen Belgiç Mar 01 '12 at 20:00

2 Answers2

2

If you initialize OnTrigger then you wont have to do the check. e.g.

public event Action OnTrigger = delegate { };

Yes ´delegate { }´ instantiates a new object, which is why this allows you to omit the ´null´ check.

´delegate { }´ returns nothing, so if you want it to return a string (which you need if Delegate1 returns a string) then you simply add ´return "";´ e.g.:

public event Action OnTrigger = delegate { return string.Empty; };

One I should add is that it's bad practice to do this in order to avoid a null check, as it's a lazy mans hack. Some code can still set the event to null, ´OnTrigger = null´ will break your code. And when it comes to (de)serialization it wont work at all.

Terkel
  • 1,575
  • 8
  • 9
  • Thanks. I have two questions: 1st. Does "delegate { };" initialize an object? what does it return? 2nd. How can I handle a delegate which returns value? like this: public delegate string Delegate1(); public event Delegate1 OnTrigger = delegate{ }; – Alperen Belgiç Mar 01 '12 at 17:50
  • Initializing an event to include an empty subscriber is somewhat icky, since the `Delegate.Combine` and `Delegate.Remove` are much faster adding a delegate to nothing, or subtracting a delegate from itself, than they are handling other scenarios, and `Delegate.Invoke` has less overhead handling a non-combined delegate than a combined one (and skipping the invocation of a null delegate is faster than invoking a dummy one). If the expected number of subscribers is greater than one, adding an empty delegate may not be too bad, but if at most one subscriber is expected, it's wasteful. – supercat Mar 02 '12 at 17:26
1

The triggerer doesn't have to know about the individual subscribers, but it does need to know about subscription. You have to either do the null check every time or use the work-around Simon suggested.

itsme86
  • 19,266
  • 4
  • 41
  • 57