web-dev-qa-db-ja.com

複数の条件を持つifステートメントをフォーマットする最適な方法

Ifステートメントをフォーマットする最良の方法である2つ以上の条件に基づいてコードを実行したい場合

最初の例:-

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

2番目の例:-

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

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

81
Matt690

オプション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 ;)
}

私見オプション 'B'の唯一の理由は、各条件に対して個別のelse関数を実行する場合です。

例えば.

if( a )
{
    if( b )
    {
    }
    else
    {
        //Do Something Else B
    }
}
else
{
   //Do Something Else A
}
123
Eoin Campbell

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

if(MyChecksAreOk()) { Code to execute }

...

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

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

28
Torbjørn

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

実際、私の意見では、 "else logic"を追加する必要があるときは常に2番目のものを使用する必要がありますが、単純な条件付きの場合は最初のフレーバーを使用します。条件が長いことが心配な場合は、常に次の構文を使用できます。

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

幸運を!

10

質問はこれまでに行われ、決定は純粋に「構文的な」理由で行われるべきであるかのように答えられてきました。

If ought内の多くの条件をどのようにレイアウトするかについての正しい答えは、「セマンティクス」にも依存するということです。したがって、条件は、「概念的に」一緒に何が起こるかに応じて分割およびグループ化する必要があります。

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

例えば。

if user.hasPermission(Admin()) {
   if (x >= 0) && (x < 100) {
      // do something
   }
}
9
interstar
    if (   ( single conditional expression A )
        && ( single conditional expression B )
        && ( single conditional expression C )
       )
    {
       opAllABC();
    }
    else
    {
       opNoneABC();
    }

Formatting a multiple conditional expressions in an if-else statement this way:
1) allows for enhanced readability:
    a) all binary logical operations {&&, ||} in the expression shown
       first
    b) both conditional operands of each binary operation are obvious
       because they align vertically
    c) nested logical expressions operations are made obvious using
       indentation, just like nesting statements inside clause
2) requires explicit parenthesis (not rely on operator precedence rules)
    a) this avoids a common static analysis errors
3) allows for easier debugging
    a) disable individual single conditional tests with just a //
    b) set a break point just before or after any individual test
    c) e.g. ...

    // 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
    {
       ... ;
    }
7
Sean

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

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

4
Omar Kooheji

最初の方が簡単です。なぜなら、左から右に読むと、「何かAND何か他のものAND何か他のものTHEN」という文がわかりやすいからです。 2番目の例は、「もし何か他のものならTHEN何か他のものならTHEN」と読みますが、これは不器用です。

また、句でいくつかのORを使用するかどうかを検討します。2番目のスタイルでどのように使用しますか?

3
RB.

プログラミング言語がサポートしていれば、switch...caseステートメントがこの状況で整頓されたコードを書くための最良の方法だと思います。

switch (//variable or Boolean) {
  case //Condition A:
  case //Condition B:
  case //Condition C:
    //Code to execute;
}
2
Kent

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
}

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

0
Brad Gilbert