通过在循环中使用continue来避免嵌套

时间:2014-11-11 15:33:08

标签: c#

当我们有一个循环(be whilefor等)时,我们在其中有一个简单的条件,指定当前循环是否应该完成任何工作(在做什么的时候)所以会产生一个进一步的嵌套缩进),是否可以简单地测试这个条件的否定并调用continue来忽略循环中的当前元素(这将避免嵌套结构)?

或者有没有理由不使用continue

例如:

foreach (var t in new[] {1, 2, 3})
{
    int n = SomeOperation(t);
    if (n == 1) continue;
    // further stuff
}

相反
foreach (var t in new[] {1, 2, 3})
{
    int n = SomeOperation(t);
    if (n != 1) 
    {
        // further stuff
    }
}

4 个答案:

答案 0 :(得分:3)

没有理由不使用continue,它存在是有原因的。

虽然这并不是说这是你的例子中最好的方法。考虑一下你在这里想做什么......

  

对集合中的元素子集执行操作

鉴于此,确定子集的责任在哪里?在操作上?或者,是否应该在操作之前选择该子集作为其自己的独特代码?我认为关注点的分离决定了这一点。请考虑对您的示例进行此修改:

var collection = new[] {1, 2, 3};
// other code doing other things on the collection here, then...

var filteredCollection = collection.Where(x => x != 1);
foreach (var t in filteredCollection)
    PerformSomeOperation(t);

这使循环更小更简单。通过将循环操作提取到单独的方法中更是如此。现在循环只做一件事......迭代一个集合。集合的定义及其创建方式完全是一个单独的问题。

使用continue关键字本身并不是件坏事。但在这种特殊情况下,它提供了一个退回并询问代码的任何给定段是否做了太多可以分离的事情的机会。

答案 1 :(得分:1)

所以我猜你所拥有的是:

foreach (var t in new[] {1, 2, 3}) 
{
    if (t != 1)
    {
       ...
    }
}

而不是使用Continue或其他一些非显而易见的分支,我首选的处理方法是使用linq过滤源:

foreach (var t in new[] {1, 2, 3}.Where(i => i != 1))
{
    ...
}

答案 2 :(得分:1)

没关系。但在某些情况下,这段代码会更好:

foreach (var t in new[] {1, 2, 3}.Where(c=>c!=1))
{
    // further stuff which would be nested if we´d not use continue (negating the condition)
}

在下一步中,您可以将工作人员封装在另一个方法中:

public void PerformAction(int element)
{
     // further stuff which would be nested if we´d not use continue (negating the condition)
}

并使用monad来自Monads for .net:

var collection = new[] {1, 2, 3};
var processedCollection = collection.Where(c => c != 1).Do(PerformAction);

答案 3 :(得分:0)

像这样的监护人声明可能是你应该预先过滤集合的气味。很大程度上取决于您的域名,您需要该条件的原因以及您的代码和工作流程如何继续。我认为这个问题没有一般性答案。