【问题标题】:How to leave a while loop inside a foreach loop如何在foreach循环中留下while循环
【发布时间】:2013-02-04 04:24:15
【问题描述】:

我有一个while 循环,在这个while loop 里面我有一个foreach loop

Here 我学会了如何使用Continue; Return; Break 在循环中跳过当前交互。但是当我在foreach loop 内时,我需要离开while loop 这可能吗?

我正在 foreach loop 内部进行交互,我想离开 foreach 并转到 while 的下一个交互。我该怎么做? 像这样:

while (!reader.EndOfStream)  //COMEÇO DO WHILE
{
  ///Some Codes

  foreach(string s in checkedlistbox1.items)
        {
          switch(s)
           {
             case "1":
                if( 1 > 0)
                 {
                    ///HERE I WANT TO GO TO THE NEXT INTERACTION OF THE WHILE
                    ///When I use CONTINUE; HERE, I GO TO THE NEXT INTERACTION OF THE FOREACH. BUT I NEED TO GO TO THE NEXT OF THE WHILE.
                 }
           }
        }
}

这是我想要做的: 我正在逐行读取file.txt,并用这些值和其他一些东西写一个新的......其中一些值可能是required(由用户设置),如果required field为空,所以我什么都不做,去下一个while interaction...

【问题讨论】:

  • 一些代码示例将是完美的......
  • @IlyaIvanov 使用break 我转到switchitself 的下一个交互;s 我需要转到while 的下一个
  • C# 已经转到 :P 试试
  • @JakobBowyer 每个人都说goto是一种不好的做法;s
  • 他们只是在逗你。

标签: c# foreach switch-statement


【解决方案1】:

1) 是的,这是可能的。它有效。

 foreach() {
    while() {
       break; //leave the while
    }
    //... and continues from here
 }

2)每个 while 都会在下一次 foreach 迭代之前结束,所以第二个问题没有多大意义......除非你的意思是在 foreach 内开始下一个 while,在这种情况下......是的!

 foreach() {
    while() {
       ...
    }
    break; //will go to the next foreach iteration, i.e. starts a new while
 }

至于您的代码示例,您在评论中提到的点的中断将满足您的需要(退出 foreach,自然进入下一个 while 迭代)。

编辑:发布示例后,您的问题似乎不在于 while 和 foreach 之间的交互,而在于 switch:break 用作“转到循环中的下一个迭代”和“完成这个案子和开关”。

编译器会将中断视为“开关中断”。您需要自己模仿行为:

    foreach(string s in checkedlistbox1.items)
    {
      bool dobreak = false;
      switch(s)
       {
         case "1":
            if( 1 > 0)
             {
                dobreak = true;
             }
             break; // exit the case
       }
       if (dobreak)
          break; // exits the for (it is a 'foreach-break')
    }

【讨论】:

  • 哦,我明白了!没有代码,我得到了相反的方法(foreach/while)。然而,同样的推理也适用
  • @Ghaleon 我读了你的编辑,问题是中断(它将与开关配对,而不是 foreach)。我会编辑我的答案
【解决方案2】:
bool dobreak = false;
while (!reader.EndOfStream && !dobreak )  //COMEÇO DO WHILE
{
  ///Some Codes

  foreach(string s in checkedlistbox1.items)
        {
          switch(s)
           {
             case "1":
                if( 1 > 0)
                 {
                    dobreak = true;
                    break;
                 }
           }
        }
}

【讨论】:

  • 这将退出 foreach 和 while...我怀疑 OP 也不想退出 while..
  • 什么是OP?而且我不想离开while 只是去下一个interaction of the while ;x 这个方法可以吗?
  • OP = 原始海报/帖子(即发起主题的人或消息)
  • 哈哈,知道了!谢谢@MatthewWatson 和 dema80!
【解决方案3】:

你需要从 switch 中断开,然后从 foreach 中断开,同时设置一个变量。

然后您可以检查该变量以查看您是否应该将continue 转移到下一次while 迭代。

这样做:

while (!reader.EndOfStream)
{
    // Some Codes

    bool skipToNext = false;

    foreach (string s in checkedlistbox1.items)
    {
        switch (s)
        {
            case "1":
                if (1 > 0)
                {
                    skipToNext = true;
                    break;
                }
        }

        if (skipToNext) break;
    }

    // in the case of there being more code, you can now use continue
    if (skipToNext) continue;

    // more code
}

此流程的工作示例

var list = new List<string> { "0", "1", "2" };
int a = 0, b = 2;

