2009-04-29 49 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

この機能を使用するには、Dynamic Linq LibraryにあるScottGuの記事をご覧ください。私はそれがあなたが望むことをすると信じています。

ラムダはタイプセーフですが、ユーザーが並べ替えることができるすべての可能な組み合わせを持つのではなく、クエリーをオンザフライで生成したい場合があります。

編集

私はあなたの方法を修正しました。基本的には、メンバーアクセスごとに式を作成する必要があります。

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オブジェクトを使用して比較を行う別の方法について考えるとよいでしょう。その後、電子メールアドレスに基づいて比較するPerson用のカスタムComparerを書くことができます。