Supongamos que quiero comprobar un montón de objetos para asegurarse de que ninguna es nulo:¿Puedo forzar mi propio cortocircuito en una llamada a un método?
if (obj != null &&
obj.Parameters != null &&
obj.Parameters.UserSettings != null) {
// do something with obj.Parameters.UserSettings
}
Es una posibilidad atractiva para escribir una función de ayuda a aceptar un número variable de argumentos y simplificar este tipo de cheque:
static bool NoNulls(params object[] objects) {
for (int i = 0; i < objects.Length; i++)
if (objects[i] == null) return false;
return true;
}
A continuación, el código anterior podría llegar a ser:
if (NoNulls(obj, obj.Parameters, obj.Parameters.UserSettings)) {
// do something
}
derecho? incorrecto Si obj
es nulo, obtendré NullReferenceException
cuando intento pasar obj.Parameters
a NoNulls
.
Por lo tanto, el enfoque anterior es claramente erróneo. Pero la instrucción if
que usa el operador &&
funciona bien, ya que está cortocircuitada. Entonces: ¿hay alguna manera de hacer que un método se cortocircuite, de modo que sus argumentos no se evalúen hasta que se haga referencia explícita dentro del método?
Lo que realmente necesita para resolver este problema no es la evaluación perezosa de los argumentos del método, aunque, como usted nota, eso sería el truco. Lo que sería mejor es un operador x.?y que tenga la semántica de (x == null? Null: x.y) - de esa manera usted puede decir "if (obj.?Parameters.?UserSettings== null)". Consideramos un operador de este tipo para C# 4 pero nunca lo implementamos. Quizás para una futura versión hipotética. –
Eso es realmente interesante. ¿Hay otros lenguajes que implementan un operador equivalente? –
@Chris: Groovy sí. Se llama operador de desreferenciación seguro de nulos. Es bueno saber que el equipo de C# lo ha considerado y podría considerarlo de nuevo :) –