la coalescencia nula se traduce aproximadamente en return x, unless it is null, in which case return y
A menudo necesito return null if x is null, otherwise return x.y
Puedo usar return x == null ? null : x.y;
No está mal, pero eso null
en el medio siempre me molesta, parece superfluo. Preferiría algo como return x :: x.y;
, donde lo que sigue a ::
se evalúa solo si lo que le precede no lo es null
.
Veo esto como casi un opuesto a la coalescencia nula, algo mezclado con una verificación nula en línea concisa, pero estoy [ casi ] seguro de que no existe tal operador en C #.
¿Hay otros idiomas que tengan un operador de este tipo? Si es así, ¿cómo se llama?
(Sé que puedo escribir un método para ello en C #; lo uso return NullOrValue.of(x, () => x.y);
, pero si tienes algo mejor, me gustaría verlo también).
return x ? x.y : NULL
. ¡Bien por convertir tipos de puntero a booleanos!Respuestas:
Ahí está el operador de desreferencia nula de fallos (?.) En el maravilloso ... Creo que eso es lo que está buscando.
(También se llama operador de navegación segura ).
Por ejemplo:
Esto dará nulo si
person
,person.homeAddress
operson.homeAddress.postcode
es nulo.(Esto ahora está disponible en C # 6.0 pero no en versiones anteriores)
fuente
null
, por ejemplo:def bar = foo ?: "<null>"
Decimal? post = pre == null ? null : SomeMethod( pre );
. Sería bueno si pudiera reducirlo a "Decimal? Post = pre :: SomeMethod (pre);"Consideramos agregar ?. a C # 4. No hizo el corte; es una característica "agradable de tener", no una característica "imprescindible". Lo consideraremos de nuevo para futuras versiones hipotéticas del idioma, pero no aguantaría la respiración esperando si fuera usted. No es probable que se vuelva más crucial a medida que pasa el tiempo. :-)
fuente
Si tiene un tipo especial de lógica booleana de cortocircuito, puede hacer esto (ejemplo de javascript):
Si
x
es nulo, no se evaluaráx.y
.fuente
Simplemente me pareció correcto agregar esto como respuesta.
Supongo que la razón por la que no existe tal cosa en C # es porque, a diferencia del operador coalescente (que solo es válido para tipos de referencia), la operación inversa podría producir una referencia o un tipo de valor (es decir,
class x
con miembroint y
, por lo que desafortunadamente sería inutilizable en muchas situaciones.Sin embargo, no estoy diciendo que no me gustaría verlo.
Una posible solución a ese problema sería que el operador elevara automáticamente una expresión de tipo de valor en el lado derecho a un valor anulable. Pero luego tiene el problema de que
x.y
donde y es un int, en realidad devolverá un, loint?
que sería una molestia.Otra solución, probablemente mejor, sería que el operador devolviera el valor predeterminado (es decir, nulo o cero) para el tipo del lado derecho si la expresión del lado izquierdo es nula. Pero luego tiene problemas para distinguir escenarios donde realmente se leyó un cero / nulo
x.y
o si fue proporcionado por el operador de acceso seguro.fuente
int?
como valor de retorno predeterminado, y el usuario puede cambiarlo a int si lo desea. Por ejemplo, si me gustaría llamar a algún métodoLookup
con un valor predeterminado de -1 en caso de que una de mis referencias seanull
:foo?.Bar?.Lookup(baz) ?? -1
?. :
ser un operador ternario, donde se requiere que el lado derecho sea del mismo tipo que el miembro apropiado dado en el medio?Delphi tiene el operador: (en lugar de.), Que es seguro para nulos.
Estaban pensando en agregar un?. operador a C # 4.0 para hacer lo mismo, pero eso consiguió el bloque de corte.
Mientras tanto, hay IfNotNull () que tipo de rasguños pican. Ciertamente es más grande que ?. o:, pero le permite componer una cadena de operaciones que no le enviará una NullReferenceException si uno de los miembros es nulo.
fuente
?.
es una característica del lenguaje C # 6.0, y sí que hace exactamente lo que el PO pidió aquí. Más vale tarde que nunca ^^En Haskell, puede utilizar el
>>
operador:Nothing >> Nothing
esNothing
Nothing >> Just 1
esNothing
Just 2 >> Nothing
esNothing
Just 2 >> Just 1
esJust 1
fuente
Haskell tiene
fmap
, que en este caso creo que es equivalente aData.Maybe.map
. Haskell es puramente funcional, así que lo que estás buscando seríaSi
x
es asíNothing
, esto vuelveNothing
. Six
es asíJust object
, esto vuelveJust (select_y object)
. No es tan bonito como la notación de puntos, pero dado que es un lenguaje funcional, los estilos son diferentes.fuente
PowerShell le permite hacer referencia a propiedades (pero no a métodos de llamada) en una referencia nula y devolverá nulo si la instancia es nula. Puede hacer esto a cualquier profundidad. Tenía la esperanza de que la función dinámica de C # 4 fuera compatible con esto, pero no es así.
No es bonito, pero puede agregar un método de extensión que funcione como lo describe.
fuente
A menudo necesito esta lógica para cadenas:
fuente
Cree una instancia estática de su clase en algún lugar con todos los valores predeterminados correctos para los miembros.
Por ejemplo:
entonces en lugar de tu
puedes escribir
fuente
Esto se está agregando en C # vNext (C # con tecnología de Roslyn, versiones con Visual Studio 2014).
Se llama propagación nula y se enumera aquí como completa. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status
También aparece aquí como completo: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c
fuente
El llamado "operador condicional nulo" se introdujo en C # 6.0 y en Visual Basic 14.
En muchas situaciones se puede utilizar como exactamente lo contrario del operador coalescente nulo:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
fuente