我在字符串中有“按属性排序”的名称。我需要使用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),还有一种更干净的排序方式吗 排序是否知道数据类型?


当前回答

这可以用

list.Sort( (emp1,emp2)=>emp1.FirstName.CompareTo(emp2.FirstName) );

. net框架将lambda (emp1,emp2)=>int转换为比较器<Employee>。

这具有强类型的优点。

如果需要降序/倒序,则反转参数。

list.Sort( (emp1,emp2)=>emp2.FirstName.CompareTo(emp1.FirstName) );

其他回答

加上@Samuel和@bluish所做的。这要短得多,因为在这种情况下Enum是不必要的。当升位是期望的结果时,作为额外的奖励,您只能传递2个参数而不是3个参数,因为true是第三个参数的默认答案。

public void Sort<TKey>(ref List<Person> list, Func<Person, TKey> sorter, bool isAscending = true)
{
    list = isAscending ? list.OrderBy(sorter) : list.OrderByDescending(sorter);
}

Sort使用IComparable接口,如果该类型实现了该接口。 你可以通过实现一个自定义IComparer来避免if:

class EmpComp : IComparer<Employee>
{
    string fieldName;
    public EmpComp(string fieldName)
    {
        this.fieldName = fieldName;
    }

    public int Compare(Employee x, Employee y)
    {
        // compare x.fieldName and y.fieldName
    }
}

然后

list.Sort(new EmpComp(sortBy));

通过表达式构建顺序可以在这里阅读

无耻地窃取页面链接:

// First we define the parameter that we are going to use
// in our OrderBy clause. This is the same as "(person =>"
// in the example above.
var param = Expression.Parameter(typeof(Person), "person");

// Now we'll make our lambda function that returns the
// "DateOfBirth" property by it's name.
var mySortExpression = Expression.Lambda<Func<Person, object>>(Expression.Property(param, "DateOfBirth"), param);

// Now I can sort my people list.
Person[] sortedPeople = people.OrderBy(mySortExpression).ToArray();

我是这样解决问题的:

List<User> list = GetAllUsers();  //Private Method

if (!sortAscending)
{
    list = list
           .OrderBy(r => r.GetType().GetProperty(sortBy).GetValue(r,null))
           .ToList();
}
else
{
    list = list
           .OrderByDescending(r => r.GetType().GetProperty(sortBy).GetValue(r,null))
           .ToList();
}

您可以使用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 );