Paul Hutchinson
Paul Hutchinson

Reputation: 829

How do I sort a list(of T) by a property x when x is a string and I don't know about the properties on T

I want to sort a list of T from a function, and sort by any property of T, referenced by name only.

For example.

function sortusers(byval Users as list(of users), byval OrderBy as string, byval OrderDirection as SortDirection)

    return Sort(Of User)(Users, OrderBy, OrderDirection)

end function

or

return Users.Sort(OrderBy, OrderDirection)

Upvotes: 0

Views: 142

Answers (2)

Paul Hutchinson
Paul Hutchinson

Reputation: 829

One way to do this is to write an extension method.

Module imnotgoodwithnames

''' <summary>
''' Sorts a list of type T.
''' </summary>
''' <typeparam name="T">The type of the objects in the list</typeparam>
''' <param name="context">The list</param>
''' <param name="sortExpression">The column to sort by</param>
''' <param name="sortDirection">The sort direction</param>
''' <returns>The sorted list</returns>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Function Sort(Of T As {Class, New})(ByVal context As List(Of T), ByVal sortExpression As String, ByVal sortDirection As SortDirection) As IOrderedEnumerable(Of T)

    Dim param = Expression.Parameter(GetType(T), sortExpression.ToString)
    Dim field As PropertyInfo = GetColByName(Of T)(context, sortExpression)
    Dim keySelector = getKeySelector(Of T)(field)

    If sortDirection = WebControls.SortDirection.Ascending Then
        Return context.OrderBy(keySelector)
    Else
        Return context.OrderByDescending(keySelector)
    End If

End Function

''' <summary>
''' Get the property information of a named property against a class
''' </summary>
''' <returns>The property info of the primary key</returns>
''' <remarks>Throws an exception if no primary key exists</remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Function GetColByName(Of T)(ByVal context As List(Of T), ByVal colname As String) As PropertyInfo
    Dim properties As PropertyInfo() = GetType(T).GetProperties()
    For Each pI As PropertyInfo In properties
        If pI.Name = colname Then
            Return pI
        End If
    Next
    Return Nothing
End Function

''' <summary>
''' Gets the key selector for a property on a generic class.
''' </summary>
''' <typeparam name="TSource">The class/type</typeparam>
''' <param name="property">the propertyinfo for the field</param>
''' <returns>the keyselector function</returns>
''' <remarks></remarks>
Function getKeySelector(Of TSource)([property] As PropertyInfo) As Func(Of TSource, Object)
    Return Function(item As TSource) [property].GetValue(item, Nothing)
End Function

End Module

Upvotes: 2

tinstaafl
tinstaafl

Reputation: 6948

You could just use the OrderBy method of the list with an inline function specifically for that list.

Upvotes: 1

Related Questions