Periódicamente, me pregunto sobre esto:
¿El OR de cortocircuito siempre devolvería el mismo valor que el operador OR sin cortocircuito?
Espero que el OR de cortocircuito siempre se evalúe más rápidamente. Entonces, ¿se incluyó el operador OR sin cortocircuito en el lenguaje C # para mayor coherencia?
¿Qué me he perdido?
f()
plantea una excepción, consideretrue || f()
ytrue | f()
. ¿Ves la diferencia? La primera expresión se evalúa comotrue
, la evaluación de la segunda da como resultado una excepción.Respuestas:
Ambos operandos estaban destinados a cosas diferentes, provenientes de C que no tenía un tipo booleano. La versión de cortocircuito || solo funciona con booleanos, mientras que la versión sin cortocircuito | trabaja con tipos integrales, realizando un bit a bit o. Simplemente funcionó como una operación lógica sin cortocircuito para booleanos que están representados por un solo bit, siendo 0 o 1.
http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators#Logical
fuente
|
operador, cuando se aplica a dos valores booleanos, se compila en el mismoor
operador en CIL que cuando se aplica a dos valores enteros, a diferencia de lo||
que se compila en CIL usandobrtrue
un condicional saltar.|
(bitwise-or) no debe ser un cortocircuito para tipos comoint
. Eso es porque en casi todos los casos necesita calcular ambos lados de una|
expresión para calcular el resultado correcto. Por ejemplo, ¿cuál es el resultado de7 | f(x)
?Si
f(x)
no se evalúa, no se puede saber.Además, sería incoherente hacer que este operador produzca un cortocircuito
bool
cuando no sea un cortocircuitoint
. Por cierto, creo que nunca lo he usado|
para comparaciones lógicas intencionalmente, encontrar que es muy inconveniente hablar de|
operador lógico.||
sin embargo, es para comparaciones lógicas, donde la evaluación de cortocircuito funciona bien.Lo mismo es válido incluso para C y C ++, donde está el origen de esos operadores.
fuente
Esto es correcto, el operador OR de cortocircuito (||) siempre devolverá el mismo valor que el operador OR sin cortocircuito (|). (*)
Sin embargo, si el primer operando es verdadero, el operador de cortocircuito no causará la evaluación del segundo operando, mientras que el operador sin cortocircuito siempre causará la evaluación de ambos operandos. Esto puede tener un impacto en el rendimiento y, a veces, en los efectos secundarios.
Por lo tanto, hay un uso para ambos: si le importa el rendimiento y la evaluación del segundo operando no produce ningún efecto secundario (o si no le importan), entonces utilice el operador de cortocircuito. . Pero si por alguna razón necesita los efectos secundarios del segundo operando, entonces debe usar el operador sin cortocircuito.
Un ejemplo en el que debe usar el operador sin cortocircuito:
(*) Excepto en el caso de un escenario realmente pervertido en el que la evaluación del primer operando a falso causa por efecto secundario el segundo operando a evaluar como verdadero en lugar de falso.
fuente
Habría 2 razones para usar la variante de circuito no corto:
mantener los efectos secundarios (pero es más claro codificar con una variable temporal)
frustrar los ataques de tiempo evitando la bifurcación en el cortocircuito (esto incluso puede mejorar la eficiencia del tiempo de ejecución si el segundo operando es una variable pero eso es una microoptimización que el compilador puede hacer de todos modos)
fuente
si la cláusula de la derecha del operador tiene efectos secundarios, y el programador pretendía que deseara que ambos efectos secundarios ocurrieran antes de verificar su valor de retorno.
fuente