在VB.NET中,为什么我应该使用Select而不是If?

3
我最近毕业并开始一份真正的工作。在我们的培训中,他们向我们介绍了VB.NET和这里使用的许多功能。在一些示例中,他们使用了Select语句(在一些地方,应该使用If/Else语句)。除了需要它的任务外,在其他语言中我只在希望执行下一个语句时使用过switch/select语句。
考虑到VB.NET没有fall through,是否有任何情况可以使用Select语句?是否有任何情况下它比If/ElseIf语句更优?
5个回答

10

Select Case,而不是仅用 Select
对我来说,这是该语言最好的功能之一。

  1. 当你有多个可能的值需要测试时,这种方式更加直观。

select case some_var
case 1
  something()
case 2
  something_else()
case 3
  etc()
end select
  • 在测试范围时,它更易于阅读:

    select case some_var
    case 1 to 10
      something()
    case 20 to 30
      something_else()
    case is > 100
      etc()
    end select
    
  • 当你需要测试一堆更复杂的条件来确保只有一个被选定时,这种方式更易读:

    select case true
    case string.isnullorempty(a_string)
      something()
    case a_string.length < 5
      something_else()
    case a_string = b_string
      etc()
    end select
    
  • 相比于C/C++中的switch语句,它允许使用表达式作为分支点,而不仅仅是常量。

  • 当将常量作为分支点(例如示例1)时,编译器能够生成更加优化的直接跳转代码。


  • 2
    我完全不知道你可以测试范围,并且有很多好的理由使用Select Case - Wayne Werner

    6
    Select 告诉编译器在一组If/Else块中的每个比较(If)都是基于相同的值,这使得它能够进行某些更难确定的优化。例如,它可能更愿意生成将该值保存在CPU寄存器中的机器代码(这只是假设...不同的编译器可以自行决定)。此外,有些人发现Select更易读。重要的是遵循您所在的团队或单位的编码标准。

    4

    首先,VB确实有“fall through”,只是不太明显。在VB中,“fall through”只是将一个case设置为具有多个值:

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

    就其优点而言,编写一个Select语句比编写三个以上针对相同值的If/ElseIf语句要简单得多。


    1
    现在它不会掉落了,对吧?大部分都覆盖了,但功能还是不同。 - dr. evil
    1
    @wayne 这就是重点。VB中选择不同的原因是为了防止开发人员意外忘记打破它。在我看来,fallthrough基本上总是无意的,或者如果不是,99%的时间你可以做一些比滥用fallthrough更好的事情。在VB中,如果需要,您可以指定您的fallthrough,并且没有办法无意中创建它(除非您搞砸了您的范围 :))。 - Jason
    1
    @wayne,这就是我所指的,但显然C#不允许这样做,因此Jason是正确的,这与C#的fallthrough没有区别,而VB.NET的语法要优雅得多。 - dr. evil
    如果一个C或C++程序员连续放置两个case语句,然后跟着一段代码块,那么他们希望这段代码能够被执行。但是,如果他放置了一个case语句、一些代码、没有break、另一个case语句和更多的代码,那么在我看来,这段代码现在变得晦涩难懂。这种fall-thru是有意为之的吗?在第一种情况下,两个代码块都应该被执行,但在第二种情况下只有一个?还是他只是忘记了break?我想你可以加入注释来澄清,但通常程序员不会这样做,读者就会感到困惑。因此,我认为这是不好的编码风格。在我看来... - Jay
    VB语法使用逗号分隔多个值的方式更优。当多个值需要执行相同的代码时,这种方式清晰易读。如果你真的有一个情况,在值为1时想要执行X和Y,在2时只想执行Y,那么将它们放入子程序中并编写正确的调用,你的代码就会变得清晰明了。 - Jay
    显示剩余2条评论

    1

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

    VB.NET的Select语句也有一些很酷的功能,所以确保你知道所有的功能。


    使用“落入”(fall through)来实现疯狂的 switch 操作(我指的不仅仅是支持多个值,这是很正常的)。 - dr. evil
    2
    C#不允许除了指定多个值之外的case分支穿透。如果您想转到另一个case分支,必须手动使用goto case命令跳转。 - Matti Virkkunen
    该死!你说得对,我一直以为它像C++一样,我的错,已经更新了帖子。现在他们移除了这个荒谬的功能,我对C#印象非常好 :) - dr. evil

    0

    在编程中,有一种情况下使用 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或执行最便宜的测试的顺序来帮助优化代码(取决于应用程序)。


    1
    你也可以将 Or 更改为 OrElse,以实现与 If/Else 相同的行为。不过,对于你清晰地解释一切的努力,我给你点赞。 - Victor Zakharov

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接