Керування не може потрапляти через одну мітку корпусу


156

Я намагаюся написати оператор перемикання, який би вводив пошуковий термін у поле пошуку залежно від того, яке саме текстове поле пошуку є. У мене є такий код. Але я отримую помилку "Контроль не може пройти з однієї мітки справи".

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

Керування не може переходити з однієї мітки регістру ( case "SearchBooks":) на іншу

Керування не може переходити з однієї мітки регістру ( case "SearchAuthors":) на іншу

Відповіді:


260

Ви пропустили кілька перерв там:

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

Без них компілятор вважає, що ви намагаєтеся виконати рядки нижче case "SearchAuthors":одразу після виконання рядків внизу case "SearchBooks":, що не дозволено в C #.

Додаючи breakвисловлювання в кінці кожного випадку, програма закінчує кожен випадок після її завершення, на яке б значення не було searchType.


31
Для мене я сидів там, дивлячись на цей і свій власний код, поки нарешті не зрозумів, що насправді не вистачає перерви в останньому випадку для тих, хто вважає це корисним.
somoso

13
А що, якщо моє рішення не потребує, breakтому що воно повинно пропасти за якихось обставин ?!
Чорний

10
уау, що за чорт думали C # devs ?! Він працює в кожній мові програмування, яку я знаю, але не в C #.
Чорний

8
Цього не вистачає цієї відповіді, це те, що ви все ще можете робити пропуски C-Style за допомогою goto case "some String".
NH.

3
Я ніколи цього не усвідомлював. Я завжди думав, що VB пропускає функцію пропуску випадку, яку має C ++. Тепер я з’ясував, що і у C # його немає, І щоб додати образи до травми, вам потрібно набрати заяву про перерву. Він навіть не заповнить його автоматично.
Brain2000

138

Вам потрібно break;, throw, gotoабо returnвід кожного з ваших етикеток. У циклі ви також можете 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;
        }

Єдиний раз, коли це не відповідає дійсності, - коли мітки регістрів складені так:

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

2
continueМожливо також
Тобіас Валінскі

3
Хтось може пояснити-чому- це? Я відчуваю, що існують законні випадки використання для виконання коду та контроль над цим продовжують переходити до наступного випадку.
YasharBahman

9
@YasharBahman, я думаю, що в мовах, які підтримують пропуск випадків, набагато більше помилок, ніж передбачалося. У мові C # мова дозволяє вам зробити goto case "SearchBooks";так, щоб ви мали можливість робити те, що вам потрібно, не втрачаючи особливої ​​виразності чи додаючи несподівані помилки.
агент-j

2
@ агент-j я бачу. Дякую, це має багато сенсу. Крім того, я не знав, що ти можеш використовувати goto так, це дійсно здорово! (хоча, я думаю, я завжди буду втомлюватися від його використання, оскільки мої професори переконували мене, що я спонтанно згоряю, якщо так зроблю)
YasharBahman

2
Чому це не є прийнятою відповіддю? Він детальніше розповідає про те, які варіанти у вас є для оператора переключення, а також дає відповідь на питання.
Програміст DotNet

30

Ви можете зробити більше, ніж просто провалитися в C #, але ви повинні використовувати "страшний" goto-оператор. Наприклад:

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

14

Вам потрібно додати перерву:

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

Це передбачає , що ви хочете , або ручку на SearchBooksразі абоSearchAuthors - як було написано в, в традиційній постановці перемикача C-стилі потік управління б «впав через» від одного саза до наступного значення , що всі 4 рядки коди отримати виконується в разі , коли searchType == "SearchBooks".

Помилка компілятора, яку ви бачите, була введена (принаймні частково) для попередження програміста про цю потенційну помилку.

Як альтернативу, ви могли викинути помилку або повернутися з методу.


1
Чи є спосіб повторити C-подібний перемикач тут? Запустити якийсь код в одному комутаторі, а потім перейти на інший, який працюватиме для всіх?
Джон Деметріу

@JohnDemetriou Ви можете скористатися операторами переходу до справи, щоб повторити те саме.
itsme.cvk

4

У кінці кожного випадку перемикання просто додайте заяву про перерву, щоб вирішити цю проблему, наприклад,

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

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

            }

4

Оскільки це не було згадано в інших відповідях, я хотів би додати, що якщо ви хочете, щоб справа SearchAuthors виконувалася відразу після того, як буде зроблено перший випадок, так само, як це відбувається, коли випускаєте "перерву" в деяких інших мовах програмування там, де це дозволено, ви можете просто використовувати "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;
}

2

Ви пропустили заяви про перерву. Не забувайте вводити заяву про перерву навіть у випадку за замовчуванням.

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;

}

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();

        }
    }
}

1
Ви повинні сказати кілька слів або щось, щоб пояснити, чому це рішення. Оскільки ви не пояснюєте, для чого потрібні перерви для одних, а не для інших.
Програміст DotNet

3
ти мав на увазі "приголосний"?
maksymiuk

1
1. Я думаю, ви мали на увазі "голосний" проти "алфавіт". 2. Ви можете змінити switch (ch)наступне. char vowelCheckChar = ( (Char.ToLower(ch) == 'y') ? ( ((new Random()).Next(2) == 0) ? ch : 'a' ) : ch ); // char vowelCheckChar = switch (vowelCheckChar)Вибачте, довелося. ;)
Том
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.