Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# events, what's with that null thing?

Tags:

c#

events

I can't really understand what is this null testing thing for when raising an event.

Say i have this code.

    class ballClass
{


    public event EventHandler BallInPlay;


    public void onHit()
    {
        if (BallInPlay != null)
        {
            BallInPlay(this, new EventArgs());
        }
        else
        {
            MessageBox.Show("null!");
        }
    }



}

and I want to to raise a BallInPlay even when the onHit() method is triggered.

right now it shows me that the BallInPlay IS null. how or with what should i "fill" it for it to work?

Thanks!

like image 293
Rob Avatar asked Nov 30 '22 04:11

Rob


2 Answers

The thing here is that if zero listeners are registered to listen to this event get raised, the event is null. If one or more listeners are registered it will have a value.

That means that if zero listeners are registered, and you try to raise the event without performing the null check, your program will throw an exception.

like image 140
Øyvind Bråthen Avatar answered Dec 05 '22 00:12

Øyvind Bråthen


You need to subscribe to the event with a handler. For example:

BallClass ball = new BallClass();
ball.BallInPlay += BallInPlayHandler;
// Now when ball.OnHit is called for whatever reason, BallInPlayHandler
// will get called
...
private void BallInPlayHandler(Object sender, EventArgs e)
{
    // React to the event here
}

For more information, you may want to read my article on events and delegates.

Note that I've fixed the casing of BallClass and OnHit above - it's a good idea to use the standard .NET naming conventions to make your code fit in better with the code around it, and to make it more readable for others.

One thing to note: the nullity check you've got at the moment isn't thread-safe. The last subscriber could unsubscribe after the if but before the invocation. A thread-safe version would be:

public void OnHit()
{
    EventHandler handler = BallInPlay;
    if (handler != null)
    {
        handler(this, new EventArgs());
    }
    else
    {
        MessageBox.Show("null!");
    }
}

This wouldn't be guaranteed to use the latest subscribers (as there's no memory barrier involved) but it is guaranteed not to throw a NullReferenceException due to race conditions.

like image 41
Jon Skeet Avatar answered Dec 04 '22 23:12

Jon Skeet