C# 6.0で導入されたnull条件演算子を使うと、イベント呼び出し時のnullチェックを簡潔に書くことができる。
以下のコードは、イベントハンドラの呼び出しを行う際の古典的なイディオムである。
public class EventSource
{
public EventHandler<int> Updated { get; set; }
public void RaiseUpdates()
{
_counter++;
var handler = Updated;
if (handler != null)
handler(this, _counter);
// 以下のコードではダメ(スレッドセーフではない)
// if (Updated != null)
// Updated(this, _counter); // ここでは Updated がnullになっている可能性がある
}
private int _counter;
}
このように、イベントハンドラの呼び出し時にはnullチェックが欠かせない。
さらに、スレッドセーフにするために、var handler = Updated
のように変数に代入を行う必要がある。
というのも、nullチェックの実行中に、別のスレッドによってUpdated
プロパティにnullが設定されている可能性があるためである。
null条件演算子(?.
)を使うと、上記イディオムを以下のように書くことができる。
Updated?.Invoke(this, _counter);
?.
演算子は、演算子の左辺を評価し、nullでない値なら、右辺が実行される。
左辺がnullなら、右辺は実行されず、次の文へ進む。
このコードは、元のイディオムと同じようにスレッドセーフでもある。