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


156

Я пытаюсь написать оператор switch, который вводит поисковый термин в поле поиска в зависимости от того, какое текстовое поле поиска присутствует. У меня есть следующий код. Но я получаю сообщение об ошибке «Не удается выполнить контроль из одной метки».

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
Что касается меня, я сидел и смотрел на этот код, и на свой собственный, пока, наконец, не понял, что на самом деле упускаю разрыв в самом последнем случае, для тех, кто считает это полезным.
сомосо

13
А что, если мое решение не требует, breakпотому что оно должно провалиться при некоторых обстоятельствах ?!
черный

10
вау, какого черта думали разработчики C # ?! Это работает на любом языке программирования, который я знаю, но не на C #.
Черный,

8
Единственное, чего не хватает в этом ответе, так это того факта, что вы все еще можете делать обходные пути в стиле C, используя goto case "some String".
НХ.

3
Я никогда не осознавал этого. Я всегда думал, что в VB отсутствует функция обработки падений, которая есть в C ++. Теперь я обнаружил, что в C # его тоже нет, и чтобы добавить оскорбление к травме, вы должны набрать оператор break. Это даже не будет автоматически заполнять это.
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
Кто-нибудь может объяснить, почему это? Я чувствую, что существуют законные сценарии использования для выполнения кода, и контроль над ним продолжается до следующего случая.
ЯшарБахман

9
@YasharBahman, я думаю, что в языках, где поддерживается переход к случаю, ошибок гораздо больше, чем предполагалось, в случаях. В C # язык позволяет вам goto case "SearchBooks";делать то, что вам нужно, не теряя при этом выразительности и не добавляя неожиданных ошибок.
agent-j

2
@ agent-j, я вижу. Спасибо, это имеет большой смысл. Кроме того, я не знал, что ты можешь использовать Goto таким образом, это действительно круто! (хотя, я думаю, я всегда буду устал от его использования, так как мои профессора убедили меня, что я самопроизвольно сожгу, если я это сделаю)
YasharBahman

2
Почему этот не принятый ответ? Он рассказывает больше о том, какие варианты у вас есть для оператора switch, а также дает ответ на вопрос.
Программист 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 Вы можете использовать операторы go to case, чтобы повторить то же самое.
itsme.cvk

4

В конце каждого случая переключения просто добавьте оператор break, чтобы решить эту проблему следующим образом:

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

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

            }

4

Поскольку это не упоминалось в других ответах, я хотел бы добавить, что если вы хотите, чтобы SearchAuthors дел выполнялся сразу после первого случая, точно так же, как и в случае пропуска "break" в некоторых других языках программирования. где это разрешено, вы можете просто использовать «Перейти».

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

Вы пропустили операторы break. Не забудьте ввести оператор break даже в случае по умолчанию.

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
Вы имели в виду "согласный"?
Максимюк

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.