Using the ternary operator for multiple operations

57,687

Solution 1

Why can't I perform three operations between ? and :

Because these are operands, which are expressions. Each expression evaluates a value; you want multiple statements. From Eric Lippert's blog post about foreach vs ForEach:

The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects.

The purpose of an expression is to compute a value, not to cause a side effect. The purpose of a statement is to cause a side effect. The call site of this thing would look an awful lot like an expression (though, admittedly, since the method is void-returning, the expression could only be used in a “statement expression” context.)

You should absolutely write this using an if block. It's clearer.

If you really, really want to use the conditional operator for this, you could write:

// Please, please don't use this.
Func<string> x = () => {
    Properties.Settings.Default.filename = fp;
    Properties.Settings.Default.Save();
    return fp;
};

string filename = fp == null ? Properties.Settings.Default.file : x();

Solution 2

The conditional operator, which is a ternary operator (not a unary operator), is not a replacement for an if statement. It is an operator that returns one of two results. While you can chain this to some extent:

var result = someBool ? "a" : (otherBool ? "b" : "c");

That gets a little hard to read. Further, you're trying to call the Save() function, which does not return a result, hence you cannot use it with this operator.

Solution 3

If this was c you'd be OK thanks to the "comma operator":

int b;
int a = (1==1) ? (b=6, somemethod(), 1) : (b=7, 2);

Here b will be set to 6, somemethod will be called and then a is set to 1.

Thankfully that was one feature that was not ported over, use if..else it's much clearer.

Solution 4

If you really, really want to, you could use a function which has side effects:

filename = (fp!=null) ? DoOneThing(...) : DoAnotherThing(...);

Though whoever maintains your code won't thank you.

Solution 5

Short answer, use an if block, its the only sane thing to do.

Other answer, for the dirty, smelly insane individual.

filename = (fp!=null) ? Func<string> {fp = Properties.Settings.Default.filename; Properties.Settings.Default.Save; return fp;} : Properties.Settings.Default.file; 
Share:
57,687
user1240679
Author by

user1240679

Updated on July 09, 2022

Comments

  • user1240679
    user1240679 almost 2 years

    How can I use the ternary ? : condition to perform multiple operations, if expression is true/false?

    wbsource = (exp) ? (Do one thing) : (Do second thing) wbsource = (exp) ? (Do one thing) (Do second thing) : (Do second thing)

    For eg:

    Why can't I perform three operations between ? and :

    filename = (fp!=null) ? fp; Properties.Settings.Default.filename=fp; Properties.Settings.Default.Save; : Properties.Settings.Default.file;
    

    With simple if condition, I would have written in a simple way like:

    if(fp!null)
    {
    filename = fp;
    Properties.Settings.Default.filename;
    Properties.Settings.Default.Save();
    }
    else
    {
    filename = Properties.Settings.Default.file
    }
    

    What's a sweet short way to write using the above ternary operator?

  • Jodrell
    Jodrell about 12 years
    Why not declare the function anonymously inline (joke)