【问题标题】:Why can't I use break in a while loop in an anonymous method?为什么我不能在匿名方法的 while 循环中使用 break?
【发布时间】:2013-10-24 12:56:47
【问题描述】:

为什么我不能在 while 循环中使用 break; 语句,而在匿名方法中?

当我收到以下错误时,我正在编写一段代码(如下):“Control cannot leave the body of an anonymous method or lambda expression”。

谢天谢地,我可以改用return; 来解决问题,但我仍然想知道为什么我不能使用break;。对我来说,这两个语句之间的主要区别在于return; 退出一个方法,而break; 退出最远的嵌套循环。

我的代码,

while (someCondition)
{
    System.Threading.Thread.Sleep(500);

    Application.Current.Dispatcher.Invoke(new Action(() =>
    {
        if (someOtherCondition)
        {
            // Do stuff...
        }
        else
        {
            if (anotherCondition)
            {
                break;
            }

            // Do something else...
        }
    }));
}

【问题讨论】:

  • 因为你必须先退出你的方法,然后你才能退出你的循环,而且由于匿名方法仍然是方法,所以你必须先退出它
  • 也许这对你有帮助:stackoverflow.com/questions/9070080/…
  • @ppetrov 对,所以我必须先退出该方法(使用return;),然后是break; 循环。
  • @Sam 理论上是的,但在你的具体情况下它会更复杂,因为你只想在满足某些条件时打破循环,所以你必须找到一种方法来获得此信息在您的 while 循环中
  • @Sam,是的,您需要返回,然后休息。为此,例如将 Action 更改为 Func 并在返回 false 时中断。

标签: c# loops while-loop break anonymous-methods


【解决方案1】:

重写代码有助于解释原因:

while (someCondition)
{
    System.Threading.Thread.Sleep(500);

    Application.Current.Dispatcher.Invoke(MyMethod);
}

private void MyMethod()
{
    if (someOtherCondition)
    {
        // Do stuff...
    }
    else
    {
        if (anotherCondition)
        {
            break;
        }

        // Do something else...
    }
}

您正在中断一个没有循环的函数。循环存在于另一种方法中。因此,正如您发现的那样,需要调用 return 。仅仅因为您使用的是匿名方法,它仍然是包含 while 循环的方法的单独方法。

【讨论】:

    【解决方案2】:

    出于同样的原因,您不能这样做:

    while(1)
    {
        method1();
    }
    
    void method1()
    {
        break;
    }
    

    即使您的匿名方法与您的 while 循环写在同一个函数中,它仍然可以从没有 while 循环的地方调用。

    【讨论】:

      【解决方案3】:

      休息;不能用于退出方法,而是需要返回。在方法内部时,您的范围仅限于该方法,因为它可以从任何地方调用。虽然在方法内部没有关于调用范围的信息,因此代码不知道是否存在要跳出的循环。因此,方法范围与 if 语句的范围不同。

      【讨论】:

        【解决方案4】:

        Return 将您带出方法或函数,而 break 则将您带出循环或迭代。

        这是主要的区别。

        // This is Oki
        public void Do()
        {
          for (int i = 0; i < 10; i++)
          {
            break;        
          }
         }   
        
        // This is a compiler error
        public void Do()
        {
            break;        
        }       
        

        【讨论】:

          【解决方案5】:

          你可以改变while的条件:

          while (someCondition)
          {
              System.Threading.Thread.Sleep(500);
          
              Application.Current.Dispatcher.Invoke(new Action(() =>
              {
                  if (someOtherCondition)
                  {
                      // Do stuff...
                  }
                  else
                  {
                      if (anotherCondition)
                      {
                          //break;
                          someCondition = false;
                          return;
                      }
          
                      // Do something else...
                  }
              }));
              if (!someCondition)
                  break;
          }
          

          【讨论】:

          • 这充斥着潜在的同步问题。
          • 是的,这很普遍!为什么要以艰难的方式做事?
          • 不确定你是否理解我的意思。我是说这样的代码很容易受到该布尔值的竞争条件的影响。
          猜你喜欢
          • 2017-03-29
          • 1970-01-01
          • 2021-04-15
          • 2011-03-21
          • 1970-01-01
          • 2019-05-10
          • 1970-01-01
          • 2014-01-14
          • 2012-11-07
          相关资源
          最近更新 更多