DataAnalyst1
DataAnalyst1

Reputation: 147

Extension method for Sorting a generic iCollection(Of T)

I'm trying to extend a generic collection to be sortable by my own criteria.

This is how I've been doing it using Linq:

Dim sortedList = ViewCollection.OrderByDescending(Function(x) x.ViewName.Replace(" ", "").Replace(".", "").Trim.All(AddressOf Char.IsLetter)).ThenByDescending(Function(x) x.ViewName.Replace(" ", "").Replace(".", "").Trim.Any(AddressOf Char.IsDigit)).ThenBy(Function(x) x.ViewName.Replace(" ", "").Replace(".", "").Trim).ToList()

So, this is the sorting method extension I'm working on:

<System.Runtime.CompilerServices.Extension()> _
        Public Function SortCollection(Of T)(ByVal Collection As ICollection(Of T), ByVal PropertyName As String) As ICollection(Of T)

            For Each p As System.Reflection.PropertyInfo In Collection.GetType().GetProperties()
                If p.Name = PropertyName Then
                    result = Collection.ToList() ' I need to replace this with the sorting criteria posted above
                End If
            Next

            Return result
        End Function

I can't seem find a way on how to pass what property from this generic object I want to use as for alphabetic sorting criteria.

Any clues?

Upvotes: 1

Views: 208

Answers (1)

You need to obtain a PropertyDescriptor and use this to sort the collection.

<Extension()> _
Public Function Sort(Of T)(ByVal collection As IEnumerable(Of T), ByVal propertyName As String, direction As ListSortDirection) As IEnumerable(Of T)
    Dim descriptor As PropertyDescriptor = TypeDescriptor.GetProperties(GetType(T)).Find(propertyName, True)
    If (direction = ListSortDirection.Descending) Then
        Return (From item As T In collection Select item Order By descriptor.GetValue(item) Descending)
    Else
        Return (From item As T In collection Select item Order By descriptor.GetValue(item) Ascending)
    End If
End Function

Usage

MessageBox.Show(String.Join(Environment.NewLine, {"xxxxx", "xxx", "x", "xxxx", "xx"}.Sort("Length", ListSortDirection.Ascending)))

Output:

x
xx
xxx
xxxx
xxxxx

Upvotes: 1

Related Questions