Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking delegates for null

Tags:

c#

.net

delegates

I was reading the Essential C# 3.0 book and am wondering if this is a good way to check delegates for null?:

class Thermostat
{
    public delegate void TemperatureChangeHandler ( float newTemperature );

    public TemperatureChangeHandler OnTemperatureChange { get; set; }

    float currentTemperature;

    public float CurrentTemperature
    {
        get { return this.currentTemperature; }
        set
        {
            if ( currentTemperature != value )
            {
                currentTemperature = value;

                TemperatureChangeHandler handler = OnTemperatureChange;

                if ( handler != null )
                {
                    handler ( value );
                }
            }
        }
    }
}

Does the solution changes if the type is immutable? I figured maybe with immutability you wouldn't run into this threading problem.

like image 995
Joan Venge Avatar asked Jun 09 '09 23:06

Joan Venge


3 Answers

Original (somewhat inaccurate) Response:

There has been much discussion on this.

In short: you can't guarantee that the handler will be valid even by doing this copy/check for null/ execute step.

The problem is, if OnTemperatureChange is unregistered between the time you copy it, and the time you execute the copy, then it's probably true that you don't want the listener to be executed anyway.

You may as well just do:

if (OnTemperatureChange != null )
{
    OnTemperatureChange ( value );
}

And handle a null reference exception.

I sometimes add a default handler that does nothing, just to prevent the null reference exception, but that adds performance impact quite seriously, especially in the case where there is no other handler registered.

Update 2014-07-10:

I defer to Eric Lippert.

My original response did allude to using default handlers, but I didn't recommend using a temp variable, which I now agree as good practice also, per the article.

like image 173
John Weldon Avatar answered Nov 20 '22 06:11

John Weldon


Use a question mark for a conditional access:

OnTemperatureChange?.Invoke();
like image 25
Luca Ziegler Avatar answered Nov 20 '22 06:11

Luca Ziegler


There is a reason the code you've given is recommended over C. Ross's version. However, John is also right that there is still another problem if an event is unregistered in the meanwhile. The blog I linked recommends that the handler ensure they can be called even after being unregistered.

like image 5
Matthew Flaschen Avatar answered Nov 20 '22 08:11

Matthew Flaschen