Périodiquement, je me pose des questions à ce sujet:
Le OU court-circuit retournerait toujours la même valeur que l'opérateur OU court-circuité le ferait?
Je m'attends à ce que le court-circuit OR soit toujours évalué plus rapidement. Alors, l'opérateur OR non court-circuité a-t-il été inclus dans le langage C # pour plus de cohérence?
Qu'est-ce que j'ai raté?
f()
déclenche une exception, considéronstrue || f()
ettrue | f()
. Voyez-vous la différence? La première expression est évaluéetrue
, l'évaluation de la dernière entraîne la levée d'une exception.Réponses:
Les deux opérandes étaient destinés à des choses différentes, provenant de C qui n'avait pas de type booléen. La version court-circuit || ne fonctionne qu'avec des booléens, tandis que la version non-court-circuit | fonctionne avec des types intégraux, effectuant un bit ou. Il s'est avéré que cela fonctionnait comme une opération logique sans court-circuit pour les booléens qui sont représentés par un seul bit, soit 0 ou 1.
http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators#Logical
la source
|
opérateur, lorsqu'il est appliqué à deux valeurs booléennes, est compilé dans le mêmeor
opérateur en CIL que lorsqu'il est appliqué à deux valeurs entières - contrairement à||
ce qui est compilé dans CIL en utilisantbrtrue
pour un conditionnel saut.|
(ou bit à bit) ne doit pas être en court-circuit pour des types commeint
. En effet, dans presque tous les cas, vous devez calculer les deux côtés d'une|
expression pour calculer le résultat correct. Par exemple, quel est le résultat de7 | f(x)
?Si
f(x)
n'est pas évalué, vous ne pouvez pas le dire.De plus, il serait incohérent de faire court-circuiter cet opérateur
bool
, alors qu'il ne l'est pasint
. Soit dit en passant, je pense que je n'ai jamais utilisé|
de comparaisons logiques intentionnellement, trouvant qu'il est très gênant de parler d'|
opérateur logique.||
cependant, c'est pour les comparaisons logiques, où l'évaluation des courts-circuits fonctionne bien.La même chose est valable même pour C et C ++, où l'origine de ces opérateurs est.
la source
C'est correct, l'opérateur OU en court-circuit (||) renverra toujours la même valeur que l'opérateur OU non-court-circuit (|). (*)
Cependant, si le premier opérande est vrai, l'opérateur de court-circuit ne provoquera pas d'évaluation du deuxième opérande, tandis que l'opérateur de non-court-circuit provoquera toujours l'évaluation des deux opérandes. Cela peut avoir un impact sur les performances et parfois des effets secondaires.
Donc, il y a une utilisation pour les deux: si vous vous souciez de la performance et que l'évaluation du deuxième opérande ne produit aucun effet secondaire (ou si vous ne vous en souciez pas), alors utilisez par tous les moyens l'opérateur de court-circuit . Mais si, pour une raison quelconque, vous avez besoin des effets secondaires du deuxième opérande, vous devez utiliser l'opérateur non-court-circuit.
Un exemple où vous devez utiliser l'opérateur de non-court-circuit:
(*) À l'exception d'un scénario vraiment perverti où l'évaluation du premier opérande à faux provoque par effet secondaire le deuxième opérande à évaluer vrai au lieu de faux.
la source
Il y aurait 2 raisons d'utiliser la variante sans court-circuit:
garder les effets secondaires (mais c'est plus clair à coder avec une variable temporaire)
déjouer les attaques de synchronisation en évitant la fourchette dans le court-circuit (cela peut même améliorer l'efficacité d'exécution si le deuxième opérande est une variable mais c'est une micro-optimisation que le compilateur peut faire de toute façon)
la source
si la clause de droite de l'opérateur a un effet secondaire, et le programmeur voulait qu'il souhaite que les deux effets secondaires se produisent avant de vérifier leur valeur de retour.
la source