下面哪个代码块更符合逻辑?

本文关键字:代码 | 更新日期: 2023-09-27 18:10:04

想象一个方法执行其任务的条件应该为真。哪个块代表最好的方法(性能相关和可读性),如果不是,你的建议是什么?

private void method()
{
    if(!condition)
    {
     MessageBox.Show("ERROR!");
     return;
    }     
    else
    {
        //DO STUFF
    }
}

private void method()
{
    if(condition)
    {
         //DO STUFF
    }     
    else
    {
         MessageBox.Show("ERROR!");
         return;
    }
}

下面哪个代码块更符合逻辑?

都不是。使用保护子句:

private void method()
{
    if(!condition)
    {
        MessageBox.Show("ERROR!");
        return;
    }     
    //inputs have been checked, proceed with normal execution
}

这样做,您可以预先处理所有异常行为,并避免正常执行路径的过度缩进。

都不是,因为您不会同时使用elsereturn

所以,你可以这样做:

private void method() {
  if (!condition) {
    MessageBox.Show("ERROR!");
  } else {
    //DO STUFF
  }
}

或:

private void method() {
  if (condition) {
    //DO STUFF
  } else {
    MessageBox.Show("ERROR!");
  }
}

或:

private void method() {
  if (!condition) {
    MessageBox.Show("ERROR!");
    return
  }
  //DO STUFF
}

或:

private void method() {
  if (condition) {
    //DO STUFF
    return;
  }
  MessageBox.Show("ERROR!");
}
使用哪个

主要取决于代码实际做什么。代码很少像示例中那样简单,所以重要的是代码还能做什么。

前两种方法的优点是具有单个退出点,这通常使遵循代码变得更容易。你通常会把较短的代码放在前面,因为在那里比在较大的代码块后面的else更容易发现。

第三个通常用于在继续执行主代码之前验证输入,您可以轻松地使用多个验证:

private void method() {
  if (!condition) {
    MessageBox.Show("ERROR!");
    return
  }
  if (!anotherCondition) {
    MessageBox.Show("ANOTHER ERROR!");
    return
  }
  //DO STUFF
}

第四个是有用的,如果你有几个条件,你不想把相同的if语句:

private void method() {
  if (condition) {
    var data = GetSomeData();
    if (data.IsValid) {
      var moreData = GetSomeMoreData();
      if (moreData.IsValid) {
        //DO STUFF
        return;
      }
    }
  }
  MessageBox.Show("ERROR!");
}

秒!第二个!

但我确实承认,如果"//do STUFF"真的很长而且嵌套,我有时会使用第一种方法。

我更喜欢"If条件"的方法,而不是条件的否定,但这只是个人偏好。

看情况。

在大多数情况下,第二个版本。

如果(!condition)块中的代码量只有几行代码,而(condition)块中的代码是大量代码,那么我会反转答案。如果不用滚动屏幕就能看到"else",那么阅读if语句就容易多了。

我更喜欢David提到的保护子句,但在一般情况下,应该将最常见的情况放在前面。它使遵循方法流程变得更容易。

可读性/标准方面。我接受第二种说法。我不认为在性能方面有什么不同,但我不是一个低级别的家伙。

通常这是一个要求以下答案的问题:"视情况而定",我将通过两个例子来展示。
if not condition 对于asp.net Web Forms验证,我经常看到这样的代码

protected void btSubmit_OnClick(object sender, EventArgs e)
{
  Page.Valide();
  if (!Page.IsValid)
     return;
  var customer = new Customer();
  // init 20 properties of customer
 ....
  var bo = new CustomerBO();
  bo.Save(customer);
}

还有一个更受欢迎:

 protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
                    {
                    }
        }
<<p> 如果条件/strong>
public void UpdateCustomer(int customerId, string ...../*it might be a customer type also*/)
{
   using (var ctx= CreateContext())
 {
    var customer = ctx.Customers.FirstOrDefault(c=>c.CustomerId = customerId);
    if ( customer != null)
    {
           /*code update 20 properties */
    }
 }
}

我希望代码清楚:p

这更像是一个风格问题,而不是一个"逻辑"问题。这两种方法都有效,您将使用哪种方法通常取决于您作为思考者/开发人员的风格。

也就是说,一旦你开始使用这些风格中的任何一种,保持一致通常是值得的。拥有大型类,其中一些函数采用第一种方式,而其他函数采用第二种方式,可能会导致以后的可维护性问题。

Robert Martin的《Clean Code》中有一个有趣的章节是关于函数的,其中建议,无论你选择哪种方式,//DO STUFF部分应该是另一个函数调用

函数应该只做一件事