通过在循环中使用continue来避免嵌套
本文关键字:continue 嵌套 循环 | 更新日期: 2023-09-27 18:29:59
当我们有一个循环(无论是while
、for
等),并且其中有一个简单的条件,指定当前循环是否应该完成任何工作(这样做将产生进一步的嵌套缩进)时,可以简单地测试这个条件的否定并调用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
}
}
确实没有理由不使用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
关键字本身的使用并不是一件坏事。但在这种特殊的情况下,它提供了一个机会,可以退一步询问代码的任何给定部分是否做了太多可以分离的事情。
所以我想你有什么:
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))
{
...
}
这是可以的。但在某些情况下,这段代码会更好:
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)
}
并使用Monads的monad-Do for.net:
var collection = new[] {1, 2, 3};
var processedCollection = collection.Where(c => c != 1).Do(PerformAction);
像这样的守护者声明可能是一种气味,您应该提前过滤集合。这在很大程度上取决于您的域、您需要该条件的原因以及您的代码和工作流如何继续。我认为这个问题没有一般的答案。