何时使用'if ... else if'以及何时使用

use*_*291 8 c# coding-style

1)我知道if…else if语句是如何工作的,但在下一个例子中,就结果值而言,两种方法都是相同的.那么我使用的两种方法中的哪一种或者我应该总是选择一种在语义上最接近代码尝试的方法(这里我猜这两种方法在语义上是完全不同的)?那么你会使用哪种方法?为什么?

protected string GetNumberDescription(int value)
{
    if (value >= veryBigNumber)
        return veryBigNumberDescription;
    else if (value >= bigNumber)
        return bigNumberDescription;
    else if (value >= smallNumber)
        return smallNumberDescription;
    else
        return "";
}

protected string GetNumberDescription(int value)
{
    if (value >= veryBigNumber)
        return veryBigNumberDescription;
    if (value >= bigNumber)
        return bigNumberDescription;
    if (value >= smallNumber)
        return smallNumberDescription;
    else
        return "";
}
Run Code Online (Sandbox Code Playgroud)

2)我注意到在编写if ... else if语句时丢失的代码使用以下格式:

if ...
else if ...
else ...
Run Code Online (Sandbox Code Playgroud)

但不是(至少在概念上)更正确的方式:

if ...
else
  if ...
  else ...
Run Code Online (Sandbox Code Playgroud)

fro*_*die 16

  1. 你应该使用第一个.它更受欢迎,也更符合逻辑.(如果这个条件成立,你不关心任何事情......在你的代码中注明.)
  2. 使用第一种方式(否则如果)通常更容易接受,更紧凑和可读.Python甚至还有一个特定的关键字(elif).


Gag*_*age 13

我个人会用

protected string GetNumberDescription(int value)
   {
       if (value >= veryBigNumber)
           return veryBigNumberDescription;
       if (value >= bigNumber)
           return bigNumberDescription;
       if (value >= smallNumber)
           return smallNumberDescription;
       return string.Empty;
   }
Run Code Online (Sandbox Code Playgroud)

这完全取决于你的功能在做什么.如果它像这样简单,那么保持简单.如果您在返回之前可能需要对结果执行某些操作,那么我将使用Egrunin的解决方案


egr*_*nin 12

protected string GetNumberDescription(int value) 
{ 
    string ret = "";

    if (value >= veryBigNumber) 
        ret = veryBigNumberDescription; 
    else if (value >= bigNumber) 
        ret = bigNumberDescription; 
    else if (value >= smallNumber) 
        ret =  smallNumberDescription; 

    return ret; 
} 
Run Code Online (Sandbox Code Playgroud)

问题已经回答,但我补充说:

  1. 从函数中退出是有好处的.
  2. 重复测试相同的变量,因此if/elseif是最合适的.

编辑添加:

在这样的情况下,我通常很早就退出了一个函数:

if (conditionOne)
{
    if (conditionTwo)
    {
        if (conditionThree)
        {
            interesting_stuff();
        }
    }
    else
        boring();
}
return;
Run Code Online (Sandbox Code Playgroud)

看到这个我很高兴:

if (!conditionOne)
    return;

if (!conditionTwo)
{
    boring();
    return;
}

if (!conditionThree)
    return;

interesting_stuff();
return;
Run Code Online (Sandbox Code Playgroud)

但是当存在许多不同嵌套级别的出口时,当您阅读代码时,很容易错过一个.

此外,正如评论中所提到的:单个出口意味着只有一个地方可以设置断点.

  • 因为返回充当控制流语句,使得读取代码更加复杂.如果您在整个函数体中都有返回语句,那么在尝试理解函数的工作原理时,您可以考虑更多使用场景.如果您尝试修改函数并向其添加更多代码,那么如果您始终希望它们执行,则仅限于将语句放在方法的开头,因为如果将它们放在最后,那么在某些情况下,语句将赢得走得那么远.但也许你需要分析结果,所以你不能把它放在开头. (2认同)

Aar*_*nLS 11

如果条件是相互排斥的,那么我认为如果模式是最好的另外​​一个.随着代码的发展和变得更加复杂,意外破坏将更加困难,因为您的控制流更准确地表示逻辑的相互排他性.

考虑是否有人重新考虑你的第一个例子与egrunin的例子类似,只有一个返回,但考虑他们忘记在每个例子中添加"else":

protected string GetNumberDescription(int value) 
{ 
    string ret = "";

    if (value >= veryBigNumber) 
        ret = veryBigNumberDescription; 
    if (value >= bigNumber) 
        ret = bigNumberDescription; 
    if (value >= smallNumber) 
        ret =  smallNumberDescription; 
    // BUG: very big numbers still fall through to this last condition, 
    //         because they meet all conditions

    return ret; 
} 
Run Code Online (Sandbox Code Playgroud)

他们刚刚介绍了一个bug.他们可能没有意识到回报是所表达的逻辑的一部分.虽然这里的错误是显而易见的,但在现实生活中,这段代码在未来几年内可能会变得更加复杂,冗长,并且更难以阅读,因此更容易犯这样的错误.

检测到意外的错误

另外,如果必须满足至少一个条件(即永远不应该返回一个空字符串),那么如果你假设所有的情况都应该被处理,那么我会在最后的其他情况下抛出异常.这将检测代码中的错误,其中代码通过所有省略并且没有找到匹配条件.如果您不抛出异常,那么该错误可能会导致奇怪的行为.其余代码如何处理未初始化的空字符串?主要取决于手头的代码.抛出异常的想法是在错误发生的地方引起严重的故障,以便可以轻松识别和纠正错误,而不是让应用程序继续以无效的返回运行.

if (value >= smallNumber) 
    ret =  smallNumberDescription; 
else if(...)
    ret =  otherNumberDescription; 
else
    throw new InvalidOperationException($"No condition matched for value={value}");

return ret; 
Run Code Online (Sandbox Code Playgroud)

如果与适当的异常日志记录/通知配对,那么这将允许您了解此错误并添加条件来处理意外的值.对于非常简单的条件来说并不是必需的,但是在主动查找和纠正此类代码中的错误方面非常有用.


Dav*_*sky 7

它们在语义上是相同的.我怀疑性能有什么不同,所以选择的是风格和可读性.如果你好奇,编译上面的代码到一个程序,并使用反射镜,看看是否有在IL任何区别.我的猜测是否有任何差别.


GSt*_*Sto 6

这主要是一个偏好问题.当使用return语句时,我认为你不需要elses,因为很明显函数在那里结束.这一切都与情况和风格有关,因此没有明确的"最佳"方式.


Ste*_*uts 5

我会建议前者,因为你在四种可能性之间做出了合理的选择.您正在将决策分组到一个if/else if块中.

如果你将第二个函数中的决定分开,它们似乎根本没有连接.显然,它们是重复的价值变量,但它可能不一定是显而易见的.

此外,如果您没有任何回报,请返回null,而不是空字符串.在我维护的应用程序中,仍然需要使用if(value == null || value!="").


Dan*_*son 5

您想使用"else if",因为只有在第一个"if"不被接受时才会触发.在你的情况下,3 if语句是可以的,只是因为如果后者"if"是正确的,那么之前的"if"s不能.

如果你的所有if语句都是正确的,你可以使用else if.

例如:

if (8<10) {
return 10;
}
if (8<9) {
return 9;
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的例子,但你明白了.当你只想要一个"if"语句时,你可以使用"else if".