Do C # 6 em diante, você pode apenas usar:
MyEvent?.Invoke();
ou:
obj?.SomeMethod();
O ?.
é o operador de propagação nula e causará um .Invoke()
curto-circuito quando o operando for null
. O operando é acessado apenas uma vez, não havendo risco do problema de "mudança de valor entre checar e invocar".
===
Antes do C # 6, não: não há mágica de segurança nula, com uma exceção; métodos de extensão - por exemplo:
public static void SafeInvoke(this Action action) {
if(action != null) action();
}
agora isso é válido:
Action act = null;
act.SafeInvoke(); // does nothing
act = delegate {Console.WriteLine("hi");}
act.SafeInvoke(); // writes "hi"
No caso de eventos, tem a vantagem de remover também a condição de corrida, ou seja, você não precisa de uma variável temporária. Normalmente, você precisa de:
var handler = SomeEvent;
if(handler != null) handler(this, EventArgs.Empty);
mas com:
public static void SafeInvoke(this EventHandler handler, object sender) {
if(handler != null) handler(sender, EventArgs.Empty);
}
podemos usar simplesmente:
SomeEvent.SafeInvoke(this); // no race condition, no null risk