¿Hay un" opuesto " al operador coalescente nulo? (any en cualquier idioma?)


La coalescencia nula se traduce aproximadamente a 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 seems parece superfluo. Preferiría algo como return x :: x.y;, donde lo que sigue a :: se evalúa solo si lo que lo precede no es null.

Veo esto como casi un opuesto a la coalescencia nula, tipo de mezclado con un breve, en línea null-check, pero estoy [casi ] seguro de que no hay tal operador en C#.

¿Hay otros lenguajes que tengan tal operador? Si es así, cómo se llama?

(sé que puedo escribir un método en C#; yo uso return NullOrValue.of(x, () => x.y);, pero si tienes algo mejor, me gustaría ver eso también.)

Author: Jay, 2010-05-28

12 answers

Está el operador de desreferenciación de null-safe (?.) in Groovy... Creo que eso es lo que buscas.

(También se llama el operador de navegación segura .)

Por ejemplo:

homePostcode = person?.homeAddress?.postcode

Esto dará null si person, person.homeAddress o {[3] } es nulo.

(Esto está ahora disponible en C# 6.0 pero no en versiones anteriores)

 59
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 16:49:43

¿Consideramos agregar?. a C # 4. No hizo el corte; es una característica de" agradable tener", no una característica de" tengo que tener". Lo consideraremos de nuevo para futuras versiones hipotéticas del idioma, pero no aguantaría la respiración esperando si fuera tú. No es probable que se vuelva más crucial a medida que pasa el tiempo. :-)

 33
Author: Eric Lippert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-29 04:19:26

Si tienes un tipo especial de lógica booleana de cortocircuito, puedes hacer esto (ejemplo de javascript):

return x && x.y;

Si x es null, entonces no evaluará x.y.

 15
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-28 14:33:44

Simplemente se sintió bien agregar esto como una respuesta.

Supongo que la razón por la que no hay 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 un tipo de referencia o valor (es decir, class x con miembro int y - por lo tanto, desafortunadamente sería inutilizable en muchas situaciones.

No estoy diciendo, sin embargo, que no me gustaría verlo!

Una posible solución a ese problema sería para el operador para levantar automáticamente una expresión de tipo valor en el lado derecho a un valor nullable. Pero entonces tienes el problema de que x.y donde y es un int realmente devolverá un int? que sería un dolor.

Otra solución, probablemente mejor, sería que el operador devuelva el valor predeterminado (es decir, null o cero) para el tipo en el lado derecho si la expresión de la izquierda es null. Pero entonces tienes problemas para distinguir escenarios donde un cero/null fue leído de x.y o si fue suministrado por el operador de acceso seguro.

 7
Author: Andras Zoltan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-28 15:29:58

Delphi tiene: (en lugar de .) operador, que es nulo-seguro.

Estaban pensando en agregar a ?. operator to C # 4.0 to do the same, but that got the chopping block.

Mientras tanto, hay IfNotNull () que tipo de rasguños que pican. Es ciertamente más grande que ?. o:, pero te permite componer una cadena de operaciones que no te dará una excepción NullReferenceException si uno de los miembros es null.

 6
Author: 48klocs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:33

En Haskell, puedes usar el operador >>:

  • Nothing >> Nothing es Nothing
  • Nothing >> Just 1 es Nothing
  • Just 2 >> Nothing es Nothing
  • Just 2 >> Just 1 es Just 1
 3
Author: dave4420,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-28 14:50:25

Haskell tiene fmap, que en este caso creo que es equivalente aData.Maybe.map. Haskell es puramente funcional, por lo que lo que está buscando sería

fmap select_y x

Si x es Nothing, esto devuelve Nothing. Si x es Just object, esto devuelve Just (select_y object). No es tan bonito como la notación de puntos, pero dado que es un lenguaje funcional, los estilos son diferentes.

 3
Author: Norman Ramsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-28 15:23:24

PowerShell le permite hacer referencia a propiedades (pero no a métodos) en una referencia null y devolverá null si la instancia es null. Puedes hacer esto a cualquier profundidad. Esperaba que la característica dinámica de C# 4 soportara esto, pero no lo hace.

$x = $null
$result = $x.y  # $result is null

$x = New-Object PSObject
$x | Add-Member NoteProperty y 'test'
$result = $x.y  # $result is 'test'

No es bonito, pero podría agregar un método de extensión que funcionará de la manera que describe.

public static TResult SafeGet<T, TResult>(this T obj, Func<T, TResult> selector) {
    if (obj == null) { return default(TResult); }
    else { return selector(obj); }
}

var myClass = new MyClass();
var result = myClass.SafeGet(x=>x.SomeProp);
 2
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-28 14:48:18

Cree una instancia estática de su clase en algún lugar con todos los valores predeterminados correctos para los miembros.

Por ejemplo:

z = new Thingy { y=null };

Entonces en lugar de su

return x != null ? x.y : null;

Puedes escribir

return (x ?? z).y;
 1
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-04 19:32:16
public class ok<T> {
    T s;
    public static implicit operator ok<T>(T s) { return new ok<T> { s = s }; }
    public static implicit operator T(ok<T> _) { return _.s; }

    public static bool operator true(ok<T> _) { return _.s != null; }
    public static bool operator false(ok<T> _) { return _.s == null; }
    public static ok<T> operator &(ok<T> x, ok<T> y) { return y; }
}

A menudo necesito esta lógica para cadenas:

using ok = ok<string>;

...

string bob = null;
string joe = "joe";

string name = (ok)bob && bob.ToUpper();   // name == null, no error thrown
string boss = (ok)joe && joe.ToUpper();   // boss == "JOE"
 1
Author: J Bryan Price,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-12 23:40:41

Esto se está agregando en C# vNext (Roslyn powered C#, 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

 1
Author: Micah Zoltu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-30 22:11:53

El llamado "operador condicional nulo" ha sido introducido en C# 6.0 y en Visual Basic 14.
En muchas situaciones se puede utilizar como el opuesto exacto del operador null-coalescing:

int? length = customers?.Length; // null if customers is null   
Customer first = customers?[0];  // null if customers is null  
int? count = customers?[0]?.Orders?.Count();  // null if customers, the first customer, or Orders is null

Https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

 0
Author: Jpsy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-06 10:12:54