0

I have a method which I need to call which accepts a ParamArray

Method(ByVal ParamArray elements() As Object)

I need to pass it two known strings, and an unknown number of strings, based on a variable number of XmlNodes in an XmlDocument

i.e.

Method("Known String 1", "Known String 2", Node1.OuterXml, ..., NodeN.OuterXml)

How can I do this?

I have tried looping through the nodes and creating and passing:

List(Of String) which results in elements() containing "Known String 1", "Known String 2", System.Collections.Generic.List[System.String]

List(Of String).ToArray which results in elements() containing "Known String 1", "Known String 2", System.String[]

String() which results in elements() containing "Known String 1", "Known String 2", System.String[]

and

Collection which results in elements() containing "Known String 1", "Known String 2", Microsoft.VisualBasic.Collection

What I want, for an example of 3 nodes is elements() to contain "Known String 1", "Known String 2", "<node 1>", "<node 2>", "<node 3>"

Is this possible?

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
Shevek
  • 3,869
  • 5
  • 43
  • 63

3 Answers3

0

The issue here is the nonintuitive leap between what you write and what the compiler does - mainly because the syntax is a little wonky.

Anyhow, notice that your method signature contains a SINGLE parameter: elements(). The () means its an array.

The ParamArray keyword allows you to "explode" the elements of an array and pass each array element as its own parameter to the method - something you already knew. But it also means that the compiler (or JIT, or whatever) recombines those parameters back into a single array.

You would have noticed this if you hadn't had the misfortune of defining elements as Object:

so TL;DR:
Either pass each array element individually - not an option in your case, Or pass a single array in for the array-typed parameter.

Dim stuffToPassInToTheMethod As List(Of String) = New List(Of String) From {"Magic String One", "Magic String Two"}

' Some loops and xml nodes.. blah blah.. end up calling stuffToPassInToTheMethod.Add(node.Attributes("yadda").Value

Then finally just pass it to the method: crazyMethodNameWithThePOINTLESSParamArray(stuffToPassInToTheMethod.ToArray)

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
-1

My answer so far is to check the types in the method and add the values to a new List(Of String) and then work with the list, not the object array:

    Dim strElements As New List(Of String)        

    For Each element As Object In elements
        If element.GetType Is GetType(System.String) Then
            strElements.Add(element)
        ElseIf element.GetType Is GetType(System.Collections.Generic.List(Of String)) Then
            For Each s As String In element
                strElements.Add(s)
            Next
        End If
    Next

But if there is a better way to add the individual strings to the ParamArray directly that would be much better

Shevek
  • 3,869
  • 5
  • 43
  • 63
-2

Shevek's answer works great. All you have to do is then pass the list you've created/populated to the method expecting a parmarray as "strElements.ToArray". I just used this to populate a DataGridView with a dynamic number of columns, like this (in a loop, creating a new strElements list for each row of data): dgvData.Rows.Add(strElements.ToArray)

Queego
  • 1