代码之家  ›  专栏  ›  技术社区  ›  Otávio Décio

选择Case True

  •  18
  • Otávio Décio  · 技术社区  · 15 年前

    显然,这曾经是VB6和VBA中短路并执行第一个真实情况的一种方式:

    Select Case True
    End Select
    

    这个还在使用吗(VB.NET)?

    9 回复  |  直到 9 年前
        1
  •  32
  •   Jean-François Corbett    9 年前

    此语法通常用于代替 If...ElseIf 陈述有些人觉得它更容易阅读。例如:

    Select Case True
        Case testVariable < 0
             Console.Write("You must supply a positive value.")
        Case testVariable > 10
             Console.Write("Please enter a number from 0-10.")
        Case True
             Call DoWork(testVariable)
    End Select
    

    答案是肯定的,这在VB.NET中仍然有效。使用它时要小心,因为它不是“标准编程结构”,将来需要维护代码的人可能不熟悉它。

        2
  •  15
  •   Patrick McDonald    15 年前

    我不确定这种结构与以下结构相比有何优势:

    If testVariable < 0 Then
         Console.Write("You must supply a positive value.")
    ElseIf testVariable > 10 Then
         Console.Write("Please enter a number less than 10.")
    Else
         Call DoWork(testVariable)
    End If
    

    上面的结构是短路的,我不必去想它是什么,因为它是一个标准结构。

        3
  •  12
  •   RolandTumble    15 年前

    其他人已经回答了这个实际问题,但我只是想插嘴,我相当频繁地使用这个结构。我认为这通常是同时测试两个布尔条件的最具可读性的方法:

    Dim A As Boolean
    Dim B As Boolean
    '
    'do stuff to set values of A and B
    '
    Select Case True
      Case A And B
        'something
      Case A And Not B
        'something else
      Case Not A And B
        'you get the picture
      Case Else
        '...
    End Select
    

    我承认,我发现它容易阅读的部分原因是我确实使用了它,而且我确实记得第一次看到它时必须解析它——但一旦成功解析,我的反应是“太棒了!”

        4
  •  10
  •   Oorang    15 年前

    在这个主题上有很多混淆,但要回答OPs问题:是的,逻辑计算在VB.Net中与在VB6中与在VBA中相同。 http://support.microsoft.com/kb/817250

    为了利用选择案例优化技术,您使用选择案例固有语法来避免使用逻辑运算符And、Or、Xor等。正是这些运算符具有短路评估功能。

    考虑这个例子:

    Public Sub Example()
        If A Or B Then
            Beep
        End If
        Select Case True
            Case A, B
                Beep
        End Select
    End Sub
    
    Private Function A() As Boolean
    Debug.Print "A Ran"
        A = True
    End Function
    
    Private Function B() As Boolean
    Debug.Print "B Ran"
        B = False
    End Function
    

    Select Case版本将仅运行A。If块将同时运行两者。这不是If语句的错误,而是And运算符的错误。如果愿意,可以将If语句构造为如下所示的短路:

    Public Sub Example2()
        If A Then
        ElseIf B Then
            Beep
        End If
    End Sub
    

    B将不会运行。这只是风格的问题。

    需要知道的重要一点是,您要避免的是And/Or/Xor运算符,而不是If块。如果您更喜欢If块的选择案例版本。。。给你更多的力量:)

        5
  •  4
  •   Victor Zakharov    9 年前

    Select Case a powerful operator by itself . 但即使 Select Case True 仍然支持,最好从可维护性的角度避免。你总是要证明你的需要是正当的。如果急需,您甚至可以使用 DoEvents GoTo . 对于公认的答案,可以这样写:

    Select Case testVariable
      Case Is < 0 : Console.Write("You must supply a non-negative value.")
      Case Is > 10 : Console.Write("Please enter a number from 0-10.")
      Case Else : Call DoWork(testVariable)
    End Select
    
        6
  •  3
  •   om252345    15 年前

    你是说像这样的事吗?

     Select Case True
        Case 1 = 0
            Console.Write("1")
        Case 1 = 1
            Console.Write("2")
        Case 2 = 2
            Console.Write("3")
    End Select
    

    其中,程序将编写2…如果这是您要问的,那么是的,这在VB.NET中仍然存在

        7
  •  2
  •   x77    9 年前

    您可以在任何包装器类型上定义Equals运算符。 然后,您可以在Select Case上使用包装器类型。

    样品包装。

    Imports System.Runtime.InteropServices
    <DebuggerStepThrough()> Friend Module Util
      Public Function _Is(v As Object) As IsWrapper
          Return New IsWrapper With {.Obj = v}
      End Function
      Public Structure IsWrapper
         Public Obj As Object
         Public Shared Operator =(ByVal a As IsWrapper, ByVal b As Object) As Boolean
             Return a.Obj Is b
         End Operator
         Public Shared Operator <>(ByVal a As IsWrapper, ByVal b As Object) As Boolean
             Return a.Obj IsNot b
         End Operator
      End Structure
    End Module
    

    Private Sub RbClass_CheckedChanged(sender As System.Object, e As System.EventArgs)
        If DirectCast(sender, RadioButton).Checked = False Then Return
        Select Case _Is(sender)
            Case RbClass : Rb = 0
            Case RbTablePredicate : Rb = 1
            Case RbTableRowFilter : Rb = 2
        End Select
        QueryCtl1_QueryChanged(Nothing, Nothing)
    End Sub
    
    Public Sub Predicate(ByVal PredicateType As Type, ByVal Op As Operadores, ByVal Obj As Object, ByVal CompareOptions As CompareOptions, ByVal Fnc As [Delegate])
       Dim pred As [Delegate] = Nothing
       Select Case _Is(PredicateType)
          Case GetType(Boolean)
              pred = New Predicate(Of Boolean)(Function(v) v)
          Case GetType(String)
              pred = StrPredicate(Op, Obj, CompareOptions)
          Case Else 'Utilizar Generics
              pred = GenericHelper.Builder(PredicateType).Predicate(Op, Obj)
       End Select
       Predicate(pred, Fnc)
    End Sub
    

    关于性能。

        8
  •  2
  •   Dennis Arkwright    7 年前

    使用构造SELECT CASE TRUE的另一个原因是当您的CASE语句计算为布尔值时。选择案例需要将所有案例评估为与控件相同的数据类型。如果您正在查看字符串数据类型,那么所有case语句也需要是字符串。

    SELECT CASE [string]
    CASE "String 1", "String 2"
        [do a thing]
    CASE "String 3"
        [do another thing]
    END SELECT
    

    但是,如果使用LIKE运算符比较部分字符串,则案例数据类型将变为布尔值,这与字符串控件不匹配。以下代码将不起作用:

    SELECT CASE [string]
    CASE LIKE "*1", "*2"
        [do a thing]
    CASE LIKE "*3"
        [do another thing]
    END SELECT
    

    为了使用通配符(因此具有布尔大小写结果),必须具有布尔控制值,因此结构需要:

    SELECT CASE TRUE
    CASE [string] LIKE "*1", "*2"
        [do a thing]
    CASE [string] LIKE "*3"
        [do another thing]
    END SELECT
    

    我想你可以用IF…ELSEIF

    IF [string] LIKE "*1" AND [string] LIKE "*2" THEN
        [do a thing]
    ELSEIF [string] LIKE "*3"
        [do another thing]
    END IF
    

    就我个人而言,当有三个以上的选项时,SELECT CASE更易于使用和阅读。当我必须评估两个或三个不同选项(>、=、<)或测试特定范围的“有效”条目的值时,我使用IF…ELSE和IF…ELSEIF。相反,如果条目具有更多的多样性,并且我需要确定十种可能性中的哪一种发生了,那么SELECT CASE是一种更容易使用的构造,因为它消除了对多个OR语句的需要。

        9
  •  1
  •   Community Alok Save    7 年前

    阅读此线程后,似乎 Select Case True 是可读性。这够了吗?当我第一次在VB.NET中看到这样的结构时,我不得不反复阅读几遍,以确保我理解了它的要点,但我的思路仍然与 RolandTumble, above . 因此,即使是可读性也要付出轻微的代价。每个人都知道什么是 If...ElseIf...End If 声明是和为什么它在那里。短路可以使用 AndAlso OrElse ,而复杂性完全取决于所涉及的代码和编码人员。

    If 语句可以优化。问显而易见的问题(你的 value = True ).有一次,一位与我们合作的编码员问我下面的内容是什么。。。

    Dim isVisible As Boolean
    ....
    If isVisible Then
        ....
    End If
    

    选择Case True 结构也让人感觉到你把重点或比较重点从实际出发 Select Case 排队进入 Case 这听起来很奇怪。