abelenky
abelenky

Reputation: 64682

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?

Upvotes: 22

Views: 3420

Answers (9)

Gabe
Gabe

Reputation: 50493

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++;

Upvotes: 7

Brian Walker
Brian Walker

Reputation: 8908

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++;

Upvotes: 2

Eric Lippert
Eric Lippert

Reputation: 659994

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.

Upvotes: 16

sth
sth

Reputation: 229573

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

Upvotes: 19

Andy Johnson
Andy Johnson

Reputation: 8149

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.

Upvotes: 1

Dan Tao
Dan Tao

Reputation: 128317

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.

Upvotes: 1

Dested
Dested

Reputation: 6433

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

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

Upvotes: 0

ANeves
ANeves

Reputation: 6365

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.

Upvotes: 5

Andrew Hare
Andrew Hare

Reputation: 351476

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.

Upvotes: 4

Related Questions