4

这不是专门的 C# 问题,而是 C# 版本switch让我问这个问题。

为什么我必须明确声明我不想从一个case语句掉到下一个语句,而不是表明我什么时候想通过?

在 C# 中,编译器不会让您从一个case语句跳到下一个语句(除非该case语句为空),但它会强制您break在每个语句的末尾放置一个显式语句。我写的绝大多数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这两个示例在功能上是等效的。

如果我忘记了continue案例 3​​ 中的语句,编译器仍然可能对我大喊大叫。不过这种情况不会经常发生,我很乐意得到帮助。事实上,在这种情况下,我错过填写骨架代码的可能性非常高。有用。告诉我我忘记了一个break声明是没有帮助的。让编译器满意只是更忙的工作。

看起来这可能只是 C 的保留(即使您在 case 语句中有代码,它也确实允许您失败)。有没有我看不到的更深层次的原因?

今天早上我正在查看一些编译器代码,其中有数百条case语句switch除了返回操作码之外什么都不做。他们每个人都发表了break声明。这么多的打字和混乱......

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

4

3 回答 3

6

C# 语句的基本原理switch是 C 的行为是,除非您使用 、 或 之类的语句显式退出,否则案例会break失败。这意味着熟悉 C 的每个人(可能是大多数 C# 程序员)都会期望 C#语法具有大致相同的含义。如果 C# 设计者没有让案例失败,那么代码将与用户期望的完全相反!returngotoswitch

另一方面,人们break在案例结束时忘记声明并控制不应该出现的地方是错误的常见来源。一个不太常见的问题是,人们会重新排序案例,以使曾经位于末尾(并且不需要 a break)的案例不再位于末尾(并且意外失败)。

换句话说,使案例失败会导致期望它失败的人的错误,但不要求明确终止案例会导致忘记放入break. 因此,案例不能通过,但break仍然需要 a。

于 2011-08-09T01:25:21.803 回答
1

switch 语句在发生这样的事情时真的很出色(替换 ifs)

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

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

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

C# 可能将丢失的中断视为错误(常见错误),这可能是标记它的原因。它通常只对最后一个进入默认语句的语句执行此操作,并且默认语句本身必须有一个中断(因为您始终可以将默认值放在开头)。C# 试图在这个意义上变得严格,以避免一些简单的错误,这些错误可能是由于忘记在每个案例(或某些案例)结束时键入 break 并让它通过执行而导致的。

于 2011-08-09T00:46:15.397 回答
0

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

C# 没有隐式失败的原因是它在大多数情况下是一个错误。C# 没有隐式中断的原因是它会让 C、C++ 和 Java 程序员感到惊讶。它甚至不会产生警告?无声的意外失败是非常糟糕的。

要求明确的行为是最安全的选择,这就是 C# 采用的路线。(而且我希望 C++ 会开发一种显式的直通语法,以便编译器可以警告隐式直通)

于 2011-08-09T01:33:30.117 回答