while (a++ < b)
{
    // Some Codes

    bool skipToNext = false;

    foreach (string s in list)
    {
        Debug.WriteLine("{0} - {1}", a, s);

        switch (s)
        {
            case "1":
                if (1 > 0)
                {
                    Debug.WriteLine("Skipping switch...");
                    skipToNext = true;
                    break;
                }
        }

        if (skipToNext)
        {
            Debug.WriteLine("Skipping foreach...");
            break;
        }
    }

    // in the case of there being more code, you can now use continue
    if (skipToNext)
    {
        Debug.WriteLine("Skipping to next while...");
        continue;
    }

    // more code
}

输出:

1 - 0
1 - 1
Skipping switch...
Skipping foreach...
Skipping to next while...
2 - 0
2 - 1
Skipping switch...
Skipping foreach...
Skipping to next while...

【讨论】:

  • 我不想离开while就去while的下一个交互;x这个方法能做到吗
  • 第一个if(skipToNext) break; 继续下一个foreach interaction,就像以前一样。我怎么去下一个while交互? ;\
  • 我的坏人!抱歉,我用continue 代替break 呵呵 ;x 现在它工作了!!如同一位老板!我只是做一个最终测试,我会给出反馈......
  • 很高兴为我的朋友服务。 :)
【解决方案4】:

未经测试,但以下是一些可以回答您问题的可能方法:

bool continueLooping = true;

string[] array = { "1", "2" };

while (continueLooping)
{
    foreach (string x in array)
    {
        // break out of foreach loop AND while loop
        if (x == "1")
        {
            continueLooping = false;
            break;
        }

        // go to next iteration of foreach loop
        if (x == "2")
        {
            continue;
        }

        // break out of foreach loop and continue while loop
        if (x == "3")
        {
            break;
        }
    }
}

【讨论】:

    【解决方案5】:

    你需要打破你的foreachwhile 所以像这样:

    bool abort = false;
    while (!reader.EndOfStream && !abort)  //COMEÇO DO WHILE
    {
      ///Some Codes
    
      foreach(string s in checkedlistbox1.items)
            {
              switch(s)
               {
                 case "1":
                    if( 1 > 0)
                     {
                        ///HERE I WANT TO LEAVE TO THE NEXT INTERACTION OF THE WHILE
                        abort = true;
                        break;
                     }
               }
    
               if (abort)
               {
                   break;
               }
        }
    }
    

    【讨论】:

      【解决方案6】:

      我是 C# 的初学者,但我建议您在 while 循环中添加另一个条件,您可以自己设置。然后,在需要时更改它。例如:

      MyKeyCondition = 0;
      
      while(MainCondition||MyKeyCondition){
      
      if(MyCheckCondition){
      MyKeyCondition = 1;
      }
      
      }
      

      现在,如果你改变你的关键条件,即使不满足主要条件,你也可以处理 while 循环。

      【讨论】:

        【解决方案7】:

        可以试试goto;

        while (true)
        {
         foreach(string s in checkedlistbox1.items)
          {
           switch(s)
           {
             case "1":
                if( 1 > 0)
                {
                  goto WhileOut;
                }
            }
          }
        }
        WhileOut:
              // some code
        

        【讨论】:

          【解决方案8】:

          嵌套循环通常表明方法应该被拆分。

          在这个例子中,它可以使代码更清晰。如果将内部for 循环放入单独的方法中,则可以使该方法返回bool。如果希望外部while 循环继续迭代,则返回true;否则,如果您希望它退出while 循环,则返回false

          看起来像这样:

          private void doSomething(StreamReader reader)
          {
              while (!reader.EndOfStream)
              {
                  // Some Codes...
          
                  if (!processNextItem(reader))
                  {
                      break;
                  }
              }
          }
          
          // Returns true if the caller should continue its while loop; false if it should exit it.
          
          private bool processNextItem(StreamReader reader)
          {
              foreach (string s in checkedlistbox1.items)
              {
                  switch (s)
                  {
                      case "1":
                          if (1 > 0)
                          {
                              return false; // Return false to exit while loop.
                          }
                  }
              }
          
              return true; // Return true to continue while loop.
          }
          

          我不确定您需要将什么传递给processNextItem();我刚刚以reader 为例。

          【讨论】:

          • 它看起来很漂亮'-'我不知道......我会尝试这样做,问题是我的代码现在非常big。我会做一些测试,一旦我得到结果,我会在这里发布,我会继续在这里检查。
          • 如果你的函数非常大,那就更有理由将它们拆分。你会得到很多长期收益的短期痛苦。 :)
          • 是的,你说得对...我只是害怕把所有东西都搞砸,试图改变 =s 我会备份并尝试!
          • 啊,这就是你的单元测试电池的用武之地!在每次重构更改后运行单元测试,以确保没有破坏任何内容。
          猜你喜欢
          • 2014-10-19
          • 2013-10-01
          • 1970-01-01
          • 2017-05-28
          • 2023-04-09
          • 2016-03-14
          • 2012-10-02
          • 2014-12-05
          • 2015-07-03
          相关资源
          最近更新 更多