Reputation: 147
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
Reputation: 9981
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