我試圖讓generic method
從下面的代碼段延長Array
:通用函數數組轉換爲KeyValuePair的排序列表(downvoted)
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
我堅持的Converter(Of TInput, TOutput) Delegate,使用Array.ConvertAll ,這將不接受新的參數,前提是我可以通過一個函數來指定,應該在TInput
使用的key
:
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
或許有辦法Overload
Array.ConvertAll
並創建一個替代Delegate
到Converter
,簽名允許完成下面的代碼(顯然不編譯爲ConvertAll
和AddressOf ClassToPair
;這裏爲了反映的想法):
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
所以,沒辦法getKey
功能傳遞到轉換器 ...
對於它的使用會像第一個例子:
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
如果沒有**存儲** Func'' getProperty'來訪問包含對象'T' [...'array()as T']的屬性,那麼這是不可能的,它告訴哪個是'TKey'在轉換過程中創建'KeyValuePair' ...因此實現轉換的函數應該首先將'getProperty'存儲在一個變量中,該變量可以被**訪問**並從'ClassToPair'中調用。所以說它應該實現兩次:** 1。** store'getProperty',** 2。**'Array.ConvertAll' ... – rellampec