简体   繁体   中英

C# Conditional Operator Not a Statement?

I have a simple little code fragment that is frustrating me:

HashSet<long> groupUIDs = new HashSet<long>();
groupUIDs.Add(uid)? unique++ : dupes++;

At compile time, it generates the error:

Only assignment, call, increment, decrement, and new object expressions can be used as a statement

HashSet.Add is documented to return a bool, so the ternary (?) operator should work, and this looks like a completely legitimate way to track the number of unique and duplicate items I add to a hash-set.

When I reformat it as a if-then-else, it works fine.

Can anyone explain the error, and if there is a way to do this as a simple ternary operator?

According to the error message the ternary operator cannot be used as a statement. You would need to do something like this to turn it into an assignment:

int dummy = groupUIDs.Add(uid)? unique++ : dupes++;

That being said, I'd recommend to just use if-then-else. It's less confusing because it doesn't involve the creation of "magic" dummy variables...

As others have pointed out, the conditional operator is not a legal statement expression. (The legal statement expressions are assignments, calls, increments, decrements and constructions.)

However, there's a stylistic problem here as well. In my opinion, expressions should be useful for their values , and statements should be useful for their side effects . What you are running into is that you have an expression that is only useful for its side effect, and that is a bad code smell.

You have a side effect, so use a conditional statement rather than a conditional expression.

You're not setting the value result of the ternary to anything that's why.

HashSet<long> groupUIDs = new HashSet<long>();
int count = groupUIDs.Add(uid)? unique++ : dupes++;

The ternary operator is not a statement. So, it cannot be used alone in an instruction - it's the equivalent of writing

"something that is not a statement";

To clarify, you should take out the ternary operator and use an if.

The compiler isn't complaining about Add it is complaining about the fact that your conditional expression is not a complete statement.

Some languages (like JavaScript) allow you to use a conditional expression to branch logic like you have done here but C# requires that you assign the result of the conditional expression to a variable. Once you assign the result of the expression, you have made a complete statement and the compiler is happy.

You need to use the value from the ternary operator for something...

HashSet<long> groupUIDs = new HashSet<long>();
int newCount = groupUIDs.Add(uid)? unique++ : dupes++;

or - use an if

HashSet<long> groupUIDs = new HashSet<long>();
if (groupUIDs.Add(uid))
   unique++;
else
   dupes++;

gmcalab and sr pt are right; the ternary operator is meant to give you a result, just like 1 + 1 gives you 2 . You could not just write:

1 + 1 ;

The confusion here (I think) is that you're thinking of the ternary operator like it's a function.

The description of the ternary operator in the language reference says that

If condition is true, first expression is evaluated and becomes the result; if false, the second expression is evaluated and becomes the result.

It looks like the ternary can only be used in the context of assignment, although the language reference doesn't state it explicity. You're not doing an assignment on the result.

In my opinion, the re-writing as an if/else would be clearer.

If this is not acceptable, why would your line be? Just use an if statement :-)

        bool b = false;
        b?callB():callA();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM