92

2 つ以上の条件に基づいてコードを実行する場合、その if ステートメントをフォーマットする最良の方法はどれですか?

最初の例:-

if(ConditionOne && ConditionTwo && ConditionThree)
{
   Code to execute
}

2 番目の例:-

if(ConditionOne)
{
   if(ConditionTwo )
   {
     if(ConditionThree)
     {
       Code to execute
     }
   }
}

これは、各条件が長い関数名か何かである可能性があることを念頭に置いて理解して読むのが最も簡単です。

4

10 に答える 10

140

オプションAの方が好き

bool a, b, c;

if( a && b && c )
{
   //This is neat & readable
}

特に長い変数/メソッド条件がある場合は、それらを改行するだけです

if( VeryLongConditionMethod(a) &&
    VeryLongConditionMethod(b) &&
    VeryLongConditionMethod(c))
{
   //This is still readable
}

さらに複雑な場合は、条件メソッドを if ステートメントの外で個別に実行することを検討します

bool aa = FirstVeryLongConditionMethod(a) && SecondVeryLongConditionMethod(a);
bool bb = FirstVeryLongConditionMethod(b) && SecondVeryLongConditionMethod(b);
bool cc = FirstVeryLongConditionMethod(c) && SecondVeryLongConditionMethod(c);

if( aa && bb && cc)
{
   //This is again neat & readable
   //although you probably need to sanity check your method names ;)
}

IMHOオプション「B」の唯一の理由はelse、条件ごとに個別の機能を実行する場合です。

例えば

if( a )
{
    if( b )
    {
    }
    else
    {
        //Do Something Else B
    }
}
else
{
   //Do Something Else A
}
于 2008-10-31T10:20:49.320 に答える
29

他の回答は、最初のオプションが通常最適である理由を説明しています。ただし、複数の条件がある場合は、オプション 1 で条件チェックを行う別の関数 (またはプロパティ) を作成することを検討してください。これにより、少なくとも適切なメソッド名を使用する場合は、コードがはるかに読みやすくなります。

if(MyChecksAreOk()) { Code to execute }

...

private bool MyChecksAreOk()
{ 
    return ConditionOne && ConditionTwo && ConditionThree;
}

条件がローカル スコープ変数のみに依存している場合は、新しい関数を静的にして、必要なものすべてを渡すことができます。ミックスがある場合は、ローカルのものを渡します。

于 2008-10-31T10:20:12.863 に答える
13
if (   ( single conditional expression A )
    && ( single conditional expression B )
    && ( single conditional expression C )
   )
{
   opAllABC();
}
else
{
   opNoneABC();
}

if-else ステートメントで複数の条件式を次のようにフォーマットします。

  1. 読みやすさが向上
    します。最初に示した式のすべての二項論理演算 {&&, ||}
    b. 各 2 項演算の両方の条件付きオペランドは、垂直方向に整列しているため明らかです
    。ネストされた論理式の操作は、句内のステートメントのネストと同様に、インデントを使用して明確になります
  2. 明示的な括弧が必要 (演算子の優先順位規則に依存しない)
    a. これにより、一般的な静的解析エラーが回避されます
  3. デバッグを容易に
    する
    // bだけで個々の単一の条件付きテストを無効にします。
    個々のテストcegの直前または直後にブレーク ポイントを設定します。
// disable any single conditional test with just a pre-pended '//'
// set a break point before any individual test
// syntax '(1 &&' and '(0 ||' usually never creates any real code
if (   1
    && ( single conditional expression A )
    && ( single conditional expression B )
    && (   0
        || ( single conditional expression C )
        || ( single conditional expression D )
       )
   )
{
   ... ;
}

else
{
   ... ;
}
于 2017-04-19T22:01:21.807 に答える
11

最初の例は、より「読みやすい」です。

実際、私の意見では、「他のロジック」を追加する必要がある場合は常に2番目のフレーバーを使用する必要がありますが、単純な条件付きの場合は、最初のフレーバーを使用します。条件の長さが心配な場合は、いつでも次の構文を使用できます。

if(ConditionOneThatIsTooLongAndProbablyWillUseAlmostOneLine
                 && ConditionTwoThatIsLongAsWell
                 && ConditionThreeThatAlsoIsLong) { 
     //Code to execute 
}

幸運を!

于 2008-10-31T10:23:16.697 に答える
10

質問がされ、これまでのところ、決定は純粋に「構文」の理由で行われるべきであるかのように回答されています。

if 内に多数の条件をどのようにレイアウトするかの正解は、「セマンティクス」にも依存するはずです。そのため、条件は「概念的に」一緒になるものに従って分割し、グループ化する必要があります。

2 つのテストが実際には同じコインの裏表である場合。if (x>0) && (x<=100) その後、それらを同じ行にまとめます。別の条件が概念的にはるかに遠い場合。user.hasPermission(Admin()) 次に、それを独自の行に配置します

例えば。

if user.hasPermission(Admin()) {
   if (x >= 0) && (x < 100) {
      // do something
   }
}
于 2008-10-31T11:07:34.500 に答える
4

2 番目の例は、Arrow Anti-patternの典型的な例なので、避けたいと思います...

条件が長すぎる場合は、それらをメソッド/プロパティに抽出します。

于 2008-10-31T10:46:17.803 に答える
3

左から右に読むと、「If something AND somethingelse AND somethingelse THEN」となるからです。これは理解しやすい文です。2 番目の例は、「If something THEN if somethingelse THEN if something else THEN」と読みますが、これは不器用です。

また、句でいくつかの OR を使用するかどうかを検討してください。2 番目のスタイルでそれを行うにはどうすればよいでしょうか。

于 2008-10-31T10:16:41.590 に答える
0

Perl では、次のようにできます。

{
  ( VeryLongCondition_1 ) or last;
  ( VeryLongCondition_2 ) or last;
  ( VeryLongCondition_3 ) or last;
  ( VeryLongCondition_4 ) or last;
  ( VeryLongCondition_5 ) or last;
  ( VeryLongCondition_6 ) or last;

  # Guarded code goes here
}

条件のいずれかが失敗した場合、ブロックの後、そのまま続行されます。ブロックの後に保持したい変数を定義している場合は、ブロックの前にそれらを定義する必要があります。

于 2008-10-31T23:14:58.520 に答える
-3

私は長い間このジレンマに直面してきましたが、まだ適切な解決策を見つけることができません。私の意見では、最初に以前の条件を取り除こうとするのが唯一の良い方法です。

代替手段がない場合は、他の人が提案したように、それを別々のものに分割し、名前を短くするかグループ化します。たとえば、すべてが真でなければならない場合は、「xの配列に偽がない場合は実行する」などを使用します。

すべてが失敗した場合、@Eoin Campbell はかなり良いアイデアを提供してくれました。

于 2018-08-17T16:09:03.980 に答える
-4

条件が非常に複雑な場合は、次のスタイルを使用します (PHP の実際の例)。

if( $format_bool &&
    (
        ( isset( $column_info['native_type'] )
            && stripos( $column_info['native_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['driver:decl_type'] )
            && stripos( $column_info['driver:decl_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['pdo_type'] )
            && $column_info['pdo_type'] == PDO::PARAM_BOOL
        )
    )
)

複数レベルのif(). if() {...}また、このような場合には、複雑な条件をバラバラに分割することはできません。そうしないと、同じステートメントをブロック内で何度も繰り返さなければならなくなるからです。

また、コードに「空気」を追加することは常に良い考えだと思います。可読性が大幅に向上します。

于 2015-02-21T10:57:10.187 に答える