martes, 4 de marzo de 2014
El operador “?.”, también llamado safe navigation operator, era la característica más demandada para el lenguaje C# en Uservoice, uno de los principales canales utilizado por Microsoft para obtener feedback e ideas a aplicar en nuevas versiones de sus productos, y parece que definitivamente se está considerando la posibilidad de incluir este útil azucarillo sintáctico tanto en C# como en VB.
Para los que no lo conozcáis, se trata de una construcción que permite acceder a propiedades de objetos sin temor a las null reference exceptions lanzadas cuando estos objetos son nulos.
Mejor veámoslo sobre un ejemplo. Imaginemos la siguiente clase, a la que damos uso un poco más abajo:
public class Person { public Person Father { get; set; } public string Name { get; set; } [...] } string name = me.Father.Father.Name; Console.WriteLine("My grandpa’s name is: "+ name);Obviamente, si la variable
me
contiene un nulo nuestra aplicación se detendría lanzándonos una cruel excepción. Y lo mismo ocurriría si el nulo lo encontramos en me.Father
o en me.Father.Father
, ¿verdad?Por esta razón, lo habitual es proteger nuestras aplicaciones contra estos casos introduciendo comprobaciones en cada uno de los puntos para impedir la catástrofe y ofrecer un resultado razonable cuando aparezcan dichos valores nulos:
string name = me != null && me.Father != null && me.Father.Father!= null ? me.Father.Father.Name : null; Console.WriteLine("My grandpa’s name is: " + (name ?? "I don’t know"));La característica que en palabras de Mads Torgersen (PM de C# en Microsoft) está siendo “seriamente considerada”, consistiría en añadir a los lenguajes C# y VB.NET un nuevo operador de navegación segura “?.” (interrogación punto) que se utilizaría en lugar del punto para navegar por grafos de objetos y, a diferencia de éste, retornaría null al encontrarse con un valor nulo durante la navegación.
Así, el código anterior podría escribirse de una forma bastante más limpia y legible:
var name = me?.Father?.Father?.Name; Console.WriteLine("My grandpa’s name is " + ( name ?? "I don’t know"));En este caso da igual si el nulo está en
me
, en me.Father
o en me.Father.Father
: en todos ellos la expresión completa retornaría null. Pero aún hay más: la inclusión de este operador no sólo se aplicaría a la navegación por propiedades, sino a otras construcciones del lenguaje como la invocación a métodos, evitando la excepción si el objeto sobre el que se actúa es nulo:
var myFamily = me?.GetFamily();O también el acceso a valores mediante un índice:
var myMary = me?.Children?["mary"];En definitiva, se trata de una característica muy interesante para simplificar nuestro código y hacerlo más legible. Según Torgersen, se va a prototipar durante los próximos meses, por lo que sería posible encontrarlo ya en la próxima versión de C#.
Fuentes:
- At last, C# is getting “?.”, sometimes called the Safe Navigation Operator
- Uservoice suggestion: Add "?." operator to C#
7 Comentarios:
Es una idea cojonuda. Espero que lo implementen cuanto antes.
Hola!
Supongo que aún queda un poco para poder usarlo, pero sí, la verdad es que pinta bastante bien :)
Gracias por comentar :)
Ummmmm interesante, y con esto ya me olvidar de la secuencia de "objeto not nothing is AndAlso objeto.objeto2 not nothing is.....".
Me gusta...
Joselín.
La idea está bien, aunque si pudiera elegir hubiese preferido poder definir referencias que no permitan valores nulos. Evitaría más bugs.
Una duda sobre el comportamiento de este operador, ¿qué pasaría si el tipo de la expresión no es un tipo por referencia?
Por ejemplo, si en tus clases de ejemplo Person tuviera una propiedad Age de tipo int, y hago:
var age = person?.Father?.Father?.Age;
¿El tipo de age sería int o Nullable<int>?
Hola, Juanma!
Efectivamente, en caso de ser un tipo valor T, el retorno de la expresión sería su correspondiente Nullable para que todo sea consistente.
Un saludo!
Muy bueno!!!, a esperar...
Para evitar nulos puedes utilizar lo que en otros lenguajes se llama "Maybe" u "Option" en F#, busca por implementaciones de Maybe para c# en github.
En cuanto al valor de age en caso de ser nulas las propiedades, este sería el valor "default" de int, en este caso 0.
Enviar un nuevo comentario