Generic Sorting using C# and Lambda Expression

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 .

H

 

 

    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() });
        }
    }

6 Comments

Comments have been disabled for this content.