Вопрос

Why can't I use a break; statement in a while loop, whilst in an anonymous method?

I was working on the piece of code (below), when I got this error: "Control cannot leave the body of an anonymous method or lambda expression".

Thankfully I can solve the problem by using return; instead, but I'd still like to know why I can't use break;. To me, the main difference between the two statements, was that return; exits a method, and break; exits the further-most nested loop.

My code,

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

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

            // Do something else...
        }
    }));
}
Это было полезно?

Решение

Rewriting the code helps to explain why:

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...
    }
}

You are breaking inside a function that has no loop. The loop exists in another method. So return needs to be called instead, as you found out. Just because you are using an annonymous method, it's still a separate method to the one containing the while loop.

Другие советы

For the same reason you can't do this:

while(1)
{
    method1();
}

void method1()
{
    break;
}

Even if your anonymous method is written in the same function as your while loop, it can still be called from somewhere where there isn't a while loop around.

break; cannot be used to exit methods, instead you need a return. And while inside a method your scope is limited to that method because it could have been called from anywhere. While inside the method there is no information on the calling scope and the code therefore does not know if there is a loop to break out of. So a method scope is different than the scope of an if-statement.

Return takes you out of a method or a function but break gets you out of the loop or an iteration.

This is the main diff.

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

// This is a compiler error
public void Do()
{
    break;        
}       

You can change condition of 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top