views:

45

answers:

3

I have this function:

Public Sub DoStuff(ByVal type as System.Type, ByVal value as Object)

End Sub

The 'value' argument is always an array of the same type as 'type'. How can I loop through the values of the array?

I'd like to be able to do something like this:

DoStuff(GetType(Integer), New Integer(){1,2,3})

Public Sub DoStuff(ByVal type as System.Type, ByVal value as Object)

    //Strongly types arr as Integer()
    Dim arr = SomeCast(type, value) 

    For Each i in arr
        //Do something with i
    Next

End Sub

Edit Ok, I think I'll add more details so you can see what I'm trying to do. I have an object that captures values coming back from another page. Once I have them captured, I want to loop through the 'Values' property. So DoStuff() above would be called for each dictionary object in 'Values'. If the value in the dictionary objct is an array I want to loop through it as well. I was saving the type added through the generic function call as a System.Type, but maybe that's not the way to go. How can I write this so I can save the type of the array and loop through the array later?

Public Class PopUpReturnValues
    Implements IPopUpReturnValues

    Public Sub AddValue(Of T As Structure)(ByVal name As String, ByVal value As T) Implements IPopUpReturnValues.AddValue
        _values.Add(name, New PopUpReturnValue() With {.UnderlyingType = GetType(T), .Value = value, .IsArray = False})
    End Sub

    Public Sub AddArray(Of T As Structure)(ByVal name As String, ByVal values As T()) Implements IPopUpReturnValues.AddArray
        _values.Add(name, New PopUpReturnValue() With {.UnderlyingType = GetType(T), .Value = values, .IsArray = True})
    End Sub

    Public Sub AddStringValue(ByVal name As String, ByVal value As String) Implements IPopUpReturnValues.AddStringValue
        _values.Add(name, New PopUpReturnValue() With {.UnderlyingType = GetType(String), .Value = value, .IsArray = False})
    End Sub

    Public Sub AddStringArray(ByVal name As String, ByVal values As String()) Implements IPopUpReturnValues.AddStringArray
        _values.Add(name, New PopUpReturnValue() With {.UnderlyingType = GetType(String), .Value = values, .IsArray = True})
    End Sub

    Private _values As New Dictionary(Of String, PopUpReturnValue)
    Public ReadOnly Property Values() As IDictionary(Of String, PopUpReturnValue)
        Get
            Return _values
        End Get
    End Property

    Public Class PopUpReturnValue
        Public UnderlyingType As Type
        Public Value As Object
        Public IsArray As Boolean
    End Class

End Class
A: 

Is the type known at compile time? If so, perhaps you could use Generics.

Etienne de Martel
I added more details to the question. Hopefully I am clearer.
adam0101
A: 

You can provide an Action, like this:

Public Sub DoStuff(ByVal value As Array, ByVal process As Action(Of Object) )
    For Each item In value
       process(item)
    Next item
End Sub

Then you just need a method that takes one parameter for each of the types you care about and knows how to cast object to that type. Then call DoStuff() passing in the address of that method. You could even use a lambda if you wanted.

Joel Coehoorn
+1  A: 

Comments moved to answers per OP

Your "do something" code in based on the type I assume, String vs Int vs Apple, it would need to handle all three types with an If statement. Just include an overload for those three types, you don't actually need to pass the type information. However, if its just calling ToString() then just use an Object array.

And if you don't like overloads, just use the TypeOf operator to inspect the values of the array. When you throw an Integer into an Object array, its still an Integer, just a boxed one.

Chris Haas