Ternary operator associativity in C# - can I rely on it?

前端 未结 5 679
旧时难觅i
旧时难觅i 2020-12-31 02:37

Ahh, don\'t you just love a good ternary abuse? :) Consider the following expression:

true ? true : true ? false : false

For those of you w

相关标签:
5条回答
  • 2020-12-31 03:18

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

    "If condition is true, first expression is evaluated and becomes the result; if false, the second expression is evaluated and becomes the result. Only one of two expressions is ever evaluated."

    0 讨论(0)
  • 2020-12-31 03:19

    Yes, you can rely on this (not only in C# but in all (that I know) other languages (except PHP … go figure) with a conditional operator) and your use-case is actually a pretty common practice although some people abhor it.

    The relevant section in ECMA-334 (the C# standard) is 14.13 §3:

    The conditional operator is right-associative, meaning that operations are grouped from right to left. [Example: An expression of the form a ? b : c ? d : e is evaluated as a ? b : (c ? d : e). end example]

    0 讨论(0)
  • 2020-12-31 03:23
    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;
    

    I like the first one.

    Yes, you can rely on conditional operator associativity. Its in the manual, at the link kindly provided by dcp, stated as "The conditional operator is right-associative", with an example. And, as you suggested and I and others agreed, the fact that you can rely on it allows clearer code.

    0 讨论(0)
  • 2020-12-31 03:25

    If you have to ask, don't. Anyone reading your code will just have to go through the same process you did, over and over again, any time that code needs to be looked at. Debugging such code is not fun. Eventually it'll just be changed to use parentheses anyway.

    Re: "Try to write the whole thing WITH parentheses."

    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))))
    

    Clarification:

    • "If you have to ask, don't."
    • "Anyone reading your code..."

    Following the conventions common in a project is how you maintain consistency, which improves readability. It would be a fool's errand to think you can write code readable to everyone—including those who don't even know the language!

    Maintaining consistency within a project, however, is a useful goal, and not following a project's accepted conventions leads to debate that detracts from solving the real problem. Those reading your code are expected to be aware of the common and accepted conventions used in the project, and are even likely to be someone else working directly on it. If they don't know them, then they are expected to be learning them and should know where to turn for help.

    That said—if using ternary expressions without parentheses is a common and accepted convention in your project, then use it, by all means! That you had to ask indicates that it isn't common or accepted in your project. If you want to change the conventions in your project, then do the obviously unambiguous, mark it down as something to discuss with other project members, and move on. Here that means using parentheses or using if-else.

    A final point to ponder, if some of your code seems clever to you:

    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. — Brian W. Kernighan

    0 讨论(0)
  • 2020-12-31 03:29

    The assertion that parentheses detract from the readability of the code is a false assumption. I find the parenthetical expression much more clear. Personally, I would use the parentheses and/or reformat over several lines to improve readability. Reformatting over several lines and using indenting can even obviate the need for parentheses. And, yes, you can rely on the fact that the order of association is deterministic, right to left. This allows the expression to evaluate left to right in the expected fashion.

    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);
    
    0 讨论(0)
提交回复
热议问题