2009-04-29 51 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對象進行比較的方法。然後,您可以編寫一個自定義的比較器,以便根據他們的電子郵件地址進行比較。