2009-04-29 25 views
1
public class Person 
{ 
    public string name { get; set; } 
    public Email email { get; set; } 

} 

public class Email 
{ 
    public string desc { get; set; } 
} 

public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression, bool desc) 
{    
    var param = Expression.Parameter(typeof(T), string.Empty); 
    try 
    { 
     var property = Expression.Property(param, sortExpression); 
     var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param); 

     if (desc) 
     { 
      return source.AsQueryable<T>().OrderByDescending<T, object>(sortLambda); 
     } 

     return source.AsQueryable<T>().OrderBy<T, object>(sortLambda); 
    } 
    catch (ArgumentException) 
    { 
     return source; 
    } 
} 

     List<Person> vet = new List<Person>(); 

     Person p = new Person { name = "aaa", email = new Email { desc = "[email protected]" } }; 
     Person pp = new Person { name = "bbb", email = new Email { desc = "[email protected]" } }; 
     vet.Add(p); 
     vet.Add(pp); 

     vet.Sort("name",true); //works 
     vet.Sort("email.desc",true) // doesnt work 

有人能帮助我吗?扩展方法排序父对象内的列表

回答

1

如果您想要此功能,请查看ScottGu关于Dynamic Linq Library的文章。我相信它会做你想做的。

虽然Lambda的类型安全,但有些时候您可能想要生成查询,而不是让用户可以排序的每种可能的组合。

编辑

我固定的方法。基本上你需要为每个成员访问创建一个表达式。

public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression, bool desc) 
    { 
     var param = Expression.Parameter(typeof(T), string.Empty); 
     try 
     { 
      var fields = sortExpression.Split('.'); 
      Expression property = null; 
      Expression parentParam = param; 
      foreach (var field in fields) 
      { 
       property = Expression.Property(parentParam, field); 
       parentParam = property; 

      } 

      var sortLambda = 
       Expression.Lambda<Func<T, object>>(
        Expression.Convert(property, typeof(object)), param); 

      if (desc) 
      { 
       return source.AsQueryable<T>(). 
        OrderByDescending<T, object>(sortLambda); 
      } 

      return source.AsQueryable<T>(). 
       OrderBy<T, object>(sortLambda); 
     } 
     catch (ArgumentException) 
     { 
      throw; 
     } 
    } 
2

您可能想要考虑另一种采用自定义Comparer对象进行比较的方法。然后,您可以编写一个自定义的比较器,以便根据他们的电子邮件地址进行比较。