【问题标题】:Control cannot fall through from one case label控制不能从一个案例标签中消失
【发布时间】:2021-01-24 04:42:39
【问题描述】:

我正在尝试编写一个 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":) 转移到另一个

【问题讨论】:

  • 我刚刚意识到,如果我们不必将break; 放入其中,switch 语句的外观会好得多。这是过去的可怕神器。
  • @Simon_Weaver 有时您确实想将几个案例项目分组并以相同的方式对待它们!在这些情况下,跌倒是非常好的。
  • @stackoverblaze 绝对是,但这是一种特殊情况,编译器可以足够聪明地弄清楚。无论哪种方式,我们都坚持下去!

标签: c# switch-statement


【解决方案1】:

你错过了一些休息时间:

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": 下的行执行后立即执行case "SearchAuthors": 下的行,这在 C# 中是不允许的。

通过在每个案例的末尾添加break 语句,程序在完成后退出每个案例,无论searchType 的值是什么。

【讨论】:

  • 对我来说,我坐在那里看着这段代码和我自己的代码,直到我终于意识到我实际上错过了最后一个案例的中断,对于任何认为有帮助的人。
  • 如果我的解决方案不需要break,因为它需要在某些情况下失败怎么办?!
  • 哇,C# 开发人员到底在想什么?!它适用于我知道的所有编程语言,但不适用于 C#。
  • 这个答案缺少的一件事是您仍然可以使用 goto case "some String" 进行 C 风格的失败。
  • C# 以正确的方式做到这一点。 C# 开发人员是天才。其他语言(如 C++)使用的失败机制是一个错误。 C# 对通过“goto case”显式失败的要求更安全、更强大、更清晰。您不仅可以实现“失败”行为,还可以明确地“明确地陷入任何情况”。失败在其他语言中是一个懒惰的笑话。 C# 旨在修复旧语言的所有这些奇怪且容易出错的怪癖。
【解决方案2】:

您需要在每个案例标签中使用break;throwgotoreturn。在一个循环中你也可以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;

【讨论】:

  • continue 也是可能的
  • 谁能解释-为什么-这是?我觉得有一些合法的用例可以执行代码并让控制权继续落入下一个案例。
  • @YasharBahman,我认为在支持 case fall-through 的语言中存在比预期案例更多的错误。在 C# 中,该语言允许您goto case "SearchBooks";,因此您可以做您需要做的事情,而不会失去太多表现力或添加意想不到的错误。
  • @agent-j 我明白了。谢谢,这很有意义。另外,我不知道你可以这样使用 goto,这真的很酷! (虽然,我想我总是会厌倦使用它,因为我的教授已经说服我,如果我这样做,我会自燃)
  • 为什么这个不是公认的答案?它详细说明了您对 switch 语句有哪些选项以及给出问题的答案。
【解决方案3】:

您可以做的不仅仅是在 C# 中失败,但您必须使用“可怕的”goto 语句。例如:

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

【讨论】:

  • 这似乎是最通用的解决方案。为什么你会称 goto 为“可怕的”?
  • 谢谢,当默认值在中间并且您想进入下一个案例时,这有效...
  • @shoopi 因为它经常实现不好,纠结控制结构。
【解决方案4】:

你需要添加一个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;
}

这假设您想要处理 SearchBooks 的情况 SearchAuthors - 正如您所写的那样,在传统的 C 风格 switch 语句中,控制流将“失败” through" 从一个 case 语句到下一个语句,这意味着所有 4 行代码都在 searchType == "SearchBooks" 的情况下执行。

引入您看到的编译器错误(至少部分地)是为了警告程序员此潜在错误。

作为替代方案,您可以抛出错误或从方法返回。

【讨论】:

  • 有没有办法在这里复制类似 C 的开关?在一个 switch 中运行一些代码,然后切换到另一个可以为所有人运行的代码?
  • @JohnDemetriou 您可以使用 go to case 语句来复制相同的内容。
【解决方案5】:

在每个 switch case 的末尾,只需添加 break-statement 即可解决此问题

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

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

【讨论】:

    【解决方案6】:

    你错过了 break 语句。即使在 default 的情况下,也不要忘记使用 break-statements。

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

    【讨论】:

      【解决方案7】:

      由于其他答案中没有提到它,我想补充一点,如果您希望在第一种情况之后立即执行 case SearchAuthors,就像在其他一些编程语言中省略 break是允许的,你可以简单地使用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;
      }
      

      【讨论】:

        【解决方案8】:
        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.我认为您的意思是“元音”与“字母”。 2. 您可能希望将switch (ch) 更改为以下内容。 char vowelCheckChar = ( (Char.ToLower(ch) == 'y') ? ( ((new Random()).Next(2) == 0) ? ch : 'a' ) : ch ); // char vowelCheckChar = switch (vowelCheckChar) 对不起,不得不。 ;)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多