Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. Help with a Generic function

Help with a Generic function

Scheduled Pinned Locked Moved Visual Basic
helpquestiondockerdata-structuresregex
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TwoFaced
    wrote on last edited by
    #1

    I set out to write a Generic function that would find controls of a desired type and pass back an array of that type. For instance I could call the function and ask for all textbox's found on a form. However, I ran into a snag. I can test if a control is of Type T, but I have know way of converting that control to Type T. The following code shows the compromise I had to make due to this limitation.

        'Returns a control array full of controls that match the desired type
        Public Function ControlArray(Of T)(ByVal container As Control) As Control()
            'Controls to pass back
            Dim list As New List(Of Control)
    
            For Each ctrl As Control In container.Controls
                'If child control is of the desired type T then
                'add to list
                If ctrl.GetType Is GetType(T) Then list.Add(ctrl)
            Next
            'Return array
            Return list.ToArray
        End Function
    

    Ideally this function would look something like the code below. The big difference is I want to return an array of type T. But how can I possibly convert a generic control to an unknown type?

        Public Function ControlArray(Of T)(ByVal container As Control) As T()
            'Controls to pass back
            Dim list As New List(Of T)
    
            For Each ctrl As Control In container.Controls
                'If child control is of the desired type T then
                'add to list
                If ctrl.GetType Is GetType(T) Then
                    'The next statement won't compile and is the major problem I
                    'need to work around
                    list.Add(DirectCast(ctrl, T))
                End If
    
            Next
            'Return array
            Return list.ToArray
        End Function
    
    C 1 Reply Last reply
    0
    • T TwoFaced

      I set out to write a Generic function that would find controls of a desired type and pass back an array of that type. For instance I could call the function and ask for all textbox's found on a form. However, I ran into a snag. I can test if a control is of Type T, but I have know way of converting that control to Type T. The following code shows the compromise I had to make due to this limitation.

          'Returns a control array full of controls that match the desired type
          Public Function ControlArray(Of T)(ByVal container As Control) As Control()
              'Controls to pass back
              Dim list As New List(Of Control)
      
              For Each ctrl As Control In container.Controls
                  'If child control is of the desired type T then
                  'add to list
                  If ctrl.GetType Is GetType(T) Then list.Add(ctrl)
              Next
              'Return array
              Return list.ToArray
          End Function
      

      Ideally this function would look something like the code below. The big difference is I want to return an array of type T. But how can I possibly convert a generic control to an unknown type?

          Public Function ControlArray(Of T)(ByVal container As Control) As T()
              'Controls to pass back
              Dim list As New List(Of T)
      
              For Each ctrl As Control In container.Controls
                  'If child control is of the desired type T then
                  'add to list
                  If ctrl.GetType Is GetType(T) Then
                      'The next statement won't compile and is the major problem I
                      'need to work around
                      list.Add(DirectCast(ctrl, T))
                  End If
      
              Next
              'Return array
              Return list.ToArray
          End Function
      
      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      You need to constrain your generic statement.  In C#, you'd do it like this public List<T> ControArray<T>(Control container) where T : Control Not sure of the VB syntax.

      Christian Graus - C++ MVP 'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert

      T 1 Reply Last reply
      0
      • C Christian Graus

        You need to constrain your generic statement.  In C#, you'd do it like this public List<T> ControArray<T>(Control container) where T : Control Not sure of the VB syntax.

        Christian Graus - C++ MVP 'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert

        T Offline
        T Offline
        TwoFaced
        wrote on last edited by
        #3

        I tried converting the code with a converter I found online but the result didn't seem to be correct. However, I think I understand what you mean, but that's not the problem. Simply put I need to convert a control to it's real type. If I could figure that out I'd be all set. Any thoughts on that? At the moment I have figured out solution. I realized I can convert the control to an object and then add it to the list. As long as Option Strict isn't on this works just fine because it just uses implicit conversion. I'm okay with that for now but I'd still like to know if there is anyway to convert a generic control to it's actual type without knowing it's type a head of time. Here is the code I'm using right now, which is working just fine.

            'Returns a control array full of controls that match the desired type
            Shared Function ControlArray(Of T as control)(ByVal container As Control) As T()
                'Controls to pass back
                Dim list As New List(Of T)
        
                For Each ctrl As Control In container.Controls
                    'If child control is of the desired type T then add to list
                    If ctrl.GetType Is GetType(T) Then list.Add(CType(ctrl, Object))
                Next
                'Return array
                Return list.ToArray
            End Function
        

        -- modified at 20:53 Friday 26th January, 2007 Okay, I take it back what I said about the constraint not being a problem. Well, technically it wasn't a problem but now that I have added a constraint I am now able to add a control type to my list which is of T. Now I don't need to convert to an object first, however, an implicit conversion is still needed so Option Strict can't be turned on. Thanks for your help! It worked perfectly. If you have any ideas on making this option strict friendly please let me know.

        C 1 Reply Last reply
        0
        • T TwoFaced

          I tried converting the code with a converter I found online but the result didn't seem to be correct. However, I think I understand what you mean, but that's not the problem. Simply put I need to convert a control to it's real type. If I could figure that out I'd be all set. Any thoughts on that? At the moment I have figured out solution. I realized I can convert the control to an object and then add it to the list. As long as Option Strict isn't on this works just fine because it just uses implicit conversion. I'm okay with that for now but I'd still like to know if there is anyway to convert a generic control to it's actual type without knowing it's type a head of time. Here is the code I'm using right now, which is working just fine.

              'Returns a control array full of controls that match the desired type
              Shared Function ControlArray(Of T as control)(ByVal container As Control) As T()
                  'Controls to pass back
                  Dim list As New List(Of T)
          
                  For Each ctrl As Control In container.Controls
                      'If child control is of the desired type T then add to list
                      If ctrl.GetType Is GetType(T) Then list.Add(CType(ctrl, Object))
                  Next
                  'Return array
                  Return list.ToArray
              End Function
          

          -- modified at 20:53 Friday 26th January, 2007 Okay, I take it back what I said about the constraint not being a problem. Well, technically it wasn't a problem but now that I have added a constraint I am now able to add a control type to my list which is of T. Now I don't need to convert to an object first, however, an implicit conversion is still needed so Option Strict can't be turned on. Thanks for your help! It worked perfectly. If you have any ideas on making this option strict friendly please let me know.

          C Offline
          C Offline
          Christian Graus
          wrote on last edited by
          #4

          Actually, the core problem is, you're iterating through a collection of controls, looking for objects that are of a more specific type.  One solution that would work in C# is the 'as' keyword foreach(Control ctrl in container.Controls) {     T specific = ctrl as T;     if (specific != null)     {           list.Add(specific);     } } This code makes use of the 'as' keyword, which does a conversion, or returns null if one is not possible.  This removes the need for a cast, and replaces the code you've got using GetType ( which is not BAD code, but this approach changes the code rather than adds to it ).

          Christian Graus - C++ MVP 'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert

          T 1 Reply Last reply
          0
          • C Christian Graus

            Actually, the core problem is, you're iterating through a collection of controls, looking for objects that are of a more specific type.  One solution that would work in C# is the 'as' keyword foreach(Control ctrl in container.Controls) {     T specific = ctrl as T;     if (specific != null)     {           list.Add(specific);     } } This code makes use of the 'as' keyword, which does a conversion, or returns null if one is not possible.  This removes the need for a cast, and replaces the code you've got using GetType ( which is not BAD code, but this approach changes the code rather than adds to it ).

            Christian Graus - C++ MVP 'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert

            T Offline
            T Offline
            TwoFaced
            wrote on last edited by
            #5

            Thanks once again for your help. I converted your code and 'as' converted to CType(ctrl, T) which I am familiar with. However, it seems that unlike C# a failed conversion will generate an error. I could do something similiar to your code by using TryCast instead which does return nothing if it fails. I'm not exactly sure what the technical differences are between CType and TryCast (aside from no errors that is). I think I might have to look that up. Now that I have used a constraint, CType and TryCast/Directcast work. Before I used a constraint they would not compile. It seems the constraint was all I needed and allows me to convert a control type to T. Now that I don't need to rely on a implicit conversion Option Strict is happy :)

            C 1 Reply Last reply
            0
            • T TwoFaced

              Thanks once again for your help. I converted your code and 'as' converted to CType(ctrl, T) which I am familiar with. However, it seems that unlike C# a failed conversion will generate an error. I could do something similiar to your code by using TryCast instead which does return nothing if it fails. I'm not exactly sure what the technical differences are between CType and TryCast (aside from no errors that is). I think I might have to look that up. Now that I have used a constraint, CType and TryCast/Directcast work. Before I used a constraint they would not compile. It seems the constraint was all I needed and allows me to convert a control type to T. Now that I don't need to rely on a implicit conversion Option Strict is happy :)

              C Offline
              C Offline
              Christian Graus
              wrote on last edited by
              #6

              CType is not the same, nor is DirectCast.  TryCast is the same as the 'as' keyword. Sounds like you've got it working, anyhow :-)

              Christian Graus - C++ MVP 'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups