I realized that there is a very clean way to express a multi-clause if statement by composing ternary conditional operators like this:

var result =
    condition1 ? result1
    : condition2 ? result2
    : condition3 ? result4
          …
    : conditionN ? resultN
    : default;

Traditionally, this would be written in a much more verbose way:

MyType result;
if (condition1) result = result1;
else if (condition2) result = result2;
else if (condition3) result = result3;
   …
else if (conditionN) result = resultN;
else result = default;

Here is a simple real-world application of this trick:

string commentCount =
    n == 0 ? "no comments"
    : n == 1 ? "1 comment"
    : n < 100 ? n + " comments"
    : "100+ comments";

I really like this pattern because the code is very concise and clean. I am surprised that I have never seen it used anywhere.

From the readers

Hugh Brown suggests an alternative way to rewrite the above code sample, which also nests conditional expressions:

string commentCount =
    string.Format("{0} comment%s",
        (n == 0 ? "no"
        : n < 100 ? n.ToString()
        : "100+"),
        (n == 1 ? "" : "s"));

Gotchas

Suprisingly, I don’t believe there are any major ones. The conditional operator has a very low operator precedence in C#, Java and C++. In C# and Java, only the assignment operators (=, +=, <<=, etc) have a lower precedence than the conditional. In C++, you also have to be cautious around the comma operator, but you should be using that construct rarely anyways.

If you really want to mix the switch expression with assignment operators, other conditionals, or even the C++ comma operator, use brackets to ensure that the conditional operators which are part of the switch expression will be applied last.

In all other cases, the pattern should behave as you’d expect.

Comments and Conclusion

It is great to find a neat trick in the good old C-based languages. Not only functional languages are cool. ;-)

Any thoughts? Has anyone seen this pattern before? Let me know in the comments.

From the readers

Bodaniel Jeanes mentions a loosely-related trick with a switch statement. Note that this works in C, but not in C# or Java:

switch (true)
{
    case n == 0:
        // do something
        break;
    case n > 2:
        // do something else
        break;
    default:
        return;
}

kick it on DotNetKicks.com

Share/Save/Bookmark