【问题标题】:When to use the 'continue' keyword in C#何时在 C# 中使用“继续”关键字
【发布时间】:2011-12-19 20:41:34
【问题描述】:

最近,我正在经历一个开源项目,虽然我已经在 .NET 中进行了几年的开发,但我之前没有偶然发现 continue 关键字。

问题:使用continue 关键字会受益的最佳做法或领域有哪些?我以前可能没有看到它有什么原因吗?

【问题讨论】:

  • 从 3.5 开始,人们使用 LINQ Where 子句来处理过去使用 continue 解决的情况。

标签: c# .net continue


【解决方案1】:

您也可以使用 continue 语句进行代码优化。当您确定在所有条件中,至多满足一个条件时。你可以像下面这样使用它,

foreach (var element in List)
{
    if (condition1)
    {
        //do stuff .....
        continue;
    }
    if (condition2)
    {
        //do stuff ....
        continue;
    }
    .
    .
    .
    if (condition)
    {
        //do stuff ....
        continue;
    }
}

这里,当满足 if 语句的任何条件时,将跳过所有 if 语句的其余部分。

【讨论】:

  • 如果不能正确管理continue,IMO 就不应该进行优化。
【解决方案2】:

我猜你以前为什么没有看到它,continue 是函数的gotobreak 和早期returns 的表亲。我们都知道Goto is considered harmful,所以很多开发人员可能倾向于避免它。

对我来说,当我想清理可能存在一些我不关心的值的循环时,我倾向于使用continue。使用continue,我可以跳过这些值,而无需将循环中的“重要”逻辑包含在嵌套的if 中。

foreach (var v in GetSomeValues())
{
  if (ThisValueIsNotImportant(v)) continue;

  //Do important stuff with the value.
}

【讨论】:

    【解决方案3】:

    如果适用,您可以使用它立即退出当前循环迭代并开始下一个循环。

    foreach (var obj in list)
    {
        continue;
    
        var temp = ...; // this code will never execute
    }
    

    continue 通常与条件相关联,并且通常可以使用条件来代替 continue;

    foreach (var obj in list)
    { 
        if (condition)
           continue;
    
        // code
    } 
    

    可以写成

    foreach (var obj in list)
    {
        if (!condition)
        {
            // code
        }
    }
    

    continue 如果您在循环中可能有多个嵌套的if 逻辑级别,则将变得更有吸引力。 continue 而不是嵌套可能会使代码更具可读性。当然,将循环和条件重构为适当的方法也会使循环更具可读性。

    【讨论】:

    • 我的编译器建议的圈复杂度如何?如果有帮助,不嵌套代码不是更好吗?
    【解决方案4】:

    将其视为“返回”,但仅适用于循环的上下文。 一个常见的例子是状态机,循环所有可用的输入。

    while(!SomeQueue.Empty)
    {
        byte nextByte = SomeQueue.Dequeue();
    
        switch State:
        {
            case A:
                if(nextByte == Condition)
                {
                    State = B;
                }
                else                
                {
                    State = ParseError;
                }
                continue;
            case B:
                //Test nextByte
                State = C;
                continue;
            case C:
                //Test nextByte
                State = A;
                continue;
            case ParseError:
                //Do something for this condition
                State = A;
                continue;
    }
    

    【讨论】:

      【解决方案5】:

      基本上continuebreak 更好(但通常只是伪装)goto 语句...

      每当您在循环中并且知道循环中接下来的所有内容都应该被跳过并继续下一次迭代时,您可以使用continue...

      因此它们应该很少使用...有时它们使代码非常可读和清晰(例如,如果替代方案是多层嵌套)...大多数时候它们会增加一些类似于goto 的混乱.

      【讨论】:

        【解决方案6】:

        它可以防止深度嵌套。

        foreach(var element in collection)
        {
            doSomething();      
            doSomethingElse();
            if (condition1)
            {
                action1();
                action2();
                if (condition2)
                {
                   action3();                            
                }
            }
        }
        

        可以改写为

        foreach(var element in collection)
        {
            doSomething();      
            doSomethingElse();
            if (!condition1)
            {
               continue;
            }
            action1();
            action2();
            if (!condition2)
            {
               continue;
            }
            action3();
        }
        

        如果代码块不是微不足道的而是垂直更大,使用continue 可能会提高代码的可读性。显然,它应该像其他所有语言结构一样慎重使用。

        【讨论】:

        • +1 用于回答最佳实践部分。我真的很讨厌那些页面长的 if 块。
        【解决方案7】:

        我是否因为不使用而错过了什么?

        这似乎是一个奇怪的问题。想必您比任何人都清楚自己是否需要尽早开始循环的下一次迭代。

        【讨论】:

          【解决方案8】:

          您应该谨慎使用它。

          最好的(= 最容易阅读的)循环不使用breakcontinue,它们是一种结构化的goto 语句。

          话虽如此,1 甚至 2 个 break/continue 语句不会使循环不可读,但明确它们的使用并使其保持简单是值得的。

          【讨论】:

          • goto 的问题在于它允许任意跳转到代码中的任意点。 continue 重新启动最近的封闭循环。我不认为对goto 的批评适用。如果这样做,它们也适用于returnthrow
          • @recursive:这种(大大减少的)批评当然适用于 return(首选:方法应该有 1 个退出点)。例外是完全不同的事情。
          【解决方案9】:

          continue 关键字用于跳过循环块的其余部分并继续。例如:

          for(int i = 0; i < 5; i++)
          {
             if(i == 3) continue; //Skip the rest of the block and continue the loop
          
             Console.WriteLine(i);
          }
          

          将打印:

          0
          1
          2
          4
          

          【讨论】:

            【解决方案10】:

            当您不想break 退出循环,但您想要下一次迭代时:

            for (int i = 0; i < something; i++)
            {
                if (condition)
                    continue;
            
                // expensive calculations, skip due to continue
                // or due to the condition above I don't want to 
                // run the following code
                stuff();
                code();
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-02-28
              • 2017-02-26
              • 1970-01-01
              • 2019-02-25
              • 2014-01-30
              • 2011-12-13
              • 1970-01-01
              相关资源
              最近更新 更多