Pourquoi ne puis-je pas ajouter une étiquette goto à la fin d'une méthode?

après avoir cherché un moyen de sortir d'une boucle imbriquée, j'ai décidé d'essayer d'utiliser 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:
}

Mais pour une raison quelconque, si je mets un <!-Le label est à la fin de la méthode, Visual Studio 2012 (Ultimate) se plaint (et ne compile pas),

Screenshot

Mais si j'ai modifier mon code pour cela,

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

aucune des erreurs n'apparaît (et il compile); j'ai cherché dans toutes les références MSDN que je connais, et je ne pouvais pas rien à ce sujet.

je sais que je pourrais facilement résoudre ce problème en utilisant return;; même ainsi, je voudrais toujours savoir ce qui cause cette erreur.

12
demandé sur Sam 2013-08-30 18:25:44

6 réponses

Une étiquette n'existe pas sur les étiquettes déclaration. De la section 8.4 de la spécification C# 5:

un énoncé étiqueté permet à un énoncé d'être préfixé par une étiquette. Les énoncés étiquetés sont autorisés en blocs, mais ne sont pas autorisés en tant qu'énoncés intégrés.

dans ce cas, vous appliquez l'étiquette à la fin de la méthode - il n'y a pas de mention pour que ce soit une étiquette . Le compilateur a donc tout à fait raison de rejeter votre code.

si vous le souhaitez vraiment, vous pouvez ajouter une étiquette à une instruction de retour par ailleurs redondante:

exitMethod:
    return;
}

... ou juste une déclaration vide, comme suggéré par Irfan. Il y a déclaration bien.

Mais je ne le recommande pas. Il suffit de changer tout goto exitMethod; simplement return.

18
répondu Jon Skeet 2013-08-30 14:29:44

vous pouvez placer une déclaration vierge.

Essaie:

exitMethod: ;            

mais de toute façon, si vous voulez vraiment revenir de la méthode actuelle, utilisez l'instruction return. si la méthode a d'autres type de retour de vide,

return (type);

sinon,

return;
9
répondu Irfan 2013-08-30 14:30:55

Dans ce cas

goto exitMethod;

est l'équivalent de tout simplement

return;

et cette déclaration de régime est beaucoup plus lisible. Donc je ne vois pas pourquoi vous voulez le faire.

1
répondu MK. 2013-08-30 14:28:58
"The goto statement transfers the program control directly to a labeled statement." 

Vous avez exitMethod comme votre étiquette, mais dans votre premier exemple vous n'avez pas de déclaration. C'est pourquoi vous obtenez une erreur.

référence goto

0
répondu Paddyd 2013-08-30 14:29:48

vous avez besoin de quelque chose pour le goto pour le faire. Il ne peut pas être vide.

Par exemple:

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();
}
0
répondu Sam Leach 2013-08-30 14:34:26

deux choses, d'abord goto n'est pas recommandé. Il ne vous permettra pas d'utiliser une étiquette comme cela en raison de la façon dont les étiquettes fonctionnent. Une étiquette est un identifiant de code source qui vous permet de pointer vers une instruction spécifique. Dans le cas où vous tentez, il n'y a aucune instruction qui suit, et donc il ne peut pas résoudre à l'emplacement d'une instruction. C'est la cause de votre erreur.

return; déclaration. Si la norme de codage que vous utilisez ne dicte qu'un seul point de retour, essayez quelque chose comme ceci:

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;
}
-1
répondu aring 2013-08-30 14:33:32