Select Case with "Is" operator

16,438

Solution 1

Anything that has the requisite comparison operators (=, >=, <=, etc.) defined is fair game for Select Case. Rightly (or wrongly), references just aren't compared with = in VB; one must use Is. (Or Object.Equals(objA As Object, objB As Object) - but, really, why? when you've got Is?)

But take a look at Object equality behaves different in .NET - perhaps the VB way is less confusing? Whatever, I think you're stuck with the If-ElseIf ladder since Select Case doesn't do Is. (well, it does, but that's a different Is, more like the it of Hypercard.) I think the ladder looks smart and easy to follow:

If sender Is StyleBoldButton Then 

ElseIf sender Is StyleUnderButton Then

ElseIf sender Is StyleItalicButton Then

Else

End If 

As you have pointed out, the Select Case True pattern is an "OrElse" short-circuit workaround in VB6 - a wonky way to meet a real need. But that's not needed in VB.NET. In that spirit, maybe it's better to use design patterns more in line with the best practices expected of an object-oriented language. For example, as Denis Troller suggested, why not give each button its own event handler?

But if you insist on something like an Is-able Select, here's something I probably won't use myself:

With sender
    If .Equals(StyleBoldButton) Then

    ElseIf .Equals(StyleUnderButton) Then

    ElseIf .Equals(StyleItalicButton) Then

    Else

    End If
End With

Here I'm counting on .Equals to work like the C# == when faced with two object types to compare (see http://visualstudiomagazine.com/articles/2011/02/01/equality-in-net.aspx). The beauty of this is that sender is mentioned only once; however there's all this ElseIf .Equals( ... ) Then you'll have to type for each "Case".

Another way I won't use myself is using GetHashCode():

Select Case sender.GetHashCode()

    Case StyleBoldButton.GetHashCode()

    Case StyleUnderButton.GetHashCode()

    Case StyleItalicButton.GetHashCode()

    Case Else

End Select

Here I'm counting on what (very) little I know of GetHashCode() to uniquely (enough) identify these controls. (See Default implementation for Object.GetHashCode() ).

Solution 2

I just came across this same problem. After seeing another post and this post I came to this solution for myself and I wanted to share in case someone out there really wanted to use the Select Case like I did :)

    Select Case DirectCast(sender, Button).Name
        Case StyleBoldButton.Name

        Case StyleUnderButton.Name

        Case StyleItalicButton.Name

    End Select

Update 6-16-16: Removed "Is = " because it was unnecessary.

Update 8-27-16: Changed the use of strings to use .Name for better error tracking.

Share:
16,438

Related videos on Youtube

Teejay
Author by

Teejay

C# / VB.net developer Freelance web-designer Hobbyist photographer

Updated on October 03, 2022

Comments

  • Teejay
    Teejay over 1 year

    In VB.NET, I have to compare some objects within a select case statement.

    Since select case uses = operator by default and this is not defined for objects, a compile error is thrown.

    I presently use this workaround:

    Select Case True
        Case sender Is StyleBoldButton
    
        Case sender Is StyleUnderButton
    
        Case sender Is StyleItalicButton
    
    End Select
    

    which actually works.

    Is there something prettier to see and more understandable?

    • Paolo Falabella
      Paolo Falabella
      If sender Is StyleBoldButton ElseIf .... End If ? Prettier to see maybe not, more understandable probably yes, since the Select Case True trick is not AFAIK very widely used in VB.NET
    • David
      David
      There probably is a better way using polymorphism. What is it that you're ultimately doing with sender? Maybe you can abstract that functionality into a single operation that would work on each type of button? Then you wouldn't need the Select but would just perform that operation regardless of the type?
  • rskar
    rskar almost 12 years
    I believe OP was asking about (syntactic sugar for) comparing references (instances of Objects), not types (classes of Objects). Besides, an If-Then-ElseIf ladder was already suggested in comments above.
  • Teejay
    Teejay almost 12 years
    @rskar Exactly, i need to compare references, not types. BTW, in case of type comparation, typeof(sender).toString() is probably the best way.
  • Teejay
    Teejay almost 12 years
    Probably the best answer to my question would have been "You can't". But your solutions are just fine :)
  • Adrian Wragg
    Adrian Wragg over 9 years
    Can you explain how this improves on OP's own solution?
  • jo0ls
    jo0ls almost 9 years
    GetHashCode should not be relied on to identify an object. The hashcode could be the same for different objects.
  • Zev Spitz
    Zev Spitz almost 8 years
    What does Case Is = "StyleBoldButton" give you over Case "StyleBoldButton"? The Is is unnecessary and thus irrelevant to the question.
  • Jeffrey
    Jeffrey almost 8 years
    Because my brain got stuck on the OPs solution of object comparison instead of realizing that my solution was a string comparison so I put the Is operator in there without really thinking about it.
  • NiKiZe
    NiKiZe over 7 years
    At-least use Case StyleBoldButton.Name instead so you don't get unexpected results if (or rather when) the name changes.
  • Jeffrey
    Jeffrey over 7 years
    This is another good suggestion, I'll update my answer to reflect that.
  • SteveCinq
    SteveCinq about 7 years
    I use this from and think it's the most readable and flexible. A couple of things about the example here: 1. Better to use TryCast in a wrapping If in case sender is not a Button control (eg If TryCast(sender, Button) IsNot Nothing then ...) 2. Possibly better than that is just cast to Control: Select Case TryCast(sender, Control) ...
  • Brent Larsen
    Brent Larsen almost 3 years
    if I could thumbs up this again, I would. I love this because the "ugly" part is as the end, and its short and sweet. It lets me convey the original intent that is implied by a Select branch (based on this value, do one of these things). Its excellent. I imagine the only better option is for VB to allow Is to work.