jueves, 12 de abril de 2007
Resulta que leyendo la especificación de C# 2.0 he encontrado, en el apartado correspondiente a los tipos anulables un nuevo operador que me ha parecido de lo más interesante, para el tratamiento rápido de valores nulos, el Null Coalescing Operator (NCO) u Operador de Fusión de Nulos (traducción libre).
El operador en cuestión, expresado como ?? (dos cierres de interrogación), permite devolver un valor si no es nulo, o devolver otro valor alternativo ante la nulidad del primero. En otras palabras, un código como:
O también escrito de la forma, utilizando el operador ternario:
Quedaría, utilizando el nuevo operador de fusión, como:
Qué limpio, ¿no?
A primera vista puede parecer que salvo mejorar la legibilidad, no aporta demasiadas ventajas frente al operador ternario ?, pero fijaos en el siguiente código, en un método que retorna el nombre del algo cuyo Id le llega como parámetro:
Utilizando el operador ternario ? podríamos dejarlo en una única línea:
Esto tiene una pega aparte de la dificultad de lectura: si el nombre del llamamos dos veces a obtenerNombre(id), lo cual podría tener efectos secundarios no deseados, o simplemente causar un problema de rendimiento. Para mejorarlo podríamos hacer esto, que mejora la legibilidad y llama sólo una vez al método, aunque es más largo de codificar, siendo muy similar al if inicial:
Con el nuevo operador el código quedaría así de simple:
Esto se ejecuta de la siguiente forma: se llama a obtenerNombre(id) y si no es nulo se retorna el valor obtenido. Sólo si el resultado de la expresión ha sido nulo se retornaría el literal "Desconocido".
No sé a vosotros, pero a mí me ha parecido interesantísimo, y de lo más útil.
El operador en cuestión, expresado como ?? (dos cierres de interrogación), permite devolver un valor si no es nulo, o devolver otro valor alternativo ante la nulidad del primero. En otras palabras, un código como:
if (s!=null)
return s;
else
return "por defecto";
O también escrito de la forma, utilizando el operador ternario:
return (s!=null?s:"por defecto");
Quedaría, utilizando el nuevo operador de fusión, como:
return s ?? "por defecto";
Qué limpio, ¿no?
A primera vista puede parecer que salvo mejorar la legibilidad, no aporta demasiadas ventajas frente al operador ternario ?, pero fijaos en el siguiente código, en un método que retorna el nombre del algo cuyo Id le llega como parámetro:
string nombre = obtenerNombre(id);
if (nombre==null)
return "Desconocido";
else
return nombre;
Utilizando el operador ternario ? podríamos dejarlo en una única línea:
return obtenerNombre(id)==null?"Desconocido":obtenerNombre(id);
Esto tiene una pega aparte de la dificultad de lectura: si el nombre del llamamos dos veces a obtenerNombre(id), lo cual podría tener efectos secundarios no deseados, o simplemente causar un problema de rendimiento. Para mejorarlo podríamos hacer esto, que mejora la legibilidad y llama sólo una vez al método, aunque es más largo de codificar, siendo muy similar al if inicial:
string p = obtenerNombre(id);
return p==null?"Desconocido":p;
Con el nuevo operador el código quedaría así de simple:
return obtenerNombre(id) ?? "Desconocido";
Esto se ejecuta de la siguiente forma: se llama a obtenerNombre(id) y si no es nulo se retorna el valor obtenido. Sólo si el resultado de la expresión ha sido nulo se retornaría el literal "Desconocido".
No sé a vosotros, pero a mí me ha parecido interesantísimo, y de lo más útil.
6 Comentarios:
Picha cuñao, la nueva especificación del C# es la 3.0, la 2.0 es la que viene con Visual Studio 2005
Jejeje, pues claro, no he dicho lo contrario... sin embargo, no había leído con detalle la especificación 2.0, y no conocía este operador, a pesar de estar utilizando VS2005.
La 3.0 tiene bastante más chicha, ya la iremos comentando poco a poco.
Creo que se ha deslizado un "bug", y debería ser "" return obtenerNombre(id) ?? "Desconocido"; "" ¿No? Tampoco conocía este operador, muy interesante :)
Efectivamente, Javier. Ya lo he corregido en el post, muchas gracias por tu atención y tus comentarios.
Así da gusto. :-)
Cómo se haría para verificar sí el decimal es nulo?
Hola!
Pues no estoy seguro de haber entendido la pregunta, pero... ¿te refieres a compararlo con null?
decimal? d;
// Hacer cosas con "d"
if(d == null)
{
...
}
Enviar un nuevo comentario