为什么需要在switch语句的最后一个标签之后放置?

时间:2010-08-11 04:07:57

标签: c# switch-statement

当然编译器知道它是switch语句的最后一个标签?

9 个答案:

答案 0 :(得分:7)

这是因为在C ++中会发生这种情况:

switch(a)
{
     case 1:
        // do stuff

     case 2:
        // do other stuff
}

如果a为1,那么 - 根据C ++规则 - “做东西”“做其他事情”会发生。因此,进入C#的C ++程序员不会被绊倒(并且为了使代码更清晰),C#要求您明确指定是要break还是要通过不同的标签。

现在,至于为什么你需要 last 块上的break,这是一个简单的一致性问题。它还使重新分解更容易:如果你移动案例,你不会因为缺少break语句而突然出现错误。此外,当您想要添加其他标签等时会发生什么。

答案 1 :(得分:6)

切换后的最终案例陈述是好的defensive programming。如果将来可能会在下面添加另一个案例陈述,则可以消除程序流程从上述案例中落下的风险。

答案 2 :(得分:3)

一致性。与使用大括号的对象实例化语句中的最后一个枚举定义或最后一个赋值之后能够使用逗号的原因相同。最后一种情况可能并不总是最后一种情况。

它也使得特殊情况更少。

如果是这种情况,那么学习,写作或阅读会更容易。虽然这增加了一致性。

答案 3 :(得分:2)

C# switch statements中,您必须明确声明要破坏或转到其他案例或转到默认值。

在C和C ++中,switch语句没有中断标记。让用户明确说出他们想要做什么在C#中很重要,以避免错误。例如,很多用户从C ++来到C#。


关于你要问的最后一个案例陈述。我可以想出3个很好的理由。

  1. 保持任何语言的一致性非常重要。
  2. 如果您稍后追加另一个案例,默认情况下该怎么办?
  3. 为什么要打破默认?为什么不转到?这里含糊不清。

答案 4 :(得分:2)

根据http://msdn.microsoft.com/en-us/library/06tc147t.aspx

  

你不能“摔倒”任何开关部分,包括最后一部分。

可以通过以下任何方式避免掉头:break,goto或return。

答案 5 :(得分:2)

实际上有一种情况你不需要休息

考虑以下代码:

using System;

public class Program
{
    public static void DoStuff()
    {
    }

    public static void DoAnotherStuff()
    {
    }

    public static void Main()
    {
        switch(1)
        {
            case 1: DoStuff(); break;
            default: DoAnotherStuff();
        }
    }
}

使用C#4.0编译器,它只为您提供了一个很好的CS0162:无法访问的代码警告

看来,由于switch有一个常量表达式,编译器已经知道它将要执行的路径,然后只是忽略了dafault标签。

很酷的是,如果你将switch(1)更改为switch(2),它就不再编译,因为默认标签没有中断。

修改C# Reference

  

C#中的要求是每个交换机部分的末尾,包括最后一个,都无法访问。尽管通常使用跳转语句满足此要求,但以下情况也是有效的,因为无法到达语句列表的末尾。

case 4:
    while (true)
        Console.WriteLine("Endless looping. . . .");

这解释了为什么默认不需要休息。实际上,任何不可缓存的标签都不需要中断,也不需要返回也不需要goto

答案 6 :(得分:1)

使用switch时,break不是唯一的选择。您还可以选择转到另一个案例,转到默认案例,转到另一个标签或返回。也可以有多个具有单个实现主体的案例。由于最多有五个选项,并且能够为一个实现提供多个案例,因此编译器无法简单地输入“正确”的答案。

你必须选择你想做的事情。它确保编译器做正确的事情,使你的代码更清晰,并且使得更难以做愚蠢的程序员事情,比如在“最后一个”之后添加另一个案例,并且忘记放入break / goto / return。

答案 7 :(得分:0)

根据Eric Lippert的this blog post(案例2),它允许您能够随意重新订购开关部分,而不会意外地引入重大变化:

  

[编译器]需要每个开关部分,   包括最后一个,有一个   无法到达的终点。的目的   这条规则,以及不可堕落的规则   一般来说,是我们想要你的   能够任意重新订购   你的开关部分没有   不小心引入了破门   变化

答案 8 :(得分:0)

如前所述,您可以使用默认值:,但也可以考虑使用null。 case null:需要休息一下;

案例null: iEvaluatedToNothing(); 打破;

如果你想“瀑布”,你可以做这样的事情;

switch (deliverMail)
{
    case null:
    case "":
    case "Address0":
        deliverMail0();
        goto case "1";
    case "1":
        deliverMail1();
        break;
}

您可以根据需要使用此处,但最后一次评估需要一个。