【问题标题】:Is there a way to make my switch/case fall through to the next case in C#?有没有办法让我的开关/案例落入 C# 中的下一个案例?
【发布时间】:2011-11-09 21:04:40
【问题描述】:

我正在使用 switch/case 语句来处理已部署应用程序的一些更新。基本上,我想通过案例来执行从当前运行版本到最新版本的更新。

从对我大喊大叫的 Visual Studio 中,我了解到 C# 不允许陷入下一个案例(这正是我想要做的)。从this question,我学会了如何做我想做的事。但是,它显然仍然是一个错误。

我得到的是

switch (myCurrentVersion)
{
    case null:
    case "":
    case "0":
        UpdateToV1();
        goto case "1";
    case "1":
        UpdateToV2();
}

我在case "1": 行收到以下错误:

错误 1 ​​控件不能从一个案例标签('案例“1”:')转移到另一个

我做错了吗?我怎样才能强迫它通过?

【问题讨论】:

    标签: c# switch-statement


    【解决方案1】:

    即使是最后一种情况,您也需要添加break 语句:

    switch (myCurrentVersion)
    {
        case null:
        case "":
        case "0":
            UpdateToV1();
            goto case "1";
        case "1":
            UpdateToV2();
            break;
    }
    

    【讨论】:

      【解决方案2】:

      这是一个很好的例子,说明措辞不当的错误消息如何造成混乱。这里实际上违反的 C# 规则不是控制从一个开关部分落到另一个开关部分;而是就是每个开关段的终点一定不能到达。正确地说,错误应该类似于

      案例“1”的开关部分的端点不能到达;考虑添加'break;'

      当我们重新审视 Roslyn 项目的 switch 语句的语义分析时,我会看看我们是否可以稍微改变一下措辞以更清楚。

      有关此问题及相关问题的更多分析,请参阅my article on the subject

      【讨论】:

      • 好吧,我不得不问,因为你在这里,我一直想知道;为什么break 不是隐含的?不允许掉线,为什么要我一遍又一遍地写break?如果通过某个关键字明确地允许通过被允许,我会喜欢它,但除此之外,为什么不节省我一点打字时间呢?在这种情况下,您还需要明确允许空案例块的失败,但这似乎不太常见。
      • @EdS.:假设我们将 break 设为可选。 然后,具有 C 背景的人会编写期望失败的程序。 但事实并非如此,编译器也不会告诉他们其他情况。使其成为可选项使该语言具有“陷阱”。我们正在努力使 C# 中的“陷阱”计数保持在较低水平。此外,我们要求您一遍又一遍地写“break”。您可以改为写“throw”或“return”或“goto”或“while(true) {}”——就编译器而言,其中任何一个都与中断一样好。
      • @EdS.:顺便说一下,我经常被问到“编译器可以推断出我的意思是这个东西,那么为什么它不是可选的?”形式的问题。每一个都是一个判断电话;对于何时适当省略,没有硬性规定。举一两个例子,见stackoverflow.com/questions/2631975/…stackoverflow.com/questions/6092670/…
      • 当然,这几乎就是我的想法(即,使其尽可能与 C 语义相似)。我知道这总是一个判断电话这样的事情。是的,我知道您可以使用其他可以防止失败的语句,我只是对这个案例感兴趣。好的,谢谢你的回答。
      • 如果您想最大程度地减少陷阱,允许失败会更合适。这就是具有 C 背景的人所期望的。
      【解决方案3】:

      您的case "1" 分支中没有break

      【讨论】:

        【解决方案4】:

        UpdateToV2(); 之后放一个break;

        你能摆脱goto case "1"吗,因为它无论如何都会落到那个地步?

        【讨论】:

        • 不,C# 不允许这样做。我认为这是因为大量省略的break;s 是偶然的,他们试图防止人们搞砸(尽管我真的认为警告比错误更合适)。
        • @Jim:是的,我认为break 应该是隐含的,并且允许通过显式使用某些关键字。
        • @Ed S. 需要显式 goto 的原因是重新排序案例不会改变代码的含义。
        • @phoog:嗯,是的,正如它所设计的那样。我是说 no-fallthrough 应该是 implicit,也就是说,我不必一遍又一遍地写 break,它就是这样工作的。如果我想要失败,那么我将需要使用一些关键字来允许它。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 2011-10-12
        • 1970-01-01
        相关资源
        最近更新 更多