Generic Lambda Expression to sort collections of different types

Suppose you have many collections with different types that you want to sort, of course you can do it by OrderBy or OrderByDescending extension methods but you have to specify the order criteria every time you call these methods. If the order criteria is determined in runtime, then you have to build a separate function to each order criteria of each type. To clear what I want to tell you suppose you have two classes, Employee and Department.
public class Employee
{
    public String Name { get; set; }
    public Int32 Age { get; set; }
    public DateTime HiringDate { get; set; }
}

public class Department
{
    public String DepartmentName { get; set; }
    public String Code { get; set; }
}
And you want to order the employee collection by one of its properties (Name,Age,or HiringDate) and order department collection by one of its properties.

OrderBy and OrderByDescending methods need Func<TSource,TKey> as selector to compare the collection items and order them. So the issue here is, How do you create a generic Func<TSource,TKey> to be passed to OrderBy or OrderByDescending methods? The answer is, by using Expression.Lambda method.

We will create a generic method with one string argument which will be the name of the property that we will order by and the return will be Lambda expression will be passed to OrderBy or OrderByDescending.
public Func<T, Object> GetExpression<T>(String sortby)
{
    var param = Expression.Parameter(typeof(T));
    var sortExpression = Expression.Lambda<Func<T, Object>>(Expression.Convert(Expression.Property(param, sortby), typeof(Object)), param);
    return sortExpression.Compile();
}
The GetExpression method do the following:
  1. Create ParameterExpression object by calling Expression.Parameter method which accepts the type of the collection we want to sort.
  2. Create the Lambda expression tree.
  3. Compile the lambda expression by calling Expression.Compile method and return a delegate that represent the lambda expression.
To test GetExpression method we can call OrderBy extension method of Employee collection or Department collection as follows
employees.OrderBy(GetExpression("Age"));
departments.OrderBy(GetExpression("Code"));
First line will order employees by according to their ages and the second line will order departments by its codes.

you can download the full source code here

Comments

Post a Comment

Popular posts from this blog

Android : How to change progress bar color at runtime programmatically?

How to fire RowCommand event of nested GridView?

ASP.Net MVC : Conditional Validation using ValidationAttribute