У меня есть простой небольшой фрагмент кода, который расстраивает меня:
HashSet<long> groupUIDs = new HashSet<long>();
groupUIDs.Add(uid)? unique++ : dupes++;
Во время компиляции это генерирует ошибку:
Только присвоение, назовите, увеличьте, постепенно уменьшитесь, и новые объектные выражения могут использоваться в качестве оператора
HashSet.Add
документируется для возврата bool, таким образом, троичный (?) оператор должен работать, и это похоже на абсолютно законный способ отследить количество уникальных и дублирующихся объектов, которые я добавляю к установленному на хеш.
Когда я переформатировал его как if-then-else, это хорошо работает.
Кто-либо может объяснить ошибку, и если существует способ сделать это как простой тернарный оператор?
Согласно сообщению об ошибке тернарный оператор не может использоваться в качестве оператора. Вам нужно будет сделать что-то вроде этого, чтобы превратить это в присваивание:
int dummy = groupUIDs.Add(uid)? unique++ : dupes++;
При этом я бы рекомендовал просто использовать if-then-else. Это не так запутанно, потому что не требует создания "волшебных" фиктивных переменных ...
Тернарный оператор не является оператором. Таким образом, его нельзя использовать отдельно в инструкции - это эквивалент записи
"something that is not a statement";
. Чтобы уточнить, вы должны убрать тернарный оператор и использовать if.
Компилятор не жалуется на Add
, он жалуется на то, что ваше условное выражение не является полным утверждением.
Некоторые языки (например, JavaScript) позволяют использовать условное выражение для ветвления логики, как вы сделали здесь, но C# требует, чтобы вы присвоили результат условного выражения переменной. Как только вы присвоите результат выражения, вы сделаете полное утверждение, и компилятор будет доволен.
gmcalab и sr pt верны; тернарный оператор предназначен для получения результата, так же как 1 + 1
дает вам 2
. Вы не могли бы просто написать:
1 + 1
;
Путаница здесь (я думаю) заключается в том, что вы думаете о тернарном операторе как о функции.
Вам нужно использовать значение тернарного оператора для чего-то ...
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++;
Как указывали другие, условный оператор не является допустимым выражением оператора. (Допустимые выражения операторов - это присваивания, вызовы, приращения, декременты и конструкции.)
Однако здесь также есть стилистическая проблема. На мой взгляд, выражения должны быть полезны для своих значений , а операторы должны быть полезны из-за их побочных эффектов . Вы столкнулись с тем, что у вас есть выражение, которое полезно только из-за своего побочного эффекта, и это неприятный запах кода.
У вас есть побочный эффект, поэтому используйте условный оператор, а не условное выражение.
описание тернарного оператора в справочнике языка говорит, что
Если условие истинно, первое выражение вычисляется и становится результатом; если ложно , второе выражение вычисляется и становится результатом.
Похоже, что тернарный код может использоваться только в контексте присваивания, хотя в справочнике по языку это не указано явно. Вы не делаете задания по результату.
На мой взгляд, переписывание как if / else было бы более ясным.
Вы не устанавливаете результат значения троичной системы ни на что, вот почему.
HashSet<long> groupUIDs = new HashSet<long>();
int count = groupUIDs.Add(uid)? unique++ : dupes++;
Если это неприемлемо, почему ваша линия будет приемлемой? Просто используйте оператор if: -)
bool b = false;
b?callB():callA();