Frage

Ahh, nicht lieben Sie gerade einen guten ternären Missbrauch? Betrachten Sie den folgenden Ausdruck :):

true ? true : true ? false : false

Für diejenigen von euch, die jetzt völlig ratlos, kann ich Ihnen sagen, dass dieser auswertet true . Mit anderen Worten, es ist äquivalent dazu:

true ? true : (true ? false : false)

Aber das ist zuverlässig? Kann ich sicher sein, dass es dazu kommen wird unter Umständen nicht:

(true ? true : true) ? false : false

Man könnte sagen - gut, fügen Sie einfach Klammer dann oder Sie es nicht ganz nutzen - immerhin ist es eine bekannte Tatsache, dass Ternary Operatoren sind böse

Sicher sind sie, aber es gibt einige Umstände, wenn sie tatsächlich Sinn machen. Für die Neugierigen - ich wringe Code, der zwei Objekte durch eine Reihe von Eigenschaften vergleicht. Es wäre sehr schön, wenn ich es so schreiben kalt:

obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
obj1.Prop4.CompareTo(obj2.Prop4)

Klar und prägnant. Aber es ist, hängt von der ternären Operator Assoziativität wie im ersten Fall arbeiten. Parenthesis würde nur Spaghetti machen aus ihm heraus.

So - ist dies überall angegeben? Ich konnte es nicht finden.

War es hilfreich?

Lösung

Ja, können Sie sich darauf verlassen (nicht nur in C #, sondern in allen (die ich kenne) andere Sprachen ( außer PHP ... go figure) mit einem bedingten Operator) und Ihr anwendungs~~POS=TRUNC ist eigentlich eine ziemlich gängige Praxis, obwohl einige Leute verabscheut es.

Der entsprechende Abschnitt in ECMA-334 (der C # Standard) ist 14.13 §3:

  

Der Bedingungsoperator ist rechtsassoziativ, was bedeutet, dass die Operationen von rechts gruppiert nach links.   [Beispiel: Ein Ausdruck der Form a ? b : c ? d : e als a ? b : (c ? d : e) bewertet. Ende   Beispiel]

Andere Tipps

Wenn Sie fragen haben, nicht. Jeder Code lesen müssen nur den gleichen Prozess durchlaufen Sie getan haben, immer und immer wieder, jeder Zeit, dass Code Bedürfnisse sehen werden. einen solchen Code Debugging macht keinen Spaß. Schließlich würde es einfach mal so zu verwenden Klammern geändert werden.

Re: "Versuchen Sie das Ganze mit Klammern zu schreiben"

result = (obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
         (obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
         (obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
                                     obj1.Prop4.CompareTo(obj2.Prop4))))

Klarstellung:

  • "Wenn Sie fragen müssen, nicht."
  • "Jede Lesung Ihr Code ..."

Im Anschluss an den Konventionen gemeinsam in einem Projekt ist, wie Sie Konsistenz beibehalten, was die Lesbarkeit verbessert. Es wäre eine Besorgung Narr zu denken, können Sie Code lesbar für jedermann-einschließlich derjenigen schreiben, die nicht einmal die Sprache kennen!

Die Aufrechterhaltung Konsistenz innerhalb eines Projektes ist jedoch ein nützliches Ziel, und nicht zu diskutieren im Anschluss an ein akzeptierten Konventionen führen das Projekt, dass schmälert das eigentliche Problem zu lösen. Diejenigen, Ihre Code-Lese wird erwartet, dass sich der gemeinsame und akzeptierte Konventionen im Projekt verwendet, und sind sogar wahrscheinlich, jemand anders sein arbeiten direkt darauf. Wenn sie sie nicht kennen, dann werden sie erwartet, dass sie zu lernen und sollten wissen, wo um Hilfe zu wenden.

Das heißt: Wenn unter Verwendung von ternären Ausdrücke ohne Klammern eine gemeinsame und akzeptierte Konvention in Ihrem Projekt ist, dann verwenden, mit allen Mitteln! Das Sie zeigt an fragen hatte, dass es in Ihrem Projekt nicht üblich oder akzeptiert ist. Wenn Sie die Konventionen in Ihrem Projekt ändern möchten, tun Sie dann die offensichtlich eindeutig, es als etwas heruntersetzen zu diskutieren mit andere Projektmitglieder und Bewegung auf. Hier, dass Mittel Klammern oder mit if-else verwendet wird.

Ein letzter Punkt, darüber nachzudenken, wenn einige Ihrer Code scheint klug Sie:

  

Debugging ist doppelt so hart wie Sie den Code in erster Linie zu schreiben. Deshalb, wenn Sie den Code so geschickt wie möglich zu schreiben, Sie sind per definitionem nicht intelligent genug, um es zu debuggen. - Brian W. Kernighan

Die Behauptung, dass Klammern von der Lesbarkeit des Codes beeinträchtigen ist eine falsche Annahme. Ich finde den Klammerausdruck viel klarer. Persönlich würde ich die Klammern und / oder umformatieren über mehrere Zeilen Lesbarkeit zu verbessern. Neuformatierung über mehrere Zeilen und mit einrücken kann sogar die Notwendigkeit Klammern vermeiden. Und, ja, können Sie sich darauf verlassen, dass die Reihenfolge der Vereinigung deterministisch ist, von rechts nach links. Dadurch kann der Ausdruck links nach rechts in der erwarteten Art und Weise zu bewerten.

obj1.Prop1 != obj2.Prop1
     ? obj1.Prop1.CompareTo(obj2.Prop1)
     : obj1.Prop2 != obj2.Prop2
           ? obj1.Prop2.CompareTo(obj2.Prop2)
           : obj1.Prop3 != obj2.Prop3
                  ? obj1.Prop3.CompareTo(obj2.Prop3)
                  : obj1.Prop4.CompareTo(obj2.Prop4);

Siehe Msdn: http://msdn.microsoft.com/en- us / library / ty67wk28% 28VS.80% 29.aspx

„Wenn die Bedingung wahr ist, wird zunächst Ausdruck ausgewertet und das Ergebnis wird;.. Wenn er falsch ist, der zweite Ausdruck ausgewertet wird und wird das Ergebnis nur eine der beiden Ausdrücke wird immer ausgewertet“

x = cond1 ? result1
  : cond2 ? result2
  : cond3 ? result3
  : defaultResult;

vs

if (cond1) x = result1;
else if (cond2) x = result2;
else if (cond3) x = result3;
else x = defaultResult;

ich wie die erste.

Ja, können Sie auf bedingte Operatorassoziativität verlassen. Sein im Handbuch, auf dem Link mit freundlicher Unterstützung von dcp vorgesehen, angegeben als „Der Bedingungsoperator ist rechtsassoziativ“, mit einem Beispiel. Und, wie Sie vorgeschlagen und ich und andere vereinbart, die Tatsache, dass man auf mich ermöglicht klareren Code verlassen kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top