Select Case with "Is" operator
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.
Related videos on Youtube
Teejay
C# / VB.net developer Freelance web-designer Hobbyist photographer
Updated on October 03, 2022Comments
-
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
If sender Is StyleBoldButton ElseIf .... End If
? Prettier to see maybe not, more understandable probably yes, since theSelect Case True
trick is not AFAIK very widely used in VB.NET -
DavidThere 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 theSelect
but would just perform that operation regardless of the type?
-
-
rskar almost 12 yearsI 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 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 almost 12 yearsProbably the best answer to my question would have been "You can't". But your solutions are just fine :)
-
Adrian Wragg over 9 yearsCan you explain how this improves on OP's own solution?
-
jo0ls almost 9 yearsGetHashCode should not be relied on to identify an object. The hashcode could be the same for different objects.
-
Zev Spitz almost 8 yearsWhat does
Case Is = "StyleBoldButton"
give you overCase "StyleBoldButton"
? TheIs
is unnecessary and thus irrelevant to the question. -
Jeffrey almost 8 yearsBecause 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 over 7 yearsAt-least use
Case StyleBoldButton.Name
instead so you don't get unexpected results if (or rather when) the name changes. -
Jeffrey over 7 yearsThis is another good suggestion, I'll update my answer to reflect that.
-
SteveCinq about 7 yearsI 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 almost 3 yearsif 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.