Req12: Select Case on object identity and type


[This post is part of a series, “wish-list for future versions of VB“]


 


VB already has a powerful “Select Cast” statement, e.g.


        Select Case x


            Case Is = 1


                Console.WriteLine(“x is equal to 1”)


            Case Is > 7


                Console.WriteLine(“x is greater than 7”)


            Case 2 To 4


                Console.WriteLine(“x is between 2 and 4”)


        End Select


 


IDEA: Allow Select Case on object identity. For example,


        Select Case sender


            Case Is TextBox1


                Console.WriteLine(“sender was TextBox1”)


            Case Is TextBox2


                Console.WriteLine(“sender was TextBox2”)


        End Select


 


IDEA: Allow Select Case on type. For example,


        Select Case TypeOf(sender)


            Case Is TextBox


                ‘ Type of “sender” is TextBox inside this block:


                sender.ReadOnly = True


            Case Is Label


                ‘ Type of “sender” is Label inside this block:


                sender.AutoEllipsis = True


        End Select


This would provide an alternative to the common object-oriented style of writing a “visitor” pattern by overriding the “Visit” method on each subtype. Instead, in the manner of F# and other functional languages, you could gather the visiting code together in one place. Note that you wouldn’t be allowed to GOTO from one branch to another (except maybe from a subtype to a supertype!)


 


Provisional evaluation from VB team: This is a decent idea, worth considering against the other decent ideas. (If you have other scenarios, please write in with them!)


 

Comments (10)

  1. Jonathan Allen says:

    The select case on type is incredibly important, but I’m not so sure about the syntax.

    Instead of implicitly changing the variable’s type, how about renaming it? Something like:

      Select value As TypeOf(expression)

    This way you can switch on an expression, not just a variable. And it makes it clear that the value is changing type.

    >  Note that you wouldn’t be allowed to GOTO from one branch to another

    I don’t see that as a problem. If you are goint to mix goto and select case, you are better off ditching both and using if blocks.

  2. Dzonny says:

    Select Case on type is very useful and I like the idea of providing typed value in Case branch without need to do DirectCast in each branch manually. Usage of original name is not problem for me – it’s not change of variable value, it’s only knowledge of compiler that in this branch the Object can be treated as TextBox – like in

    With DirectCast(sender, TextBox)

       .Text = ":-)"

    End With

    GoTo >> Some compiler warning or error when GoTo ends in different branch (of incompatible type) is useful but not hight priority. Somebody who uses GoTo have to really know what (s)he is doing! In case of incompatible types InvalidCastException may be raised in runtime.

  3. Kevin Ryall says:

    This would be great to have. VB’s select case syntax is already very powerful – this would just round it off.

    I usually handle the select on object identify case with a ‘Select Case True’ block – it does what I need at the cost of being slightly harder to read. Automatically providing the typed variable in each block would be fantastic – but I prefer Jonathan’s  syntax as it more explicit / less ‘magical’.

  4. JonathanS says:

    I have had multiple instances of these scenarios where this feature would have been useful.

  5. Adam Speight says:

    Fix the compiler warning rules for select Case

    In the following example all the cases are covered.

    Public Function NZP(ByVal i As Integer) As Integer

     Select Case i

      Case Is < 0

       Return -1

      Case Is = 0

       Return 0

      Case Is > 0

       Return 1

     End Select

    End Function

    To get rid of the warning you need to change the last case Else.

  6. Adam Speight says:

    It useful for checking inherited types. Suppose you have your own number class that inherits a Number_Base.

     Dim a As New Invalid_Number

     Dim b As New Valid_Number

     Dim c = a + b

    End Sub

    End Module

    Public MustInherit Class Number_Base

    Public Shared Operator +(ByVal a As Number_Base, ByVal b As Number_Base) As Number_Base

     Select Case a

      Case TypeOf a Is Valid_Number

      Case TypeOf a Is Invalid_Number

     End Select

    End Operator

    End Class

    Public Class Invalid_Number

    Inherits Number_Base

    End Class

    Public Class Valid_Number

    Inherits Number_Base

    End Class

    Public MustInherit Class Validity_Base

    End Class

    Public Class Invalid

    Inherits Validity_Base

    End Class

    Public Class Valid

    Inherits Validity_Base

    End Class

    Public Module e

    Public Sub CheckValidity(ByVal vt As Validity_Base)

    Select Case TypeOf vt

      Case Is  Invalid

       Console.WriteLine("Imvalid")

      Case Is Valid

       Console.WriteLine("Result Valid")

     End Select

    End Sub

    End Module

  7. Kyralessa says:

    It’s syntactic sugar, nothing more, since you can already do this kind of thing with an If statement.

    But who cares; I like syntactic sugar.  It looks like a good idea.

  8. Richard says:

    This seems a good idea – I think I’ve come across situations where I’ve wanted to use both of these constructs in the past.

  9. Simon Geering says:

    Would be a lot neater than the

    Select Case True

       TypeOf()

    That i end up using for this at the moment.

  10. weitzhandler says:

    Yes we want it!!!