In regelmäßigen Abständen wundere ich mich darüber:
Der Kurzschluss-ODER würde immer den gleichen Wert zurückgeben, den der kurzgeschlossene ODER-Operator?
Ich gehe davon aus, dass der Kurzschluss ODER immer schneller ausgewertet wird. War der kurzgeschlossene ODER-Operator aus Gründen der Konsistenz in der C # -Sprache enthalten?
Was habe ich vermisst?
f()
eine Ausnahme auslöst, betrachtentrue || f()
undtrue | f()
. Sehen Sie den Unterschied? Der erstere Ausdruck wertet austrue
, die Auswertung des letzteren führt dazu, dass eine Ausnahme ausgelöst wird.Antworten:
Beide Operanden waren für verschiedene Dinge gedacht und stammten von C, das keinen booleschen Typ hatte. Die Kurzschlussversion || funktioniert nur mit Booleschen Werten, während die Nicht-Kurzschlussversion | arbeitet mit integralen Typen, die bitweise oder. Es funktionierte zufällig als logische Nicht-Kurzschlussoperation für Boolesche Werte, die durch ein einzelnes Bit dargestellt werden und 0 oder 1 sind.
http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators#Logical
quelle
|
Operator, wenn er auf zwei boolesche Werte angewendet wird,or
in CIL in denselben Operator kompiliert wird wie wenn er auf zwei ganzzahlige Werte angewendet wird - im Gegensatz zu||
dem, der mitbrtrue
einer Bedingung in CIL kompiliert wird springen.|
(das bitweise-oder) muss für Typen wie nicht kurzgeschlossen seinint
.|
Dies liegt daran, dass Sie in fast allen Fällen beide Seiten eines Ausdrucks berechnen müssen, um das richtige Ergebnis zu berechnen. Was ist zum Beispiel das Ergebnis von7 | f(x)
?Wenn
f(x)
nicht ausgewertet wird, können Sie nicht sagen.Darüber hinaus wäre es inkonsistent, diesen Operator kurzzuschließen
bool
, wenn er nicht kurzgeschlossen istint
. Ich glaube übrigens, ich habe nie|
absichtlich logische Vergleiche verwendet, und es ist sehr unpraktisch, von|
einem logischen Operator zu sprechen .||
Dies ist jedoch für logische Vergleiche gedacht, bei denen die Kurzschlussbewertung einwandfrei funktioniert.Gleiches gilt auch für C und C ++, wo der Ursprung dieser Operatoren liegt.
quelle
Dies ist richtig. Der Kurzschluss-ODER-Operator (||) gibt immer den gleichen Wert zurück wie der Nicht-Kurzschluss-ODER-Operator (|). (*)
Wenn jedoch der erste Operand wahr ist, bewirkt der Kurzschlussoperator keine Auswertung des zweiten Operanden, während der Nicht-Kurzschlussoperator immer eine Auswertung beider Operanden bewirkt. Dies kann sich auf die Leistung und manchmal auf Nebenwirkungen auswirken.
Es gibt also eine Verwendung für beide: Wenn Sie sich um die Leistung kümmern und die Auswertung des zweiten Operanden keine Nebenwirkungen hervorruft (oder wenn Sie sich nicht um sie kümmern), verwenden Sie auf jeden Fall den Kurzschlussoperator . Wenn Sie jedoch aus irgendeinem Grund die Nebenwirkungen des zweiten Operanden benötigen , sollten Sie den Operator ohne Kurzschluss verwenden.
Ein Beispiel, bei dem Sie den Nicht-Kurzschlussoperator verwenden sollten:
(*) Mit Ausnahme eines wirklich perversen Szenarios, in dem die Bewertung des ersten Operanden auf falsch durch Nebenwirkung den zweiten Operanden auf wahr anstatt auf falsch bewertet.
quelle
Es gibt zwei Gründe, die Variante ohne Kurzschluss zu verwenden:
Beibehalten von Nebenwirkungen (aber das ist klarer mit einer temporären Variablen zu codieren)
vereiteln Timing - Attacken durch die Gabel in dem Kurzschluss zu vermeiden (dies kann auch die Laufzeiteffizienz verbessern , wenn der zweite Operand ist eine Variable , aber das ist eine Mikro-Optimierung der Compiler ohnehin machen können)
quelle
wenn die rechte Klausel des Bedieners Nebenwirkungen hat und der Programmierer beabsichtigte, dass beide Nebenwirkungen auftreten sollen, bevor der Rückgabewert überprüft wird.
quelle