Often when offering a user specified sort order, and using LINQ for sorting, I end up with an ugly scenario like this:
public static IEnumerable<ConfirmationItemViewModel> SortAscending(IEnumerable<ConfirmationItemViewModel> confirmations, string sortProperty)
{
switch (sortProperty)
{
case "CreatedOn":
confirmations = confirmations.OrderBy(i => i.CreatedOn).ToList();
break;
case "PaymentId":
confirmations = confirmations.OrderBy(i => i.PaymentId).ToList();
break;
default:
confirmations = confirmations.OrderBy(i => i.PaymentId).ThenBy(i => i.CreatedOn).ToList();
break;
}
return confirmations;
}
The OrderBy
method takes a function delegate of the type Func<TSource, TKey>
, which I presume it uses to get the value of the sort property from each item in the collection being sorted. I would like to write a method that takes the property name instead of a delegate, and returns a delegate that returns the property value, if that even half explains what I mean.
Hopefully my attempt at coding it, which doesn't work, will explain more. This is the closest I have been able to get, given my limited understanding of expressions and delegates:
public static Func<TObject, TKey> BuildKeySelector<TObject, TKey>(TObject source, string propertyName)
{
return obj =>
{
var prop = source.GetType().GetProperty(propertyName, typeof(TKey));
return (TKey) prop.GetValue(obj);
};
}
static void Main(string[] args)
{
// Sort a list of Person objects by their Name property.
var peeps = new List<Person>();
var rank = peeps.OrderBy(BuildKeySelector(<something>, "Name"));
}