【问题标题】:Select Case on an object's type in VB.NET在 VB.NET 中选择对象类型的大小写
【发布时间】:2010-11-21 01:46:41
【问题描述】:

我不确定这是否有效的 C#,但希望您能理解。 :)

switch (msg.GetType()) {
    case ClassA:
        // blah
    case ClassB:
        // blah 2
    case ClassC:
        // blah 3
}

如果使用 VB.NET 的 Select Case,我将如何打开对象的类型?

我知道有些人可能会建议使用polymorphism,但我使用的是小消息类的层次结构,所以这在我的情况下真的行不通。

【问题讨论】:

    标签: vb.net switch-statement select-case


    【解决方案1】:

    使用 VB 2010,对于面向 .NET 框架 4 及更高版本的项目,您现在可以这样做:

    Select Case msg.GetType()
        Case GetType(ClassA)
    End Select
    

    在早期的 VB 版本中,它不起作用,因为您无法比较两个类型是否相等。您必须使用 Is 关键字检查它们是否指向相同的引用。除非按照 Michael 的建议,使用 Name 或 FullName 等类型的属性进行比较,否则无法在 Select Case 中执行此操作。不过,您可以使用 If 和 ElseIf 的组合:

    Dim type = msg.GetType()
    If type Is GetType(ClassA)
        ...
    ElseIf type Is GetType(ClassB)
        ...
    ...
    End If
    

    【讨论】:

    • 我将使用If/ElseIfs。有点糟糕,没有类似开关的方式来做到这一点。
    • 具体来说,这只适用于 .Net Framework 4 及更高版本。 Type.Equality Operator
    • 您可以对此持保留态度并进行自己的性能测试:我自己对If/ElseIfSelect Case 的简单性能测试证明If/ElseIf 选项每次都更快。 Select Case 花费了大约 4 倍的时间。我现在会坚持使用If/ElseIf
    • 谢谢 - 这允许在同一比较中检查 2 种不同类型时更简洁/更易于阅读的代码,例如 Case GetType(ClassA), GetType(ClassB)Elseif typeof obj is ClassA or typeof obj is ClassB then
    【解决方案2】:

    好吧,如果你坚持使用 Select Case,你总是可以选择:

    Select Case True
        Case TypeOf msg Is ClassA
            ' do something '
        Case TypeOf msg Is ClassB
            ' do something else '
        Case Else
            ' and so on '
    End Select
    

    但我想大多数人都喜欢避免这种事情。 If/ElseIf 可能会更清楚。

    【讨论】:

    • 请避免这种事情! :)
    • 如果块很短,我对这个很矛盾。反对这部分代码的论点是什么?
    • 实际上这似乎一点也不坏,尤其是当您可能有多个案例(失败)时 - 这看起来比 if 语句更好...
    • 我更喜欢 CASE 而不是嵌套的 IF——IMO 更具可读性且不易出错。我经常使用 SELECT CASE True ...,效果很好。
    【解决方案3】:

    这是一种在同一个 sub 中处理 Button1 和 Button2 点击事件的方法(我最初是一名 VB6 程序员,所以这是 VB6 处理控件数组的一个很好的替代品)

    Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click
                    Select Case True
                        Case sender Is Me.Button1
                            ' Do Button1 stuff '
                        Case sender Is Me.Button2
                            ' Do Button2 stuff '
                    End Select
                End Sub
    

    【讨论】:

      【解决方案4】:

      我永远不会select case true,但你可以这样做:

      Select Case msg.GetType.Name
          Case GetType(ClassA).Name
              ...
          Case GetType(ClassB).Name
              ...
          Case Else
              ...
      End Select
      

      这比这看起来更干净:

      If msg.GetType Is GetType(ClassA) Then
          ...
      ElseIf msg.GetType Is GetType(ClassB) Then
          ...
      Else
          ...
      End If
      

      【讨论】:

      • 它可能更直观,但也慢了大约一百倍。但如果他真的想那样做的话,它就能完成工作。
      • @Bernesto - 比什么慢一百倍?这个答案与接受的答案相同(我没有 2010 来测试类型相等的性能)。我不认为它应该是-1??
      • 如果 Type.Name 不是完全限定的类型名称,如果两个类具有相同的名称但位于不同的命名空间中,则可能会发生冲突。
      • @MrShoubs “比什么慢一百倍?”您确实意识到,与仅比较 Type 实例的公认答案不同,您的答案为每个实例创建字符串并进行比较?
      【解决方案5】:

      这个:

      Dim a As Object = New TextBox
      
      Select Case True
          Case TypeOf a Is TextBox
              MsgBox("aaa")
      
          Case TypeOf a Is ComboBox
      
          Case TypeOf a Is ListBox
      
      End Select
      

      【讨论】:

        猜你喜欢
        • 2017-05-04
        • 1970-01-01
        • 2011-05-19
        • 1970-01-01
        • 1970-01-01
        • 2013-06-18
        • 1970-01-01
        • 2021-04-06
        • 1970-01-01
        相关资源
        最近更新 更多