Почему я не могу добавить метку goto в конце метода?

после исследования способа выхода из вложенного цикла я решил попробовать использовать goto,

private void example()
{
    for (int i = 0; i < 100; i++)
    {
        for (int ii = 0; ii < 100; ii++)
        {
            for (int iii = 0; iii < 100; iii++)
            {
                goto exitMethod;
            }                
        }             
    }

exitMethod:
}

но по какой-то причине, если я поставлю goto label находится в самом конце метода, Visual Studio 2012 (Ultimate) жалуется (и он не будет компилироваться),

Screenshot

но если я изменю свой код на этот,

private void example()
{
    for (int i = 0; i < 100; i++)
    {
        for (int ii = 0; ii < 100; ii++)
        {
            for (int iii = 0; iii < 100; iii++)
            {
                goto exitMethod;
            }                
        }             
    }

exitMethod:

    int someUnneededVariable; // Just an example, if I add ANY piece of code the error vanishes.
}

ни одна из ошибок не появляется (и она компилируется); я искал все ссылки MSDN, которые я знаю, и я не мог найти все, что угодно.

я знаю, что я мог бы легко решить эту проблему с помощью return;; даже так, я все равно хотел бы узнать, что вызывает эту ошибку.

6 ответов


метка не существует сама по себе: она помечает сообщении. Из раздела 8.4 спецификации C# 5:

оператор labeled-позволяет оператору иметь префикс метки. Помеченные операторы разрешены в блоках, но не разрешены как встроенные операторы.

в этом случае вы применяете метку в конце метода - нет инструкции для того, чтобы она была меткой на. Таким образом, компилятор абсолютно прав отклоните свой код.

Если вы действительно хотите, вы можете добавить метку в оператор возврата с избыточным возвратом:

exitMethod:
    return;
}

... или просто пустое заявление, как предложил Ирфан. Должно быть a заявление.

но я бы не рекомендовал. Просто измените любой goto exitMethod; заявление просто return.


вы можете разместить пустой оператор.

попробуй:

exitMethod: ;            

но в любом случае, если вы действительно хотите вернуться из текущего метода, используйте оператор return. если метод имеет другой тип возврата, чем void,

return (type);

иначе

return;

в этом случае

goto exitMethod;

эквивалентно просто

return;

и этот план возврата значительно более удобочитаем. Так что я не понимаю, зачем тебе это делать.


"The goto statement transfers the program control directly to a labeled statement." 

вы exitMethod как ваша метка, но в вашем первом примере у вас нет оператора. Вот почему вы получаете ошибку.

Гото ссылка


нужно что-то для goto сделать. Она не может быть пустой.

например:

private void example()
{
    for (int i = 0; i < 100; i++)
    {
        for (int ii = 0; ii < 100; ii++)
        {
            for (int iii = 0; iii < 100; iii++)
            {
                goto exitMethod;
            }                
        }             
    }

exitMethod:
    int i = DoSomething();
}

две вещи, первый goto не рекомендуется. Это не позволит вам использовать такую метку из-за того, как работают метки. Метка-это только идентификатор исходного кода, позволяющий указать на определенную инструкцию. В случае, если вы пытаетесь, нет никакой инструкции, следующей за ней, и, следовательно, она не может разрешить местоположение инструкции. Это вызывает вашу ошибку.

опять же, вы не должны использовать goto таким образом. Если вам просто нужно выйти из функции, вы можете используйте return; заявление. Если стандарт кодирования, который вы используете, диктует только одну точку возврата, попробуйте что-то вроде этого:

private void example()
{
    bool escaping = false;
    for (int i = 0; i < 100 && !escaping; i++)
    {
        for (int ii = 0; ii < 100 && !escaping; ii++)
        {
            for (int iii = 0; iii < 100 && !escaping; iii++)
            {
                escaping = true;
                break; // this is only needed if there is code farther down this 
                       // inner loop that would otherwise be executed.
            }                
        }             
    }

return;
}