Está confiando en & & cortocircuito seguro in.NET?


Asume que myObj es null. ¿Es seguro escribir esto?

if(myObj != null && myObj.SomeString != null)

Sé que algunos idiomas no ejecutarán la segunda expresión porque && se evalúa como false antes de que se ejecute la segunda parte.

Author: CodesInChaos, 2011-01-27

9 answers

Sí. En C # && y || están cortocircuitando y por lo tanto evalúa el lado derecho solo si el lado izquierdo no determina ya el resultado. Los operadores & y | por otro lado no cortocircuitan y siempre evalúan ambos lados.

La especificación dice:

Los operadores && y || se denominan operadores lógicos condicionales. También se les llama operadores lógicos de "cortocircuito".
...
La operación x && y corresponde a la operación x & y, excepto que y se evalúa solo si x es true
...
La operación x && y se evalúa como (bool)x ? (bool)y : false. En otras palabras, x se evalúa primero y se convierte a tipo bool. Entonces, si x es true, y se evalúa y se convierte a tipo bool, y esto se convierte en el resultado de la operación. De lo contrario, el resultado de la operación es false.

(Especificación del Lenguaje C # Versión 4.0-7.12 Lógica condicional operadores)

Una propiedad interesante de && y || es que están cortocircuitando incluso si no operan en bools, sino tipos donde el usuario sobrecarga los operadores & o | junto con el operador true y false.

La operación x && y se evalúa como T.false((T)x) ? (T)x : T.&((T)x, y), donde T.false((T)x) es una invocación del operator false declarado en T, y T.&((T)x, y) es una invocación del operator & seleccionado. Además, el valor (T) x solo se evaluará una vez.

En otras palabras, x primero se evalúa y se convierte a tipo T y operator false se invoca en el resultado para determinar si x es definitivamente false.
Entonces, si x es definitivamente false, el resultado de la operación es el valor previamente calculado para x convertido a tipo T.
De lo contrario, y se evalúa, y el operador seleccionado & se invoca sobre el valor previamente calculado para x convertido a tipo T y el valor calculado para y para producir el resultado de la operación.

(Especificación del lenguaje C # Versión 4.0-7.12.2 Operadores lógicos condicionales definidos por el usuario)

 65
Author: CodesInChaos,
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-10-29 09:56:17

Sí, C# usa cortocircuitos lógicos.

Tenga en cuenta que aunque C# (y algunos otros lenguajes.NET) se comportan de esta manera, es una propiedad del lenguaje, no del CLR.

 14
Author: harpo,
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
2011-05-19 15:03:55

Sé que llego tarde a la fiesta, pero en C# 6.0 también puedes hacer esto:

if(myObj?.SomeString != null)

Que es lo mismo que arriba.

Véase también: ¿Qué es el signo de interrogación y el operador de punto ?. ¿media en C # 6.0?

 6
Author: Drew Delano,
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 12:18:01

Su código es seguro - && y || ambos están cortocircuitados. Puedes usar operadores no cortocircuitados & o|, que evalúan ambos extremos, pero realmente no veo eso en mucho código de producción.

 4
Author: Joe Enos,
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
2011-01-27 19:05:06

Claro, es seguro en C#, si el primer operando es false entonces el segundo nunca se evalúa.

 3
Author: Mauricio,
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
2011-01-27 19:02:54

Un ejemplo es

if(strString != null && strString.Length > 0)

Esta línea causaría una excepción nula si ambos lados se ejecutaran.

Interesante nota al margen. El ejemplo anterior es bastante más rápido que el método IsNullOrEmpty.

 1
Author: Bengie,
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
2011-01-27 19:30:43

Es perfectamente seguro. C# es uno de esos lenguajes.

 0
Author: Ilya Kogan,
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
2011-01-27 19:02:28

Sí, C# y la mayoría de los lenguajes calculan las oraciones if de izquierda a derecha.

VB6 por cierto calculará todo, y lanzará una excepción si es null...

 0
Author: Yochai Timmer,
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
2011-01-27 19:12:29

En C#, && y || están cortocircuitados, lo que significa que la primera condición se evalúa y el resto se ignora si se determina la respuesta.

En VB.NET, AndAlso y OrElse también están cortocircuitados.

En JavaScript, && y || también están cortocircuitados.

Menciono VB.NET para mostrar que el feo hijastro pelirrojo de. net también tiene cosas geniales, a veces.

Menciono JavaScript, porque si está haciendo desarrollo web, probablemente podría también use JavaScript.

 0
Author: John Grabauskas,
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-10-11 17:02:23