Условный оператор C# не оператор?

У меня есть простой небольшой фрагмент кода, который расстраивает меня:

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

Во время компиляции это генерирует ошибку:

Только присвоение, назовите, увеличьте, постепенно уменьшитесь, и новые объектные выражения могут использоваться в качестве оператора

HashSet.Add документируется для возврата bool, таким образом, троичный (?) оператор должен работать, и это похоже на абсолютно законный способ отследить количество уникальных и дублирующихся объектов, которые я добавляю к установленному на хеш.

Когда я переформатировал его как if-then-else, это хорошо работает.

Кто-либо может объяснить ошибку, и если существует способ сделать это как простой тернарный оператор?

22
задан Mechanical snail 24 September 2012 в 21:32
поделиться

9 ответов

Согласно сообщению об ошибке тернарный оператор не может использоваться в качестве оператора. Вам нужно будет сделать что-то вроде этого, чтобы превратить это в присваивание:

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

При этом я бы рекомендовал просто использовать if-then-else. Это не так запутанно, потому что не требует создания "волшебных" фиктивных переменных ...

19
ответ дан 29 November 2019 в 04:01
поделиться

Тернарный оператор не является оператором. Таким образом, его нельзя использовать отдельно в инструкции - это эквивалент записи

"something that is not a statement";

. Чтобы уточнить, вы должны убрать тернарный оператор и использовать if.

5
ответ дан 29 November 2019 в 04:01
поделиться

Компилятор не жалуется на Add, он жалуется на то, что ваше условное выражение не является полным утверждением.

Некоторые языки (например, JavaScript) позволяют использовать условное выражение для ветвления логики, как вы сделали здесь, но C# требует, чтобы вы присвоили результат условного выражения переменной. Как только вы присвоите результат выражения, вы сделаете полное утверждение, и компилятор будет доволен.

4
ответ дан 29 November 2019 в 04:01
поделиться

gmcalab и sr pt верны; тернарный оператор предназначен для получения результата, так же как 1 + 1 дает вам 2 . Вы не могли бы просто написать:

1 + 1 ;

Путаница здесь (я думаю) заключается в том, что вы думаете о тернарном операторе как о функции.

1
ответ дан 29 November 2019 в 04:01
поделиться

Вам нужно использовать значение тернарного оператора для чего-то ...

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++;
2
ответ дан 29 November 2019 в 04:01
поделиться

Как указывали другие, условный оператор не является допустимым выражением оператора. (Допустимые выражения операторов - это присваивания, вызовы, приращения, декременты и конструкции.)

Однако здесь также есть стилистическая проблема. На мой взгляд, выражения должны быть полезны для своих значений , а операторы должны быть полезны из-за их побочных эффектов . Вы столкнулись с тем, что у вас есть выражение, которое полезно только из-за своего побочного эффекта, и это неприятный запах кода.

У вас есть побочный эффект, поэтому используйте условный оператор, а не условное выражение.

16
ответ дан 29 November 2019 в 04:01
поделиться

описание тернарного оператора в справочнике языка говорит, что

Если условие истинно, первое выражение вычисляется и становится результатом; если ложно , второе выражение вычисляется и становится результатом.

Похоже, что тернарный код может использоваться только в контексте присваивания, хотя в справочнике по языку это не указано явно. Вы не делаете задания по результату.

На мой взгляд, переписывание как if / else было бы более ясным.

1
ответ дан 29 November 2019 в 04:01
поделиться

Вы не устанавливаете результат значения троичной системы ни на что, вот почему.

HashSet<long> groupUIDs = new HashSet<long>();
int count = groupUIDs.Add(uid)? unique++ : dupes++;
7
ответ дан 29 November 2019 в 04:01
поделиться

Если это неприемлемо, почему ваша линия будет приемлемой? Просто используйте оператор if: -)

        bool b = false;
        b?callB():callA();
0
ответ дан 29 November 2019 в 04:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: