5

In C# ist garantiert, dass Ausdrücke von links nach rechts ausgewertet werden?Von links nach rechts Ausdruck Auswertung

Zum Beispiel:

myClass = GetClass(); 
if (myClass == null || myClass.Property > 0) 
    continue; 

Gibt es Sprachen, die nicht entsprechen?

Antwort

14

Sie tatsächlich beziehen sich auf eine Sprache Funktion namens „Kurzschließen logische Ausdrücke“:

Was dies bedeutet, ist dies: Wenn das Ergebnis eines logischen Ausdrucks nicht mehr ändern können, zum Beispiel wenn klar ist, dass der Ausdruck unabhängig von "wahr" oder "falsch" ausgewertet wird, werden die verbleibenden Teile des Ausdrucks nicht ausgewertet.

Zum Beispiel, C#, Java oder JavaScript tun das, und Sie können sich darauf in diesen Sprachen verlassen (um Ihre Frage zu beantworten).

In Ihrem Fall, wenn MyClass nicht null ist:

  • MyClass == null das Ergebnis falsch
  • da es ein „oder“ Ausdruck ist, noch der zweite Teil das Ergebnis ändern können, so wird es
  • ausgewertet
  • myClass.Property > 0 bestimmt das Endergebnis

wenn MyClass null ist:

  • MyClass == null true ausgewertet
  • da es ein „oder“ Ausdruck ist, ist es egal, was
  • nicht mehr Auswertung folgt durchgeführt wird, ist das Endergebnis stimmt

Es Sprachen sind, die tun logische Ausdrücke nicht kurzschließen. Klassisches VB ist ein Beispiel, hier würde "myClass.Property> 0" ausgewertet werden und einen Fehler erzeugen, wenn MyClass null wäre (in VB "Nothing" genannt).

0

Die Auswertungsreihenfolge hängt vom Operator ab, in diesem Fall ist der Boolesche Wert oder (||) so definiert, dass er short-circuiting lautet, damit solche Konstrukte funktionieren.

5

Kurzschlüssen wird in Abschnitt 7.11 des C# 3.0 spec beschrieben:

Der Betrieb x || y entspricht der Operation x | y, außer dass y nur ausgewertet wird, wenn x nicht wahr ist.

Also ja, dir geht es gut.

Wie für andere Sprachen - ich spreche nie gerne für alle Sprachen. In VB.NET können Sie OrElse und AndAlso verwenden, die kurzgeschlossen sind, aber normales Oder und And nicht.

2

Aber Vorsicht:

wenn Sie etwas haben, wie

sprintf (buf, "% s% s", func1 (& var), func2 (& var));

mit Nebenwirkungen auf var, es ist nicht definiert (in C bin ich mir nicht sicher, ob die Bewertungsreihenfolge in anderen Sprachen definiert ist), in welcher Reihenfolge func1() und func2() ausgeführt werden (es kommt darauf an Ordnung (links oder rechts) werden die Argumente auf den Stapel gelegt und von dort ausgewertet.

+0

In C# ist die genaue Reihenfolge definiert. – Martijn

0

ich bin nicht sicher, Sie sind wirklich interessiert, um oder in Auswertung Kurzschluss?

ich bin nicht 100 % sicher, aber soweit ich weiß, wird die Reihenfolge der Auswertung in C# immer gleich sein (und ich nehme an, wenn nicht alle .net Sprachen) .Kurzschlussauswertung funktioniert wie in den vorherigen Antworten erklärt.

In C# können Sie jedoch mit einfachen Operatoren (& statt & &) einen Kurzschluss vermeiden. Normalerweise möchten Sie kurzschließen, aber es kann ein Fall sein, in dem Sie alle Auswertungen ausführen möchten.

0

Die und/oder Operatoren in Sprachen wie Ada, Visual Basic und Pascal schließen nicht kurz. Sie bieten zusätzliche Operatoren, um diese Funktionalität zu ermöglichen, wie "und dann" und "oder sonst" in Ada.

0

Python hat Kurzschluss or und and Betreiber.

0

In Java und Haskell & & und || Kurzschluss auch.

Interessant am Rande: in Haskell dies natürlich mit der Sprache kommt (Sie können Ihre eigenen Operatoren definieren, die dies tun), während in Java und C# ist es spezifische für die beiden Betreiber.

0

Eigentlich ist Kurzschluss ein Teil, aber Sie müssen auch wissen, ob die Sprache von links nach rechts die Bewertung garantiert. Zum Beispiel C (ANSI, ISO, C99) garantieren NICHT von links nach rechts Bewertung. Im Beispielcode wäre es möglich, den Wert von Property vor der Überprüfung auf NULL zu prüfen oder beides gleichzeitig zu tun ... die meisten Compiler tun das nicht, aber es gibt nichts, was sie davon abhält und vollständig mit der Spezifikation konform zu sein. Es sagt Ihnen sogar, dass Sie solchen Code NICHT schreiben sollten.