Cスタイル言語を使用せず&&
、質問と同等のコードを実行する必要があるとします。
あなたのコードは次のようになります:
if(smartphone != null)
{
if(smartphone.GetSignal() > 50)
{
// Do stuff
}
}
このパターンは、多くの結果になります。
ここで、仮想言語が導入するバージョン2.0を想像してください&&
。あなたはそれがいかにクールだと思いますか!
&&
上記の例が行うことを実行するための認識された慣用的な手段です。それを使用することは悪い習慣ではありません。実際、上記のような場合に使用しないことは悪い習慣else
です。
言語が賢いのは、最初のステートメントがfalseの場合、2番目のステートメントを評価しても意味がないため、null参照例外がスローされないことがわかっているためです。
いいえ、あなたはあなたが最初の文が偽だった場合、その後も、第二の文を評価しない点がないことを知っていたので、賢いです。言語は岩の箱のように愚かであり、あなたがそれをするように言ったことをしました。(John McCarthyはさらに賢く、短絡評価は言語にとって有用なものであることを認識していました)。
あなたが賢いということと、言語が賢いということの違いは重要です。なぜなら、良い練習と悪い練習は、しばしばあなたが必要なだけ賢くて、それ以上賢くないということになるからです。
考慮してください:
if(smartphone != null && smartphone.GetSignal() > ((range = (range != null ? range : GetRange()) != null && range.Valid ? range.MinSignal : 50)
これにより、コードが拡張され、range
。range
がnullの場合、GetRange()
失敗するrange
可能性があるので、まだnullである可能性がありますが、呼び出しによって設定しようとします。この後に範囲がnullでない場合Valid
、そのMinSignal
プロパティが使用50
されます。それ以外の場合は、デフォルトが使用されます。
これも依存します&&
が、おそらく1行に入れるのは賢すぎるでしょう(私が100%正しいと確信しているわけではありません。また、その事実が私の主張を実証しているので、再確認しません)。
&&
ただし、ここで問題になるわけではありませんが、1つの式に多くを使用する機能(良いこと)により、理解しにくい式を不必要に書く能力(悪いこと)が増加します。
また:
if(smartphone != null && (smartphone.GetSignal() == 2 || smartphone.GetSignal() == 5 || smartphone.GetSignal() == 8 || smartPhone.GetSignal() == 34))
{
// do something
}
ここでは&&
、特定の値のチェックとの使用を組み合わせています。これは電話信号の場合には現実的ではありませんが、他の場合には発生します。ここで、それは私が十分に賢くないことの例です。次のことをした場合:
if(smartphone != null)
{
switch (smartphone.GetSignal())
{
case 2: case 5: case 8: case 34:
// Do something
break;
}
}
私は読みやすさとパフォーマンスの両方を得ることができました(への複数の呼び出しGetSignal()
はおそらく最適化されていなかったでしょう)。
ここでも問題は&&
、その特定のハンマーを使用して、他のすべてを釘として見ることではありません。それを使用しないことで、使用するよりも良いことができます。
ベストプラクティスから離れる最後のケースは次のとおりです。
if(a && b)
{
//do something
}
に比べ:
if(a & b)
{
//do something
}
私たちが後者を好む理由に関する古典的な議論はb
、私たちa
が真実であるかどうかを望むことを評価する際に何らかの副作用があるということです。私はそのことに同意しません。その副作用が非常に重要な場合は、別のコード行でそれを実現してください。
ただし、効率の観点からは、この2つの方が優れている可能性があります。最初のコードは明らかに少ないコードを実行し(b
1つのコードパスでまったく評価しない)、評価にかかる時間を節約できますb
。
ただし、最初のブランチにももう1つブランチがあります。仮想Cスタイル言語でnoを使用して書き換えるかどうかを検討します&&
。
if(a)
{
if(b)
{
// Do something
}
}
この余分な部分if
は、の使用には隠されていますが&&
、まだ存在しています。そのため、分岐予測が発生し、そのため分岐予測ミスが発生する可能性がある場合です。
そのため、if(a & b)
場合によってはコードをより効率的にすることができます。
ここでif(a && b)
は、それが最初のベストプラクティスアプローチであると言います。より一般的なのは、場合によっては実行可能な唯一のもの(falseのb
場合a
はエラーになる)であり、より高速です。if(a & b)
ただし、特定の場合には、それが便利な最適化であることが多いことに注意してください。