2011-09-27 23 views
0

想象一下,对于一种方法来说,condintion应该是真的。哪个区块代表最佳方法(与性能相关且可读性),或者如果不是,您的建议是什么?以下哪个代码块更符合逻辑?

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

OR

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

这个问题是更好地在这里适用:http://codereview.stackexchange.com/ –

+2

有没有你不抛出异常什么特别的原因?看起来像这样引发的错误,如“在错误消息” – harold

+1

@harold上单击确定后所有地狱崩溃,代码位于顶层(UI),因此您不能向用户建议抛出异常。 – hungryMind

回答

3

那么,既不,因为你不会使用b其他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!"); 
} 
+0

很好地列举和清楚解释! –

1

二!第二!

但是我确实承认如果“// DO STUFF”真的很长并且嵌套,有时会做第一个。

+0

理想情况下,doStuff()应该是另一种方法调用,如果我们遵循Bob Martin叔叔的Clean Code准则的函数 –

+1

是真的,但只有当它作为一个工作单元才有意义。 DavidHeffernan的解决方案同样出色,但无论哪种情况,您都无法真正期望所有“// DO STUFF”每次都会被分解成新的方法。 – mlathe

12

都没有。使用保护条款代替:

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

    //inputs have been checked, proceed with normal execution 
} 

完成这样你可以处理所有的异常行为的前期,避免压痕的正常执行路径含量超标。

+0

我的答案与此不同,但您的是我在大部分代码中实际使用的模式。 +1为你思考它。 – David

+0

我更喜欢这种方式,所以我给+1。但值得注意的是,有些人坚持“每个职能应该有一个回报”。显然这不是OP问题的一部分,所以再次只是需要注意的一点。 –

+0

@Kiley在例外和goto常见之前的日子里,单次回访非常受欢迎。时间已过。 –

0

我更喜欢“如果条件”的方法,而不是否定条件,但这只是个人偏好。

0

这取决于。

在大多数情况下,第二个版本。如果(!条件)块中的代码量只有几行代码,并且(条件)块中的代码是很多代码,那么我会将该答案颠倒过来。如果您不必滚动就可以看到“else”,那么通过if语句更容易阅读。

+0

如果条件块中的代码是很多代码,它可能应该被重构并提取到另一个函数。 –

+0

我同意,如适用。我更喜欢做一件事情并且做得很好的小功能。但有些情况下不适用,在这种情况下,我仍然会回答我的答案。 – David

0

我更喜欢大卫提到的守卫条款,但在一般情况下,您应该首先将最常见的情况。它使得更容易遵循方法的流程。

0

这是一个比“逻辑”问题更多的风格问题。这两种方法都有效,您将使用哪种方法通常取决于您作为思考者/开发者的风格。

也就是说,一旦你开始使用这些样式中的任何一种,它一般都是值得一致的。有了大型课堂,其中一些功能是第一种方式,第二种方式可能会导致后期的可维护性问题。

罗伯特·马丁的Clean Code呈现上提出了职能有趣的一页,无论您选择何种方式,//做的东西的一部分应该是另一个函数调用

职能应该只做一件事

0

可读性/标准明智。我会接受数字2.我不认为有明显的表现差异,但我不是一个低级别的人。

0

正如通常这是一个问题,要求以下答案:“它取决于”,我会通过两个示例显示。
如果不是条件 对于ASP。净Web窗体验证我看到很多时候这个代码

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

if条件

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