创建一个对List <t>集合</t>进行排序的通用方法

时间:2010-09-01 05:42:28

标签: c# linq generics lambda

我以前做的是创建一个案例开关,以这种格式对我的LINQ进行排序:

List<products> productList = GetAllLists();

switch (sortBy)
{
  case "name":
     return productsList.OrderBy(pl => pl.Name);
  case "date":
     return productsList.OrderBy(pl => pl.DateCreate);
}
从长远来看,这会变得很麻烦。

我想要一个通用的方法,你只需要用它来整理像这样的List集合,并帮助你切换要排序的属性..这样的东西:

return SortListCollection(productsList, Name);

4 个答案:

答案 0 :(得分:3)

您不需要为此使用反射,您可以使用表达式树来实现,这将更快。 Here's a blog post描述了这个过程,但是'cut'n'paste样本是:

public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName)
{
    var parameter = Expression.Parameter(source.ElementType, String.Empty);
    var property = Expression.Property(parameter, propertyName);
    var lambda = Expression.Lambda(property, parameter);

    var methodCallExpression = Expression.Call(typeof(Queryable), "OrderBy",
        new Type[] { source.ElementType, property.Type },
        source.Expression, Expression.Quote(lambda));

    return source.Provider.CreateQuery<T>(methodCallExpression);
}

答案 1 :(得分:2)

需要能够传入字符串吗?传入Func<T,TResult>委托将快速,灵活,并允许运行时检查;传入string不会。

你甚至可以准备好一堆预定义的代表:

var sortedByName = productList.OrderBy(NameSelector);
var sortedByDate = productList.OrderBy(DateCreatedSelector);
var sortedByCustom = productList.OrderBy(p => p.SomeOtherProperty);

// ...

// predefined delegates
public static readonly Func<Product, string> NameSelector = p => p.Name;

public static readonly Func<Product, DateTime> DateCreatedSelector =
                                                     p => p.DateCreated;

当然,如果你愿意的话,你可以用自己的方法将它全部包装起来,但是这种方法只是包含OrderBy调用的多余单行。

答案 2 :(得分:1)

解决:

private List<T> SortList<T>(List<T> collection, SortOrder order, string propertyName) where T : class
        {
            if (order == SortOrder.Descending)
            {
                return collection.OrderByDescending(cc => cc.GetType().GetProperty(propertyName).GetValue(cc, null)).ToList();
            }

            return collection.OrderBy(cc => cc.GetType().GetProperty(propertyName).GetValue(cc, null)).ToList();
        }

答案 3 :(得分:0)

使用反射构建可以按属性名称进行比较的比较器类。然后实例化该类并将其比较函数传递给List.Sort