19

ああ、あなたはちょうど良い三次虐待が好きではありませんか?:) 次の式を検討してください。

true ? true : true ? false : false

今、完全に当惑している人のために、これはtrueと評価されると言えます。つまり、これは次と同等です。

true ? true : (true ? false : false)

しかし、これは信頼できますか?状況によっては、これにならないことを確信できますか:

(true ? true : true) ? false : false

何人かは言うかもしれません -まあ、括弧を追加するか、丸括弧を使わないでください - 結局のところ、三項演算子が悪であることはよく知られている事実です!

確かにそうですが、実際に意味を成す状況がいくつかあります。好奇心旺盛な人のために - 私は一連のプロパティによって 2 つのオブジェクトを比較するコードを書いています。次のように冷静に書くと、かなりいいでしょう。

obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
obj1.Prop4.CompareTo(obj2.Prop4)

明確かつ簡潔。ただし、最初のケースのように機能する三項演算子の結合性に依存します。括弧はそれからスパゲッティを作るだけです.

それで - これはどこかに指定されていますか?私はそれを見つけることができませんでした。

4

5 に答える 5

24

はい、これに頼ることができます (C# だけでなく、(私が知っている) 他のすべての言語 ( PHP を除く) 条件付き演算子を使用) と、ユースケースは実際にはかなり一般的な方法ですが、一部の人々はそれを嫌っています。 .

ECMA-334 (C# 標準) の関連セクションは 14.13 §3 です。

条件演算子は右結合です。つまり、操作は右から左にグループ化されます。[例: の形式の式a ? b : c ? d : eは として評価されa ? b : (c ? d : e)ます。終了例】

于 2009-11-19T14:14:04.650 に答える
17

尋ねる必要がある場合は、しないでください。あなたのコードを読んでいる人は、そのコードを見る必要があるときはいつでも、あなたがしたのと同じプロセスを何度も何度も繰り返さなければなりません。そのようなコードのデバッグは楽しいものではありません。最終的には、とにかく括弧を使用するように変更されます。

Re:「全体を括弧付きで書いてみてください。」

result = (obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
         (obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
         (obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
                                     obj1.Prop4.CompareTo(obj2.Prop4))))

説明:

  • 「尋ねなければならないなら、聞かないでください。」
  • 「あなたのコードを読んでいる人は...」

プロジェクトで一般的な規則に従うことは、一貫性を維持する方法であり、読みやすさを向上させます。言語を知らない人を含め、誰にとっても読みやすいコードを書けると考えるのはばかげたことです。

ただし、プロジェクト内で一貫性を維持することは有用な目標であり、プロジェクトで受け入れられている規則に従わないと、実際の問題の解決を妨げる議論につながります。あなたのコードを読む人は、プロジェクトで使用されている一般的で受け入れられている慣習を認識していることが期待されており、他の誰かがそのプロジェクトに直接取り組んでいる可能性さえあります。彼らがそれらを知らない場合、彼らはそれらを学ぶことが期待されており、どこに助けを求めるべきかを知っているべきです.

とはいえ、括弧なしで三項式を使用することがプロジェクトで一般的で受け入れられている慣習である場合は、必ずそれを使用してください。 あなたが尋ねなければならなかったことは、それが一般的ではないか、あなたのプロジェクトで受け入れられていないことを示しています. プロジェクトの慣例を変更したい場合は、明らかに明白な方法を実行し、他のプロジェクト メンバーと議論するものとしてマークし、先に進みます。ここでは、括弧を使用するか、if-else を使用することを意味します。

コードの一部が賢いと思われる場合は、熟考する最後のポイント:

デバッグは、最初にコードを書くよりも 2 倍大変です。したがって、コードをできるだけ賢く書いたとしても、定義上、それをデバッグするほど賢くはありません。— ブライアン・W・カーニハン

于 2009-11-19T14:15:35.113 に答える
4

括弧がコードの可読性を損なうという主張は、誤った仮定です。括弧で囲まれた表現の方がはるかに明確だと思います。個人的には、読みやすさを向上させるために、括弧を使用したり、数行にわたって再フォーマットしたりします。数行にわたって再フォーマットし、インデントを使用すると、括弧が不要になることもあります。そして、はい、あなたは関連付けの順序が右から左に決定論的であるという事実に頼ることができます。これにより、式を期待どおりに左から右に評価できます。

obj1.Prop1 != obj2.Prop1
     ? obj1.Prop1.CompareTo(obj2.Prop1)
     : obj1.Prop2 != obj2.Prop2
           ? obj1.Prop2.CompareTo(obj2.Prop2)
           : obj1.Prop3 != obj2.Prop3
                  ? obj1.Prop3.CompareTo(obj2.Prop3)
                  : obj1.Prop4.CompareTo(obj2.Prop4);
于 2009-11-19T14:23:21.137 に答える
1
x = cond1 ? result1
  : cond2 ? result2
  : cond3 ? result3
  : defaultResult;

vs

if (cond1) x = result1;
else if (cond2) x = result2;
else if (cond3) x = result3;
else x = defaultResult;

私は最初のものが好きです。

はい、条件付き演算子の結合性に依存できます。マニュアルでは、dcpから提供されたリンクで、例とともに「条件演算子は右結合です」と記載されています。そして、あなたが提案し、私と他の人が同意したように、あなたがそれに頼ることができるという事実は、より明確なコードを可能にします。

于 2010-12-17T02:11:01.333 に答える
1

msdn を参照してください: http://msdn.microsoft.com/en-us/library/ty67wk28%28VS.80%29.aspx

「条件が true の場合、最初の式が評価され、結果になります。false の場合、2 番目の式が評価され、結果になります。2 つの式のうち 1 つだけが評価されます。」

于 2009-11-19T14:16:35.860 に答える