173 votes

Le contrôle ne peut pas tomber à cause d'une étiquette de cas

J'essaie d'écrire une instruction de commutation qui saisit le terme recherché dans le champ de recherche en fonction de la zone de texte de recherche présente. J'ai le code suivant. Mais je reçois une erreur "Control cannot fall through from one case label".

switch (searchType)
{
    case "SearchBooks":
        Selenium.Type("//*[@id='SearchBooks_TextInput']", searchText);
        Selenium.Click("//*[@id='SearchBooks_SearchBtn']");

    case "SearchAuthors":
        Selenium.Type("//*[@id='SearchAuthors_TextInput']", searchText);
        Selenium.Click("//*[@id='SearchAuthors_SearchBtn']");
}

Le contrôle ne peut pas tomber d'une étiquette de cas ( case "SearchBooks": ) à un autre

Le contrôle ne peut pas tomber d'une étiquette de cas ( case "SearchAuthors": ) à un autre

0 votes

Je viens de réaliser à quel point une déclaration de commutation serait plus belle si nous n'avions pas à mettre break; là-dedans. C'est un horrible artefact du passé.

0 votes

Parfois, il faut regrouper plusieurs cas et les traiter de la même manière ! La fonction Falling Through est très utile dans ces cas-là.

0 votes

@stackoverblown certainement, mais c'est une sorte de cas spécial que le compilateur pourrait être assez intelligent pour comprendre. De toute façon, nous sommes coincés avec ça !

296voto

BoltClock Points 249668

Tu as raté des pauses là :

switch (searchType)
{
    case "SearchBooks":
        Selenium.Type("//*[@id='SearchBooks_TextInput']", searchText);
        Selenium.Click("//*[@id='SearchBooks_SearchBtn']");
        break;

    case "SearchAuthors":
        Selenium.Type("//*[@id='SearchAuthors_TextInput']", searchText);
        Selenium.Click("//*[@id='SearchAuthors_SearchBtn']");
        break;
}

Sans eux, le compilateur pense que vous essayez d'exécuter les lignes ci-dessous case "SearchAuthors": immédiatement après les lignes sous case "SearchBooks": ont été exécutées, ce qui n'est pas autorisé en C#.

En ajoutant le break à la fin de chaque cas, le programme quitte chaque cas après qu'il ait terminé, pour toute valeur de searchType .

34 votes

Pour ma part, je suis resté assis à regarder ce code et le mien jusqu'à ce que je me rende compte que je manquais la rupture dans le tout dernier cas, pour ceux qui trouvent cela utile.

0 votes

@somoso J'ai eu la pause à l'intérieur de les accolades d'un nid if donc je n'ai pas pu le repérer rapidement.

15 votes

Et si ma solution ne nécessite pas break parce qu'il doit tomber dans certaines circonstances ? !

147voto

agent-j Points 14703

Vous devez break; , throw , goto o return de chacune de vos étiquettes de cas. Dans une boucle, vous pouvez également continue .

        switch (searchType)
        {
            case "SearchBooks":
                Selenium.Type("//*[@id='SearchBooks_TextInput']", searchText);
                Selenium.Click("//*[@id='SearchBooks_SearchBtn']");
                break;

            case "SearchAuthors":
                Selenium.Type("//*[@id='SearchAuthors_TextInput']", searchText);
                Selenium.Click("//*[@id='SearchAuthors_SearchBtn']");
                break;
        }

La seule fois où ce n'est pas vrai, c'est lorsque les étiquettes des caisses sont empilées comme ceci :

 case "SearchBooks": // no code inbetween case labels.
 case "SearchAuthors":
    // handle both of these cases the same way.
    break;

4 votes

continue est également possible

4 votes

Quelqu'un peut-il m'expliquer -pourquoi- cela ? J'ai l'impression qu'il existe des cas d'utilisation légitimes pour exécuter du code et faire en sorte que le contrôle se poursuive jusqu'au cas suivant.

14 votes

@YasharBahman, je pense qu'il y a beaucoup plus de bugs que de cas prévus dans les langages qui supportent le case fall-through. En C#, le langage vous permet de goto case "SearchBooks"; afin que vous puissiez faire ce que vous devez faire sans perdre beaucoup d'expressivité ou ajouter des bogues inattendus.

40voto

Darwin Airola Points 479

En C#, vous pouvez faire plus qu'un simple passage, mais vous devez utiliser la "redoutable" instruction goto. Par exemple :

switch (whatever)
{
  case 2:
    Result.Write( "Subscribe" );
    break;
  case 1:
    Result.Write( "Un" );
    goto case 2;
}

0 votes

Cela semble être la solution la plus polyvalente. Mais pourquoi qualifier goto de "redoutable" ?

0 votes

Merci, cela fonctionne lorsque le défaut est au milieu et que vous voulez passer à l'affaire suivante...

14voto

Justin Points 42106

Vous devez ajouter une déclaration de rupture :

switch (searchType)
{
case "SearchBooks":
    Selenium.Type("//*[@id='SearchBooks_TextInput']", searchText);
    Selenium.Click("//*[@id='SearchBooks_SearchBtn']");
    break;
case "SearchAuthors":
    Selenium.Type("//*[@id='SearchAuthors_TextInput']", searchText);
    Selenium.Click("//*[@id='SearchAuthors_SearchBtn']");
    break;
}

Cela suppose que vous souhaitiez soit traiter le message SearchBooks cas ou le site SearchAuthors - comme vous l'aviez écrit, dans une instruction de commutation traditionnelle de type C, le flux de contrôle serait "passé" d'une instruction de cas à la suivante, ce qui signifie que les 4 lignes de code sont exécutées dans le cas où searchType == "SearchBooks" .

L'erreur de compilation que vous voyez a été introduite (du moins en partie) pour avertir le programmeur de cette erreur potentielle.

Vous auriez également pu lancer une erreur ou retourner une méthode.

1 votes

Y a-t-il un moyen de reproduire l'interrupteur de type C ici ? Exécuter du code dans un commutateur, puis passer à un autre qui fonctionnera pour tout le monde ?

0 votes

@JohnDemetriou Vous pouvez utiliser les instructions go to case pour reproduire la même chose.

6voto

Debendra Dash Points 1932

À la fin de chaque switch case, il suffit d'ajouter l'élément break -pour résoudre ce problème

switch (manu)
{
    case manufacturers.Nokia:
        _phanefact = new NokiaFactory();
        break;

    case manufacturers.Samsung:
        _phanefact = new SamsungFactory();
        break;  
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X