Kontrola nie może wypaść z jednej etykiety przypadku

156

Próbuję napisać instrukcję przełącznika, która wpisuje wyszukiwane hasło w polu wyszukiwania w zależności od tego, które pole tekstowe wyszukiwania jest obecne. Mam następujący kod. Ale pojawia się błąd „Kontrola nie może wyjść z jednej etykiety przypadku”.

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']");
}

Kontrola nie może przechodzić z jednej etykiety przypadku ( case "SearchBooks":) do drugiej

Kontrola nie może przechodzić z jednej etykiety przypadku ( case "SearchAuthors":) do drugiej

Maya
źródło

Odpowiedzi:

260

Przegapiłeś tam kilka przerw:

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

Bez nich kompilator myśli, że próbujesz wykonać poniższe wiersze case "SearchAuthors":natychmiast po wykonaniu poniższych wierszy case "SearchBooks":, co nie jest dozwolone w C #.

Dodając breakinstrukcje na końcu każdego przypadku, program kończy każdy przypadek po jego zakończeniu, dla dowolnej wartości searchType.

BoltClock
źródło
31
Siedziałem tam, patrząc na ten kod i swój własny, aż w końcu zdałem sobie sprawę, że tak naprawdę brakuje mi przerwy w ostatniej sprawie, dla każdego, kto uzna to za pomocne.
somoso
13
A co, jeśli moje rozwiązanie nie wymaga odpowiedzi, breakponieważ musi się spełnić w pewnych okolicznościach ?!
Czarny
10
wow, co do cholery myśleli twórcy C # ?! Działa w każdym języku programowania, jaki znam, ale nie w C #.
Black
8
Jedna rzecz to odpowiedź brakuje, jest fakt, że można jeszcze zrobić C-Style fall-through użyciu goto case "some String".
NH.
3
Nigdy nie zdawałem sobie z tego sprawy. Zawsze myślałem, że VB nie ma funkcji przechodzenia przez przypadek, którą ma C ++. Teraz dowiaduję się, że C # też go nie ma, ORAZ aby dodać zniewagę do obrażeń, musisz wpisać instrukcję break. Nie wypełni go nawet automatycznie.
Brain2000
138

Trzeba break;, throw, goto, lub returnod każdego z etykietami przypadków. W pętli możesz też 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;
        }

Nie jest to prawdą tylko wtedy, gdy etykiety skrzynek są ułożone w następujący sposób:

 case "SearchBooks": // no code inbetween case labels.
 case "SearchAuthors":
    // handle both of these cases the same way.
    break;
agent-j
źródło
2
continuejest również możliwe
Tobias Valinski
3
Czy ktoś może wyjaśnić - dlaczego - to jest? Wydaje mi się, że istnieją uzasadnione przypadki użycia do wykonania kodu i kontynuowania kontroli w następnym przypadku.
YasharBahman,
9
@YasharBahman, myślę, że jest znacznie więcej błędów niż zamierzonych przypadków w językach, które obsługują rozwiązywanie problemów. W C # język na to pozwala, goto case "SearchBooks";więc masz możliwość robienia tego, co trzeba, bez utraty ekspresji lub dodawania nieoczekiwanych błędów.
agent-j
2
@ agent-j, widzę. Dzięki, to ma sens. Nie wiedziałem też, że możesz użyć goto w ten sposób, to naprawdę fajne! (chociaż myślę, że zawsze będę zmęczony używaniem go, ponieważ moi profesorowie przekonali mnie, że spontanicznie spalę, jeśli to zrobię)
YasharBahman,
2
Dlaczego ta odpowiedź nie jest akceptowaną odpowiedzią? Mówi więcej o tym, jakie masz opcje instrukcji przełącznika, a także udziela odpowiedzi na pytanie.
DotNet Programmer
30

Możesz zrobić więcej niż tylko upaść w C #, ale musisz użyć „przerażającej” instrukcji goto. Na przykład:

switch (whatever)
{
  case 2:
    Result.Write( "Subscribe" );
    break;
  case 1:
    Result.Write( "Un" );
    goto case 2;
}
Darwin Airola
źródło
14

Musisz dodać instrukcję przerwania:

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

Zakłada się, że chcesz albo obsłużyć SearchBooksprzypadek lubSearchAuthors - jak pisał w, w tradycyjnym switch C-styl przepływ kontrola byłaby „upadły przez” z jednej instrukcji case do następnego sposób, że wszystkie 4 linie kodu zostać wykonany w przypadku, gdysearchType == "SearchBooks" .

Błąd kompilatora, który widzisz, został wprowadzony (przynajmniej częściowo), aby ostrzec programistę o tym potencjalnym błędzie.

Alternatywnie mogłeś zgłosić błąd lub wrócić z metody.

Justin
źródło
1
Czy jest sposób na odtworzenie tutaj przełącznika podobnego do C? Uruchomić jakiś kod w jednym przełączniku, a następnie przejść do innego, który będzie działał dla wszystkich?
John Demetriou
@JohnDemetriou Możesz użyć instrukcji przejdź do przypadku, aby zreplikować to samo.
itsme.cvk
4

Na końcu każdego przypadku przełącznika po prostu dodaj instrukcję break, aby rozwiązać ten problem w następujący sposób:

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

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

            }
Debendra Dash
źródło
4

Ponieważ nie zostało to wspomniane w innych odpowiedziach, chciałbym dodać, że jeśli chcesz, aby SearchAuthors przypadku był wykonywany zaraz po wykonaniu pierwszego przypadku, tak jak ma to miejsce w przypadku pomijania "przerwy" w niektórych innych językach programowania jeśli jest to dozwolone, możesz po prostu użyć „goto”.

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

    case "SearchAuthors":
    Selenium.Type("//*[@id='SearchAuthors_TextInput']", searchText);
    Selenium.Click("//*[@id='SearchAuthors_SearchBtn']");
    break;
}
Ouissal
źródło
2

Pominięto instrukcje break. Nie zapomnij wprowadzić instrukcji break nawet w przypadku domyślnego.

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;
    default :
        Console.WriteLine("Default case handling");
        break;

}
Husnain Shabbir
źródło
0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Case_example_1
{
    class Program
    {
        static void Main(string[] args)
        {
            Char ch;
            Console.WriteLine("Enter a character");
            ch =Convert.ToChar(Console.ReadLine());
            switch (ch)
            {
                case 'a':
                case 'e':
                case 'i':
                case 'o':
                case 'u':
                case 'A':
                case 'E':
                case 'I':
                case 'O':
                case 'U':

                    Console.WriteLine("Character is alphabet");
                    break;

                default:
                    Console.WriteLine("Character is constant");
                    break;

            }

            Console.ReadLine();

        }
    }
}
Bob Maharjan
źródło
1
Powinieneś umieścić jakieś słowa lub coś, aby wyjaśnić, dlaczego jest to rozwiązanie. Ponieważ nie wyjaśniasz, dlaczego potrzebujesz przerw dla jednych, a dla innych nie.
DotNet Programmer
3
czy miałeś na myśli „spółgłoskę”?
maksymiuk
1
1. Myślę, że miałeś na myśli „samogłoskę” kontra „alfabet”. 2. Możesz zmienić switch (ch)na następujące. char vowelCheckChar = ( (Char.ToLower(ch) == 'y') ? ( ((new Random()).Next(2) == 0) ? ch : 'a' ) : ch ); // char vowelCheckChar = switch (vowelCheckChar)Przepraszam, musiałem. ;)
Tom