我在字符串中有“按属性排序”的名称。我需要使用Lambda/Linq对对象列表进行排序。
Ex:
public class Employee
{
public string FirstName {set; get;}
public string LastName {set; get;}
public DateTime DOB {set; get;}
}
public void Sort(ref List<Employee> list, string sortBy, string sortDirection)
{
//Example data:
//sortBy = "FirstName"
//sortDirection = "ASC" or "DESC"
if (sortBy == "FirstName")
{
list = list.OrderBy(x => x.FirstName).toList();
}
}
与其使用一堆if来检查字段名(sortBy),还有一种更干净的排序方式吗
排序是否知道数据类型?
您可以使用Reflection来获取属性的值。
list = list.OrderBy( x => TypeHelper.GetPropertyValue( x, sortBy ) )
.ToList();
TypeHelper有一个静态方法,比如:
public static class TypeHelper
{
public static object GetPropertyValue( object obj, string name )
{
return obj == null ? null : obj.GetType()
.GetProperty( name )
.GetValue( obj, null );
}
}
你可能还想看看VS2008 Samples库中的Dynamic LINQ。您可以使用IEnumerable扩展将List转换为IQueryable,然后使用Dynamic link OrderBy扩展。
list = list.AsQueryable().OrderBy( sortBy + " " + sortDirection );
您可以使用反射来访问该属性。
public List<Employee> Sort(List<Employee> list, String sortBy, String sortDirection)
{
PropertyInfo property = list.GetType().GetGenericArguments()[0].
GetType().GetProperty(sortBy);
if (sortDirection == "ASC")
{
return list.OrderBy(e => property.GetValue(e, null));
}
if (sortDirection == "DESC")
{
return list.OrderByDescending(e => property.GetValue(e, null));
}
else
{
throw new ArgumentOutOfRangeException();
}
}
笔记
你为什么要传阅这份名单?
您应该使用枚举作为排序方向。
如果传递一个lambda表达式,可以得到一个更简洁的解决方案
指定要排序的属性,而不是以字符串形式指定属性名。
在我的例子中,list == null将导致NullReferenceException,您应该捕获这种情况。