为什么不强制显式转换而不是显式中断switch语句?

时间:2011-08-09 00:41:26

标签: c# switch-statement defaults fall-through

这不是一个特别的C#问题,但它是switch的C#版本让我提出这个问题。

为什么我必须明确说明我不希望从一个case语句落到下一个case语句而不是指示我何时想要通过?

在C#中,编译器不会让你从一个case语句转到下一个语句(除非break语句为空)但它会强制你显式{{1}在每个人的最后。我写的绝大多数switch陈述都没有落空。

int x = 4;
string result;

switch (x)
{
case 1:
   result = "One";
   break;
case 2:
   result = "A couple";
   break;
case 3:
case 4:
   result = "Three or four";
   break;
/*
case 5:
   result = "Five";   // Here be an error! A common typo for me!!!
*/
default:
   result = "Five or more";
   break;
}

上述例子旨在表明可能性。实际落入的次数(如上面的3到4之间)是最小的。如果我删除上面案例5中的注释,C#编译器会将其作为错误捕获。如果编译器完全知道我想要做什么,为什么我必须手动修复它?

以下情况不会更好吗?

int x = 4;
string result;

switch (x)
{
case 1:
   result = "One";
case 2:
   result = "A couple";
case 3:
   continue;   // or even goto 4
case 4:
   result = "Three or four";
/*
case 5:
   result = "Five";   // This would not longer be an error!! Hooray!
*/
default:
   result = "Five or more";
}

让我明确一点,我不是在提倡堕落。每个break语句末尾都有一个隐含的case。这两个例子在功能上是等价的。

如果我忘记了案例3中的continue语句,编译器仍然会对我大喊大叫。这种情况不会经常发生,我很乐意帮助。实际上,在这种情况下,我错过了填充框架代码的可能性非常高。有用。告诉我,我忘记了break声明从来没有帮助。保持编译器满意是一件非常繁忙的工作。

看起来这可能只是来自C的延续(即使你在case语句中有代码,它也可以让你失败)。我没有看到更深层次的原因吗?

我今天早上正在查看一些编译器代码,case中有数百个switch语句除了返回操作码之外什么也没做。他们每个人都有break陈述。这么多打字和杂乱......

人们怎么想?为什么第二个选项不是更好的默认值?

3 个答案:

答案 0 :(得分:6)

C#switch语句的基本原理是C的行为是,除非您明确退出breakreturngoto之类的语句,否则案例将会失效。这意味着每个熟悉C(可能是大多数C#程序员)的人都希望C#switch语法的含义大致相同。如果C#设计人员使案例失败,那么代码将完全符合用户期望的

另一方面,它是人们在案件结束时忘记break陈述并且控制权落在不应该的地方的常见错误来源。一个不太常见的问题是,人们会重新排序这些案例,使得过去(不需要break)的案例不再在最后(并且意外地掉落)。

换句话说,使的案例失败会导致那些期望它失败的人的错误,但不要求明确终止案件会导致忘记放置的人的错误在break中。因此,案件无法通过,但仍需要break

答案 1 :(得分:1)

当发生类似这样的事情(替换ifs)时,

switch语句真的很闪耀

switch (my_var) {
    case 1:
    case 2:
    case 3:
    case 4:
        do_something();
        break;
    case 5:
    case 6:
    case 7:
    case 8:
        do_something else();
        break;
}

这会大量替换嵌套的ifs或带有ands的巨大if语句。

另一个主要原因是它从C中被带回来.Case语句看起来几乎就像编译器为它们生成的程序集(在某些情况下)。不太确定他们为什么一开始就采用这种设计,但我真的没有看到任何问题,因为相同数量的if也可能看起来混乱(但并非总是如此)。

C#可能会看到丢失的中断是一个错误(常见的错误),可能这就是标记它的原因。它通常只用最后一个进入默认语句并且默认语句本身必须有一个中断(因为你始终可以将默认值放在开头)。在这种意义上,C#试图严格,以避免一些简单的错误,这些错误可能是由于在每个案例(或某些案例)结尾处忘记键入break而导致执行失败。

答案 2 :(得分:0)

C和C ++具有隐式性能的原因是向后兼容依赖它的大量代码,即使很少。

C#没有隐式转换的原因是它在大多数情况下都是一个错误。 C#没有隐式中断的原因是它对C,C ++和Java程序员来说是一个惊喜。它甚至不会产生警告?无声的意外失败非常糟糕。

要求行为是明确的是最安全的选择,那就是C#采取的路线。 (我希望C ++能够为翻译创建一个明确的语法,以便编译器可以警告隐式的直通)