92

如果您想根据两个或多个条件执行某些代码,这是格式化该 if 语句的最佳方法?

第一个例子:-

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

第二个例子:-

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 ;)
}

恕我直言,选择“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.每个二元运算的两个条件操作数都很明显,因为它们垂直对齐
    c。使用缩进使嵌套的逻辑表达式操作变得明显,就像在子句中嵌套语句一样
  2. 需要显式括号(不依赖于运算符优先规则
    )这避免了常见的静态分析错误
  3. 允许更轻松
    的调试
    仅使用 a // 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

第一个示例更“易于阅读”。

实际上,在我看来,当你必须添加一些“其他逻辑”时,你应该只使用第二个,但是对于一个简单的条件,使用第一个风格。如果您担心条件太长,您总是可以使用以下语法:

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

祝你好运!

于 2008-10-31T10:23:16.697 回答
10

这个问题被问到并且到目前为止已经得到了回答,好像该决定应该纯粹基于“句法”理由做出。

我想说,如何在 if 中布置多个条件的正确答案也应该取决于“语义”。因此,应根据“概念上”的组合情况对条件进行分解和分组。

如果两个测试真的是同一枚硬币的两个方面,例如。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

第二个是箭头反模式的经典示例所以我会避免它......

如果您的条件太长,请将它们提取到方法/属性中。

于 2008-10-31T10:46:17.803 回答
3

第一个更容易,因为如果您从左到右阅读,您会得到:“If something AND somethingelse AND somethingelse THEN”,这是一个易于理解的句子。第二个例子是“If something THEN if somethingelse THEN if something else THEN”,这很笨拙。

另外,考虑一下如果你想在你的子句中使用一些 OR - 你会如何在第二种风格中做到这一点?

于 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

我已经面临这个困境很长时间了,我仍然找不到合适的解决方案。在我看来,唯一的好方法是首先尝试摆脱之前的条件,这样你就不会突然比较其中的 5 个。

如果没有其他选择,那么就像其他人建议的那样 - 将其分解为单独的名称并缩短名称或将它们分组,例如,如果所有内容都必须为真,则使用类似“如果 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 回答