views:

190

answers:

3

I am trying to write a generic function that generates an Xelement based on a list of objects, and a property of the object

Currently I have this code copied and pasted in several spots

 InputElementsArray = New XElement(New XElement("ArrayInputs", _
                   New XElement("InputName", "TestFailedRefDesList"), _
                   New XElement("DataType", "StringArray"), _
                   New XElement("ValueList", From d In _PassFailItem.FailureDetails Select New XElement("InputValue", d.RefDes))))
    InputElements.Add(InputElementsArray)

The above code works fine for me, but I would much rather create one single function that does the same task given an object and a property

Private Shared Function CreateBaseArrayInputs(Of T)(ByVal ListOfItems As List(Of T)) As XElement
    Dim InputElementsArray As XElement = _
         New XElement("ArrayInputs", _
                  New XElement("InputName", "TestFailureCodeList"), _
                  New XElement("DataType", "StringArray"), _
                  New XElement("ValueList", From d In ListOfItems Select New XElement("InputValue", d)))
    Return InputElementsArray
End Function

I am unsure about how I can generically set the property of d to use. Any ideas?

A: 

I don't think that you can specify a property using generics. I C# you cat put a restriction on T using the where keyword, but it seems that this is not avaible in VB.NET.

The restriction would allow you to specify that you T-elements have to implement an interface, and therefore you would know that the properties for that interface would be availble.

Jan Aagaard
It IS available in VB: http://msdn.microsoft.com/en-us/library/ms235246.aspx
Meta-Knight
Thanks. Forgot that VB and C# do not share keywords.
Jan Aagaard
A: 

I found a solution to the problem. It is not as elegant as I would have liked, but it still works

Here is the calling code

 Dim TestArray As XElement = CreateBaseArrayInputs((From d In _PassFailItem.FailureDetails Select New XElement("InputValue", d.FailureCodes)))

Here is the Called Function

Private Shared Function CreateBaseArrayInputs(ByVal ListOfItems As IEnumerable(Of XElement)) As XElement
    Dim InputElementsArray As XElement = _
         New XElement("ArrayInputs", _
                  New XElement("InputName", "TestFailureCodeList"), _
                  New XElement("DataType", "StringArray"), _
                  New XElement("ValueList", ListOfItems))
    Return InputElementsArray
End Function
Aaron M
+3  A: 

In addition to using XML literals, I would pass your value selector into your function like this:

Private Shared Function CreateBaseArrayInputs(Of T, TValue)( _
        ByVal ListOfItems As List(Of T), _
        ByVal selector As Func(Of T, TValue)) As XElement

    Return <ArrayInputs>
               <InputName>TestFailureCodeList</InputName>
               <DataType>StringArray</DataType>
               <ValueList>
                   <%= From d In ListOfItems _
                       Select <InputValue><%= selector(d) %></InputValue> %>
               </ValueList>
           </ArrayInputs>
End Function

Which you would call like this:

 Dim TestArray As XElement = CreateBaseArrayInputs(_PassFailItem.FailureDetails, Function(d) d.FailureCodes)
dahlbyk
Thats very similar to the code that I would up using, it just simplfies the process of passing in the data. Thanks
Aaron M