【问题标题】:In VB.NET why should I use Select, instead of If?在 VB.NET 中,为什么我应该使用 Select 而不是 If?
【发布时间】:2011-06-30 19:42:37
【问题描述】:

我最近毕业并开始了一份真正的工作。在我们的培训中,他们向我们展示了 VB.NET 以及他们在这里使用的许多功能。在一些示例中,他们使用了 Select 语句(在一些地方使用了 If/Else 确实应该使用的地方)。

我唯一一次在其他语言中使用 switch/select 语句(除了需要它的赋值)是当我想要下一个语句时。

鉴于 VB.NET 没有失败,有哪些情况(如果有)可以使用 Select 语句?是否有任何情况下它提供优于 If/ElseIf 声明的优势?

【问题讨论】:

    标签: vb.net select if-statement language-features


    【解决方案1】:

    Select Case,不仅仅是Select
    对我来说,这是该语言的最佳特性之一。

    1. 当您有几个可能的值要测试时,它会更加直观。

      select case some_var
      case 1
        something()
      case 2
        something_else()
      case 3
        etc()
      end select
      
    2. 在测试范围方面更具可读性:

      select case some_var
      case 1 to 10
        something()
      case 20 to 30
        something_else()
      case is > 100
        etc()
      end select
      
    3. 当您有一堆更复杂的条件要测试时,它更具可读性,确保只选择一个:

      select case true
      case string.isnullorempty(a_string)
        something()
      case a_string.length < 5
        something_else()
      case a_string = b_string
        etc()
      end select
      
    4. 它优于 C/C++ switch,因为它允许表达式作为分支点,而不仅仅是常量。

    5. 当使用常量作为分支点(示例 1)时,编译器能够通过直接跳转生成更优化的代码。

    【讨论】:

    • 我完全不知道你可以测试范围,还有很多 Select Case 的好论据
    【解决方案2】:

    Select 告诉编译器在类似的 If/Else 块集中的每个比较 (If) 都在相同的值上,这允许它进行某些更难以确定的优化。例如,它可能更渴望生成在 cpu 寄存器中保存该值的机器代码(这只是假设......不同的编译器可以做他们想做的事)。

    此外,我们中的一些人发现Select 更具可读性。遵循您发现自己的任何团队或单位的编码标准非常重要。

    【讨论】:

      【解决方案3】:

      首先,VB 确实失败了,只是没那么明显。 VB 中的“失败”只是将一种情况设置为具有多个值:

      Dim number As Integer = 8
      Select Case number
          Case 6,7,8
              ' do stuff
          Case Else
              ' do default stuff
      End Select
      

      至于它的优点,写一个Select 语句比写三个以上的If/ElseIf 语句要容易得多,它们都针对相同的值进行测试。

      【讨论】:

      • 现在不会失败吧?它涵盖了大部分内容,但功能仍然不同。
      • @dr.邪恶 - 出于所有意图和目的,它是失败的。它更像是一个安全网,而不是跌倒。基本上,您不会像在 C# 中那样通过忘记break; 来无意中创建失败
      • 我不知道我是否会考虑真正的失败,因为在说 - C++ 你可以在一个案例上运行一些操作 - 可能会消耗一些东西。我看到的最好的例子是从整数转换为罗马数字,但现在找不到链接。
      • @wayne 这就是重点。他们在 VB 中选择不同的原因是为了防止开发人员意外忘记破坏它。在我看来,失败基本上总是无意的,或者如果不是,99% 的时间你可以做一些比滥用失败更好的事情。在 VB 中,如果需要,你可以指定你的失败,并且没有办法无意中创建它(除非你搞砸了你的范围:)
      • @wayne 这就是我所指的,但显然 C# 无论如何都不允许这样做,所以 Jason 是对的,这与 C# 的失败完全一样,而 VB.NET 的语法更加优雅。
      【解决方案4】:

      如果您要根据输入比较/范围比较做几件不同的事情,如果它是 if-elseif+,那么使用 Select 而不是疯狂的 if-elseif 块。

      VB.NET 的 Select 语句也有一些很酷的特性,因此请确保您了解所有特性。

      【讨论】:

      • 使用 fall through 来做疯狂的 switch 事情(我不是指只支持多个值,这是正常的)
      • evil:除了指定多个值外,C# 不允许大小写失败。如果你想去另一个案例,你必须手动goto case进入它。
      • 该死!你说得对,我一直认为它就像 C++,我的错,更新了帖子。我对 C# 印象深刻,因为他们删除了这个荒谬的功能 :)
      【解决方案5】:

      在某些情况下,Select Case 可能比 If 更有效:当您在 If 条件中有一个“或”子句列表并且您不需要全部评估它们来确定条件的真实性时。假设你有一个这样的 if 语句:

      If A() Or B() Then
          DoSomething()
      ElseIF C() or D() Then
          DoSomethingElse()
      Else
          DoTheDefault()
      EndIF
      

      在这种情况下,为了评估第一个 if 语句,函数 A() 和 B() 都被执行,同样地,当 A() 和 B() 都为 false 时,对于第二个 if 语句。如果 A() 返回 true,则 B() 的值无关紧要,除非它以您真正想要的方式更改程序状态(通常不是好的做法),否则 B() 的执行是多余的。编译器受到以下要求的约束:必须在得出一个值之前执行测试的所有部分(根据语言规范,不允许优化测试)。

      您可以将条件分成多个 IfElse 语句以自行优化,但这会降低代码的可读性,并增加稍后进行更改时出错的风险。我发现在这种情况下使用 Select Case 更好:

      Select Case True
          Case A(), B()
              DoSomething()
          Case C(), D()
              DoSomethingElse()
          Case Else
              DoTheDefault()
      End Select
      

      现在,如果 A() 返回 True,则根本不计算 B()。条件的评估按列出的顺序进行,因此您可以通过将测试按最有可能返回 True 或执行成本最低的顺序排列(取决于应用程序)来帮助优化代码。

      【讨论】:

      • 您也可以将Or 更改为OrElse 以实现与If/Else 相同的行为。不过,+1 表示您努力解释清楚一切。
      猜你喜欢
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 2014-03-12
      • 2012-12-13
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多