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.
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.
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.
Use a question mark for a conditional access:
OnTemperatureChange?.Invoke();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With