c# - Evaluación de la declaración de corto circuito-¿está garantizado?
conditional-operator logical-operators (6)
Pregunta rápida aquí sobre las declaraciones de cortocircuito en C #. Con una sentencia if como esta:
if (MyObject.MyArray.Count == 0 || MyObject.MyArray[0].SomeValue == 0)
{
//....
}
¿Se garantiza que la evaluación se detendrá después de la porción "MyArray.Count", siempre que esa porción sea verdadera? De lo contrario obtendré una excepción nula en la segunda parte.
Prefiero usar el operador &&, porque luego prueba un positivo (mi matriz contiene elementos), en lugar de negativo (mi error no contiene elementos):
if (MyObject.MyArray.Count > 0 && MyObject.MyArray[0].SomeValue == 0)
{
//....
}
Esto también está garantizado para cortocircuito.
Sí,
Para las operaciones AND si cualquiera de los operandos se evaluó como falso, la expresión total se evaluó como falso, entonces no hay necesidad de evaluar las expresiones restantes, y en el caso de la operación OR si alguno de los operandos evaluados es verdadero, se puede omitir la evaluación restante.
Entonces usando && o || operador, la expresión completa se puede evaluar como verdadera o falsa sin evaluar todas las subexpresiones.
Pero considere también su efecto secundario . Este artículo puede ser útil para comprender en profundidad la evaluación de cortocircuitos con algunos ejemplos del mundo real.
Sí, está garantizado, pero aún puede obtener una excepción de referencia nula si MyArray es nulo (o MyObject, obviamente).
Sí, está garantizado.
http://msdn.microsoft.com/en-us/library/6373h346%28v=VS.80%29.aspx
El operador OR condicional (||) realiza un OR lógico de sus operandos bool, pero solo evalúa su segundo operando si es necesario.
Sí, esto está garantizado.
Especificación de lenguaje C # - 7.11 Operadores lógicos condicionales :
El
&&
y||
Los operadores se denominan operadores lógicos condicionales. También se les llama operadores lógicos de "cortocircuito".
Por lo tanto, admitirán el cortocircuito lógico por definición ; puede confiar en este comportamiento.
Ahora es importante hacer una distinción entre un operador condicional y un operador lógico :
- Sólo los operadores condicionales admiten cortocircuitos, los operadores lógicos no lo hacen.
- Los operadores lógicos de C # se parecen a 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 pueden (esto es un poco de un tecnicismo, ya que la evaluación condicional del operador implica una resolución de sobrecarga y esta resolución de sobrecarga puede resolverse en una sobrecarga personalizada del operador lógico del tipo, por lo que puede evitar esta limitación). cierto punto).
Solo una pequeña observación.
Tu dices esto:
De lo contrario obtendré una excepción nula en la segunda parte. (énfasis mío)
Esto no es verdad, en realidad. Si el cortocircuito no estuviera garantizado, podría obtener una IndexOutOfRangeException
en la segunda parte.
Aún es posible que pueda obtener una NullReferenceException
, si el primer elemento de su objeto MyArray
es realmente nulo (o si alguno de los otros objetos en esa expresión lo es).
El único cheque totalmente seguro sería este:
bool conditionHolds =
MyObject == null ||
MyObject.MyArray == null ||
MyObject.MyArray.Count == 0 ||
MyObject.MyArray[0] == null ||
MyObject.MyArray[0].SomeValue == 0;
if (conditionHolds)
{
//....
}