I am trying to get a generic method
to extend Array
from the following piece of code:
Public Class clsField
Public idx As String
Public name As String
Public weight As Long
Public Sub New(i As String, n As String, w As Long)
idx = i : name = n : weight = w
End Sub
End Class
Public Class Container
Public fields As clsField() ' filled in by a JSON parser (order matters)
' returns a list sorted by clsField.weight preserving order for elements with same 'weight' value
Public Function getFields() As List(Of KeyValuePair(Of String, clsField))
Dim auxList As List(Of KeyValuePair(Of String, clsField))
If (fields Is Nothing) OrElse (fields.Count < 1) Then Return New List(Of KeyValuePair(Of String, clsField))
' .ToList to transform IEnumerable to the return type
auxList = Array.ConvertAll(fields, New Converter(Of clsField, KeyValuePair(Of String, clsField))(AddressOf FieldToPair)).ToList
Return auxList.OrderBy(Function(x) x.Value.weight).ToList()
End Function
Public Shared Function FieldToPair(fld As clsField) As KeyValuePair(Of String, clsField)
Return New KeyValuePair(Of String, clsField)(fld.idx, fld)
End Function
End Class
I am stuck with the Converter(Of TInput, TOutput) Delegate, used by Array.ConvertAll, which will not accept a new parameter, provided that I can pass a function to specify the key
that should be used on TInput
:
Private Function ClassToPair(Of T)(obj As T, getProperty As Func(Of T, Object)) As KeyValuePair(Of String, T)
Return New KeyValuePair(Of String, T)(getProperty(obj), obj)
End Function
Perhaps there is a way to Overload
Array.ConvertAll
and create an alternative Delegate
to Converter
, with a signature that allows to complete the following code (that obviously do not compile for ConvertAll
and AddressOf ClassToPair
; added here to reflect the idea) :
Module ArrayExtension ' custom method for array
' returns a list sorted by clsField.weight preserving order for elements with same 'weight' value
' getKey is used to transform the array into a List (Of KeyValuePair (Of String, T)) -> using the Converter
' getSortProperty is used to change the sorting 'property'
<Extension()>
Public Function toSortedPairedList(Of T)(arr As T(), Optional getKey As Func(Of T, String) = Nothing,
Optional getSortProperty As Func(Of KeyValuePair(Of String, T), Object) = Nothing) _
As List(Of KeyValuePair(Of String, T))
Dim auxList As List(Of KeyValuePair(Of String, T))
If (arr Is Nothing) OrElse (arr.Count < 1) Then Return New List(Of KeyValuePair(Of String, T))
' .ToList to transform IEnumerable to the return type
auxList = Array.ConvertAll(arr, New Converter(Of T, KeyValuePair(Of String, T))(AddressOf ClassToPair)).ToList
Return auxList.OrderBy(getSortProperty).ToList()
End Function
Private Function ClassToPair(Of T)(obj As T, getProperty As Func(Of T, Object)) As KeyValuePair(Of String, T)
Return New KeyValuePair(Of String, T)(getProperty(obj), obj)
End Function
End Module
So, no way to pass the getKey
function to the Converter...
For the first example its usage would be something like:
Public Function getFields() As List(Of KeyValuePair(Of String, clsField))
Dim auxList As List(Of KeyValuePair(Of String, clsField))
If (fields Is Nothing) OrElse (fields.Count < 1) Then Return New List(Of KeyValuePair(Of String, clsField))
Return fields.toSortedPairedList(Function(x) x.idx, Function(y) y.Value.weight)
End Function