daghoff
asked on
Passing unknown variabels
How do you in VB.NET pass variabels to a subrutine if you dont know the variabel types or the number of variabels beeing passed to the sub before runtime?
In the sub there must also be a way to determin what info has been passed to the sub.
The sub will of cause have logic to process the values after it has been detected what type of data has been passed, but that is not part of this problem/solution.
is there a way to code this?
In the sub there must also be a way to determin what info has been passed to the sub.
The sub will of cause have logic to process the values after it has been detected what type of data has been passed, but that is not part of this problem/solution.
is there a way to code this?
For the Unknonw number of variables, you use a ParamArray.
For the unknow type, you define it as an array of Objects. My Visual Studio is being patched right now. I cannot check if I have it exactly right, but you get the concept.
For the unknow type, you define it as an array of Objects. My Visual Studio is being patched right now. I cannot check if I have it exactly right, but you get the concept.
Sub Foo(ByVal X As Byte, ByVal ParamArray A() As Object)
Dim W As Object
For Each W In A
Select Case True
Case TypeOf W Is Integer
CInt(W) = 10
Case TypeOf W Is TextBox
DirectCast(W,TextBox).Text
Case Else
Throw New NotSupportedException ("Type not supported")
End Select
Next
End Sub
put these in a Dictionary(Of String, Object) from the calling procedure (which I assume knows the variabe types) and name them appropriately, e.g
1.Calling routine would:
1.Calling routine would:
Dim ObjDICT As New Dictionary(Of String, Object)
ObjDICT.Add("Label", New Label With {.Name = "MyLabel", .Text = "MyLabelText"})
ObjDICT.Add("TextBox", New TextBox With {.Name = "MyTextBox", .Text = "MyTextBoxText"})
2. The recieving routine will then use the keys of the dictionary to cast the object to its typeFunction RecVFUNCT(ByVal xDict As Dictionary(Of String, Object) As Boolean
For Each x In xDict.Keys
Select Case x
Case "Label"
Dim Lbl = DirectCast(xDict.Item(x), Label)
Case "TextBox"
Dim Tbx = DirectCast(xDict.Item(x), TextBox)
End Select
Next
End Function
ASKER
Forgot to mention that the variabels to be passed are always two or more arrays of the same length. The arrays may be defined as string, integer, boolean etc. but that is not known before the program is run.
You mean this can be solved by putting it all in a new array?
You mean this can be solved by putting it all in a new array?
An array is an object. The array of Object variables used as a ParamArray can receive them. You will end up with an array of Array. The looping will just be a little more involved if you need to access individual values, something like:
Extra comment: ParamArray can be used alone. But if you have other parameters to pass, ParamArray should be the last one.
Extra comment: ParamArray can be used alone. But if you have other parameters to pass, ParamArray should be the last one.
Sub Foo(ByVal x As Byte, ByVal ParamArray a() As Object)
For Each w() As Object In A
For i As Integer = 0 To 10 - 1
Select Case True
Case TypeOf w(0) Is Integer
Debug.WriteLine(CInt(w(i)))
Case TypeOf w(0) Is TextBox
DirectCast(w(i), TextBox).Text = "Foo"
Case Else
Throw New NotSupportedException("Type not supported")
End Select
Next
Next
End Sub
You should be able to call it with code similar to the following:Dim a() As Integer
Dim b() As TextBox
'Fill the arrays
foo(10)
foo(10, a)
foo(10, b)
foo(10, a, b)
foo(10, b, a)
ASKER
Thanx for the answers. I liked the ParamArray approche best because it reduces the calling code to just one line as it should be.
But I forgot to mention that the arrays passed to the sub is to be returned. What my sub does is to sort them so the big question is how do I get them back? ParamArray does not allow ByRef.
I have an application where I need to sort arrays acording to one of them. How many and what type varies from place to place in the code. So insted of having the sort logic eveywhere I was hoping it could be put into a sub.
Perhaps there is no simple solution? Does anyone have a good aproche that realy solves my problem in a simpler way than just putting the sort logic eveywhere?
Or is there a specialiced multi array sort function/command already in place in VB.NET that I can use?
But I forgot to mention that the arrays passed to the sub is to be returned. What my sub does is to sort them so the big question is how do I get them back? ParamArray does not allow ByRef.
I have an application where I need to sort arrays acording to one of them. How many and what type varies from place to place in the code. So insted of having the sort logic eveywhere I was hoping it could be put into a sub.
Perhaps there is no simple solution? Does anyone have a good aproche that realy solves my problem in a simpler way than just putting the sort logic eveywhere?
Or is there a specialiced multi array sort function/command already in place in VB.NET that I can use?
An array is a class and is already a reference. These types of objects are always passes as a reference, no matter if you use ByVal or ByRef. Changing ParamArray is the same as changing the passed array.
This is a common misconception. ByVal and ByRef works only for value types, objects made from a structure or form the basic types.
This is a common misconception. ByVal and ByRef works only for value types, objects made from a structure or form the basic types.
ASKER
I knew that arrays are always passed in a "ByRef" way, but acording to what I have learned about ParamArray that is not the case. But it actually works as my slitly modified code below shows. The value that is modified in the sub is accessable after the sub has finished.
Public Class Form1
Dim IA(3) As Integer
Dim SA(3) As String
Dim BA(3) As Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
IA(1) = 3 : IA(2) = 2 : IA(3) = 1
SA(1) = "B" : SA(2) = "A" : SA(3) = "C"
BA(1) = True : BA(2) = False : BA(3) = True
MsgBox("Initial value before calling sub: " & SA(2))
Foo1(3, SA, IA, BA)
MsgBox("Updated value after calling sub: " & SA(2))
End Sub
Private Sub Foo1(ByVal NumValues As Byte, ByVal ParamArray A() As Object)
Dim Vc As Integer
For Each W() As Object In A '<<---- Error in this line!! ************************** ********** *****
For Vc = 1 To NumValues
Select Case True
Case TypeOf W(Vc) Is Integer
MsgBox("We have an Integer array")
Case TypeOf W(Vc) Is String
MsgBox("We have a String array")
W(Vc) = "4444444444444"
Case TypeOf W(Vc) Is Boolean
MsgBox("We have a Boolean array")
End Select
Next
Next
End Sub
End Class
But there are still one more problem. In the line marked above I get these type of errors shown below when the passed array is not defined as String. How do I overcome that problem?
Unable to cast object of type 'System.Int32[]' to type 'System.Object[]'.
Unable to cast object of type 'System.Boolean[]' to type 'System.Object[]'.
Regards
Public Class Form1
Dim IA(3) As Integer
Dim SA(3) As String
Dim BA(3) As Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
IA(1) = 3 : IA(2) = 2 : IA(3) = 1
SA(1) = "B" : SA(2) = "A" : SA(3) = "C"
BA(1) = True : BA(2) = False : BA(3) = True
MsgBox("Initial value before calling sub: " & SA(2))
Foo1(3, SA, IA, BA)
MsgBox("Updated value after calling sub: " & SA(2))
End Sub
Private Sub Foo1(ByVal NumValues As Byte, ByVal ParamArray A() As Object)
Dim Vc As Integer
For Each W() As Object In A '<<---- Error in this line!! **************************
For Vc = 1 To NumValues
Select Case True
Case TypeOf W(Vc) Is Integer
MsgBox("We have an Integer array")
Case TypeOf W(Vc) Is String
MsgBox("We have a String array")
W(Vc) = "4444444444444"
Case TypeOf W(Vc) Is Boolean
MsgBox("We have a Boolean array")
End Select
Next
Next
End Sub
End Class
But there are still one more problem. In the line marked above I get these type of errors shown below when the passed array is not defined as String. How do I overcome that problem?
Unable to cast object of type 'System.Int32[]' to type 'System.Object[]'.
Unable to cast object of type 'System.Boolean[]' to type 'System.Object[]'.
Regards
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
-MJC