我以前做的是创建一个案例开关,以这种格式对我的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);
答案 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