我试图让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