16

Pregunta rápida aquí sobre declaraciones de cortocircuito en C#. Con una sentencia if como esta:Evaluación de declaración de cortocircuito: ¿está garantizado? [C#]

if (MyObject.MyArray.Count == 0 || MyObject.MyArray[0].SomeValue == 0) 
{ 

//.... 
} 

¿Está garantizado que la evaluación se detendrá después de la parte "MyArray.Count", a condición de que la porción es cierto? De lo contrario, obtendré una excepción nula en la segunda parte.

+1

En caso de que haga esta pregunta porque * sí * obtuvo una excepción de referencia nula del código anterior, es probable que sea porque 'MyArray' es nulo o' MyArray [0] 'contiene un valor nulo. Ver mi respuesta –

Respuesta

34

Sí, esto está garantizado.

C# Language Specification - 7.11 Conditional logical operators:

Los && y || operadores son llamados los operadores lógicos condicionales. También se denominan operadores lógicos de "cortocircuito".

tanto que apoyarán lógica de cortocircuito por definición - Puede confiar en este comportamiento.

Ahora bien, es importante hacer una distinción entre un condicional operador y un operador lógico :

  • Sólo operadores condicionales apoyar cortocircuitos, operadores lógicos no lo hacen.
  • Los operadores lógicos de C# tienen el mismo aspecto que sus contrapartes condicionales, pero con un carácter menos, por lo que un OR lógico es | y un AND lógico es &.
  • Los operadores lógicos pueden estar sobrecargados pero los operadores condicionales no (esto es un poco técnico ya que la evaluación de operador condicional implica resolución de sobrecarga y esta resolución de sobrecarga puede resolverse a una sobrecarga personalizada del operador lógico del tipo, por lo que puede evitar esto limitación en cierta medida).
+1

+1 para realmente citar el CLS. – Polynomial

5

Sí, está garantizado, pero aún puede obtener una excepción de referencia nula si MyArray es nulo (o MyObject para el caso, obviamente).

0

yo prefiero usar el operador & &, porque entonces prueba un positivo (mi matriz contiene elementos), en lugar de negativo (mi error no contiene material):

if (MyObject.MyArray.Count > 0 && MyObject.MyArray[0].SomeValue == 0) 
{ 

//.... 
} 

Esto también se garantiza que cortocircuito.

+0

El resultado de este código no es el mismo que el de él. En el suyo, si el conteo es 0, cortocircuita y entra en el bloque. En el suyo, * solo * ingresa al bloque en el valor del primer elemento siendo 0. –

2

Solo una pequeña observación.

Usted dijo lo siguiente:

De lo contrario, obtendrá una excepción nula en la segunda parte. (énfasis mío)

Esto no es cierto, en realidad. Si no se garantizaran los cortocircuitos, podría obtener un IndexOutOfRangeException en la segunda parte.

Es todavía posible que usted podría conseguir un NullReferenceException, si el primer elemento de la realidad objeto es nula (o si cualquiera de los otros objetos de esa expresión son).

La única totalmente comprobación segura sería la siguiente:

bool conditionHolds = 
    MyObject == null || 
    MyObject.MyArray == null || 
    MyObject.MyArray.Count == 0 || 
    MyObject.MyArray[0] == null || 
    MyObject.MyArray[0].SomeValue == 0; 

if (conditionHolds) 
{ 
    //.... 
} 
+1

Creo que mencionó: if (! ConditionHolds) – riffnl

+0

@riffnl: No, solo estaba haciendo mi ejemplo consistente con el código del OP. (Él/ella parece querer que el código haga algo en el caso negativo). –

2

Sí,

a favor y en operaciones de si alguno de los operandos evaluadas para la expresión a continuación total de falsa evaluado como false entonces no es no es necesario evaluar las expresiones restantes, y en el caso de la operación OR si alguno de los operandos se evalúa como verdadero, la evaluación restante se puede omitir

Así que al usar & & o || operador, la expresión completa se puede evaluar como verdadera o falsa sin evaluar todas las sub expresiones.

Pero considere su side effect también. This article puede ser útil para comprender en profundidad la evaluación de cortocircuitos con algunos ejemplos del mundo real.

Cuestiones relacionadas