15

我刚开始自学 C#,在关于 Switch 语句的教程中,我读到:

禁止执行流程从一个 case 块流向下一个 case 块的行为是 C# 与 C++ 不同的一个领域。在 C++ 中,case 语句的处理可以从一个运行到另一个。

为什么它在 C# 中的一个 case 语句之后停止?如果您可以break在任何时候使用该语句停止,那么在 C# 与 C++ 中是否有任何理由让它在找到匹配项后停止?如果你想在 C# 中使用多个 case,你是否必须使用另一个 Switch 语句?

4

5 回答 5

16

C# 具有goto casevalue,它具有 fallthrough 的所有好处,但更难意外实现。

MSDN 上的示例

于 2012-11-05T20:34:53.070 回答
16

从技术上讲,这是不正确的:当主体case为空时,C# 确实允许穿透:

switch(val) {
case 1:
case 2:
    Console.WriteLine("small");
    break;
case 3:
case 4:
case 5:
case 6:
case 7:
    Console.WriteLine("medium");
    break;

 default:
    Console.WriteLine("large");
    break;
}

在 C/C++ 中的非空主体之后允许隐式失败往往是错误的。这就是 C# 的设计者决定不允许它使用的原因。

于 2012-11-05T20:36:40.817 回答
4

我认为争论的焦点是 C++ 中的 switch 语句通常导致的问题多于解决的问题。即当他们不是程序员的意图时失败了,他们只是忘记了break. 所以 C# 取消了它。

与 C++ 中的许多其他“功能”相同。并不是说它们偶尔没有用,只是它们更多时候是有害的。就像将任何东西评估为布尔值一样,所以在 C# 中你不能这样做:

if(1) 
{

}

因为将整数评估为布尔值会导致很多难以发现的错误。

于 2012-11-05T20:35:32.133 回答
1

C# 的版本更不容易出错——如果你忘记写 a break,什么都不会在你的脸上爆炸,这会发生。它看起来也更好一些。再说一次,无论如何,在大多数情况下都没有什么理由使用 switch 语句(通常它最终只是类型调度的糟糕实现,它通过类继承在两种语言中都内置)。

于 2012-11-05T20:36:23.537 回答
0

这可能完全属于反模式领域,但如果你真的想要失败行为,这可能应该接近与跳转表相同

using System;

namespace MyApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      int day = 4;
      switch (day) {
        case 1: goto d1;
        case 2: goto d2;
        case 3: goto d3;
        case 4: goto d4;
        case 5: goto d5;
        case 6: goto d6;
        case 7: goto d7;
      }    
      d1: Console.WriteLine("Monday");
      d2: Console.WriteLine("Tuesday");
      d3: Console.WriteLine("Wednesday");
      d4: Console.WriteLine("Thursday");
      d5: Console.WriteLine("Friday");
      d6: Console.WriteLine("Saturday");
      d7: Console.WriteLine("Sunday");
    }
  }
}
于 2021-10-01T16:29:17.403 回答