Desde C # 6 en adelante, puede usar:
MyEvent?.Invoke();
o:
obj?.SomeMethod();
El ?.es el operador de propagación nula, y provocará .Invoke()un cortocircuito cuando el operando esténull . Solo se accede al operando una vez, por lo que no hay riesgo de que se produzca el problema de "cambios de valor entre verificación e invocación".
===
Antes de C # 6, no: no hay magia segura para nulos, con una excepción; métodos de extensión, por ejemplo:
public static void SafeInvoke(this Action action) {
if(action != null) action();
}
ahora esto es válido:
Action act = null;
act.SafeInvoke(); // does nothing
act = delegate {Console.WriteLine("hi");}
act.SafeInvoke(); // writes "hi"
En el caso de los eventos, esto tiene la ventaja de eliminar también la condición de carrera, es decir, no necesita una variable temporal. Entonces, normalmente necesitarías:
var handler = SomeEvent;
if(handler != null) handler(this, EventArgs.Empty);
pero con:
public static void SafeInvoke(this EventHandler handler, object sender) {
if(handler != null) handler(sender, EventArgs.Empty);
}
podemos usar simplemente:
SomeEvent.SafeInvoke(this); // no race condition, no null risk