【问题标题】:c# switch statement more limited than vb.net 'case' [closed]c# switch 语句比 vb.net 'case' 更受限制 [关闭]
【发布时间】:2011-08-18 23:13:57
【问题描述】:

我正在阅读一篇有趣的文章 here,它对 vb.net 中的“case”语句与 C# 中的“switch”语句提出了一个有趣的观点,我将其粘贴在下面:

以下 Visual Basic Select Case 语句不能在 C# 中用单个 switch 语句表示:

Dim Condition As Integer = 55
Select Case Condition
  Case 1, 3 To 5, 10, 12, 14, Is > 50
    'value 55 executes code here
  Case Else
    'values <1, 2, 6-9, 11, 13, 15-49
End Select

我一直发现 C# 中的 switch 语句,在每种情况下都带有 dropthrough 和 consequentrequirements for a break,有点笨拙。他们有什么理由没有增强 switch 命令来允许这些情况?无论如何,dropthrough什么时候有用?有人知道该构造的任何扩展以提供更大的灵活性吗?

干杯

【问题讨论】:

  • switch 结构在 C 方言语言中非常有限。这可以说是因为 switch(在一些小的值上,比如 0-255)可以 变成直接跳转并完全避免条件 - 再加上贯穿语义(C# 没有),它对(“ASCII”)字符处理等很有用。真正的问题是——为什么 C# 和 VB.NET 都不支持像 F#、Scala 或 Haskell 这样更通用(和更高级别)的 模式匹配 构造? :-)
  • 我很确定具有超过 7 个元素的 switch 语句(在 C# 中)实际上在编译时转换为字典(哈希表)。散列像“Is > 50”这样的谓词将是一个非常有趣的问题。
  • 我不明白接近投票。这是一个有效的问题。 VB.NET 比 C# 有更多功能是有历史原因的,也有一些原因不能以相同的效率在内部实现更强大的功能,但实际上没有什么能阻止编译器实现这种类型的功能,即使CLR 没有。很高兴听到编译器团队中的某个人或了解有关此问题的任何讨论的知识,以了解为什么这实际上没有实现。也许就像 C# 开发人员真的不关心这个功能一样简单。
  • @Samuel Neff - 我也会投票结束。这是一个讨论点,而不是一个问题。这很有趣,但(再次)这不是一个真正的问题

标签: c# vb.net language-design language-features


【解决方案1】:

在 C# 中,您只能在 case 中使用不同的值。这使得它更受限制,但另一方面它使它更快,因为它可以使用哈希查找来实现。

C# 中的 switch 语法比 C/C++ 中的限制更多。你仍然可以做同样的事情,但不会隐式地失败,你必须编写一个特定的跳转到下一个案例。这种限制的原因是,错误地失败比故意失败更常见。

在 C# 中,您需要在默认情况下使用 if 语句来处理范围:

int condition = 55;
switch (condition) {
  case 1:
  case 3:
  case 4:
  case 5:
  case 10:
  case 12:
  case 14:
    // values 1, 3-5, 10, 12, 14
    break;
  default:
    if (condition > 50) {
      // value 55 executes code here
    } else {
      // values <1, 2, 6-9, 11, 13, 15-49
    }
    break;
}

【讨论】:

  • 感谢您的来信。这对我来说确实是答案;我曾怀疑基于架构或性能的某些东西正在推动差异。当你提到失败不是隐含的,我认为需要休息意味着失败会隐含地发生?感谢您的来信。
【解决方案2】:

我记得一位大学讲师曾经告诉我们,他发现与跌倒有关的唯一有用的事情就是写下圣诞节十二天的歌词。

类似的东西

for (int i = 1; i <= 5; i++) {
    Console.WriteLine("On the " + i + " day of christmast my true love gave to me");
    switch (i) {
    case 5:
        Console.WriteLine("5 Gold Rings");
        goto case 4;
    case 4:
        Console.WriteLine("4 Colly Birds");
        goto case 3;
    case 3:
        Console.WriteLine("3 French Hens");
        goto case 2;
    case 2:
        Console.WriteLine("2 Turtle Doves");
        goto case 1;
    case 1:
        Console.WriteLine("And a Partridge in a Pear Tree");
        break;
    }
    Console.WriteLine("-");
}

10 年后,我倾向于同意他的观点。当时我们做的 java 确实失败了,不得不为 C# 伪造它。

【讨论】:

  • 大声笑,我同意。我想不出一个失败的逻辑情况是有用的,但是有很多类似的情况是真实的,其他人也有很好的例子。对我来说(在没有上述 goto 的情况下),如果你只能有不同的案例而不是范围/其他复杂的标准,你什么时候想触发多个?感谢您的来信!
  • 在状态机第一次运行一段代码之前必须发生一些特殊情况的状态机中,失效有时很有用。 FIRST_FOO 案例执行适当的初始化,将状态推进到 MORE_FOO,并使用显式注释掉到 MORE_FOO 代码,该代码处理第一次调用以及后续调用。
【解决方案3】:

匹配多个 case 的特殊情况允许忽略,但不允许比较和范围 case。所以:

int condition = 55;
switch (condition) {
  case 1: case 3: case 4: case 5: case 10: case 12: case 14:
    // value 55 doesn't execute here anymore

  default:
    //values <1, 2, 6-9, 11, 13, >14
}

【讨论】:

  • 谢谢。该示例确实说明了该构造的有限使用;上面关于它被编译器散列的观点很有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多