22

イライラする単純な小さなコードフラグメントがあります。

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

コンパイル時に、次のエラーが生成されます。

代入、呼び出し、インクリメント、デクリメント、および新しいオブジェクト式のみをステートメントとして使用できます

HashSet.Addbool を返すように文書化されているため、三項 (?) 演算子が機能するはずです。これは、ハッシュ セットに追加する一意のアイテムと重複するアイテムの数を追跡するための完全に正当な方法のように見えます。

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 の場合、2 番目の式が評価され、結果になります。

言語リファレンスには明示的に記載されていませんが、三項は代入のコンテキストでのみ使用できるようです。結果に対して割り当てを行っていません。

私の意見では、if/else として書き直すとより明確になります。

于 2010-04-06T16:20:15.347 に答える
0

これが受け入れられない場合、なぜあなたの行はありますか? if ステートメントを使用するだけです:-)

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