Generic Sorting using C# and Lambda Expression
- by Haitham Khedre
Download : GenericSortTester.zip  I worked in this class from long time and I think it is a nice piece of code that I need to share , it might help other people searching for the same concept.  this will help you to sort any collection easily without needing to write special code for each data type , however if you need special ordering you still can do it , leave a comment and I will see if I need to write another article to cover the other cases.  I attached also a fully working example to make you able to see how do you will use that .              public static class GenericSorter
    {
        public static IOrderedEnumerable<T> Sort<T>(IEnumerable<T> toSort, 
      Dictionary<string, SortingOrder> sortOptions)
        {
            IOrderedEnumerable<T> orderedList = null;
            foreach (KeyValuePair<string, SortingOrder> entry in sortOptions)
            {
                if (orderedList != null)
                {
                    if (entry.Value == SortingOrder.Ascending)
                    {
                        orderedList = 
                          orderedList.ApplyOrder<T>(entry.Key, "ThenBy");
                    }
                    else
                    {
                        orderedList = 
                          orderedList.ApplyOrder<T>(entry.Key,"ThenByDescending");
                    }
                }
                else
                {
                    if (entry.Value == SortingOrder.Ascending)
                    {
                        orderedList = 
                          toSort.ApplyOrder<T>(entry.Key, "OrderBy");
                    }
                    else
                    {
                      orderedList =
                        toSort.ApplyOrder<T>(entry.Key, "OrderByDescending");
                    }
                }
            }
            return orderedList;
        }
        private static IOrderedEnumerable<T> ApplyOrder<T>
            (this IEnumerable<T> source, string property, string methodName)
        {
            ParameterExpression param = Expression.Parameter(typeof(T), "x");
            Expression expr = param;
            foreach (string prop in property.Split('.'))
            {
                expr = Expression.PropertyOrField(expr, prop);
            }
            Type delegateType = 
              typeof(Func<,>).MakeGenericType(typeof(T), expr.Type);
              LambdaExpression lambda = 
              Expression.Lambda(delegateType, expr, param);
            MethodInfo mi = typeof(Enumerable).GetMethods().Single(
                            method => method.Name == methodName
                            && method.IsGenericMethodDefinition
                            && method.GetGenericArguments().Length == 2
                            && method.GetParameters().Length == 2)
                    .MakeGenericMethod(typeof(T), expr.Type);
            return (IOrderedEnumerable<T>)mi.Invoke
                     (null, new object[] { source, lambda.Compile() });
        }
    }
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }