22

我有一个简单的小代码片段让我感到沮丧:

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

在编译时,它会生成错误:

只有赋值、调用、递增、递减和新对象表达式可以用作语句

HashSet.Add被记录为返回一个布尔值,因此三元 (?) 运算符应该可以工作,这看起来是一种完全合法的方法来跟踪我添加到哈希集中的唯一和重复项目的数量。

当我将其重新格式化为 if-then-else 时,它​​工作正常。

谁能解释这个错误,如果有办法作为一个简单的三元运算符来做到这一点?

4

9 回答 9

19

根据错误消息,三元运算符不能用作语句。你需要做这样的事情来把它变成一个作业:

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

话虽如此,我建议只使用 if-then-else。它不那么令人困惑,因为它不涉及创建“魔术”虚拟变量......

于 2010-04-06T16:15:08.103 回答
16

正如其他人指出的那样,条件运算符不是合法的语句表达式。(合法的语句表达式是赋值、调用、递增、递减和构造。)

但是,这里也存在风格问题。在我看来,表达式应该对它们的值有用,而语句应该对它们的副作用有用。您遇到的是,您有一个仅对其副作用有用的表达式,这是一种不好的代码气味。

你有一个副作用,所以使用条件语句而不是条件表达式。

于 2010-04-06T17:24:04.643 回答
7

您没有将三元的值结果设置为任何原因。

HashSet<long> groupUIDs = new HashSet<long>();
int count = groupUIDs.Add(uid)? unique++ : dupes++;
于 2010-04-06T16:14:10.640 回答
5

三元运算符不是语句。因此,它不能在指令中单独使用——它相当于写作

"something that is not a statement";

为了澄清,您应该取出三元运算符并使用 if。

于 2010-04-06T16:14:44.440 回答
4

编译器不是在抱怨Add它是在抱怨你的条件表达式不是一个完整的语句。

某些语言(如 JavaScript)允许您使用条件表达式来分支逻辑,就像您在此处所做的那样,但 C# 要求您将条件表达式的结果分配给变量。一旦你分配了表达式的结果,你就完成了一个完整的语句并且编译器很高兴。

于 2010-04-06T16:13:36.807 回答
2

您需要将三元运算符的值用于某事...

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

或 - 使用 if

HashSet<long> groupUIDs = new HashSet<long>();
if (groupUIDs.Add(uid))
   unique++;
else
   dupes++;
于 2010-04-06T16:19:46.330 回答
1

gmcalab 和 sr pt 是对的;三元运算符旨在为您提供结果,就像1 + 1给您一样2。你不能只写:

1 + 1;

这里的困惑(我认为)是您正在考虑三元运算符,就像它是一个函数一样。

于 2010-04-06T16:19:34.653 回答
1

语言参考中对三元运算符的描述

如果条件为真,则计算第一个表达式并成为结果;如果为 false,则计算第二个表达式并成为结果。

看起来三元只能在赋值上下文中使用,尽管语言参考没有明确说明。您没有对结果进行分配。

在我看来,重写为 if/else 会更清楚。

于 2010-04-06T16:20:15.347 回答
0

如果这是不可接受的,您的线路为什么会这样?只需使用 if 语句 :-)

        bool b = false;
        b?callB():callA();
于 2010-04-06T16:16:35.010 回答