2012-08-31 18 views
7

Chcę posortować listę w C#, przez właściwość obiektów przechowywanych w nim. Mam to:Odbicie get właściwość obiektu do sortowania listy

if (sortColumn == "Login") 
{ 
    if (sortDir == "ASC") 
    { 
     filteredList.Sort((x, y) => string.Compare(x.Login, y.Login, true)); 
    } 
    else 
    { 
     filteredList.Sort((x, y) => string.Compare(y.Login, x.Login, true)); 
    } 
} 

i działa dobrze, ale chcę zrobić to bardziej ogólne, żeby nie trzeba znać pola sortowania. Mam na myśli coś takiego:

//With sortColumn = "Login"; 
if (sortDir == "ASC") 
{ 
    filteredList.Sort((x, y) => string.Compare(x.GetType().GetProperty(sortColumn), y.GetType().GetProperty(sortColumn), true)); 
} 
else 
{ 
    filteredList.Sort((x, y) => string.Compare(y.GetType().GetProperty(sortColumn), x.GetType().GetProperty(sortColumn), true)); 
} 

Oczywiście to nie działa, ale to, co chcę. Czy to możliwe w jakikolwiek sposób?

Dzięki.

+2

próbowałeś '.... GetProperty (sortColumn) .GetValue (...) '? –

Odpowiedz

3

kod odbicie nie jest poprawna, spojrzeć na ten

PropertyInfo pi1 = typeof(x).GetProperty(sortColumn); 
PropertyInfo pi2 = typeof(y).GetProperty(sortColumn); 

//With sortColumn = "Login"; 
if (sortDir == "ASC") 
{ 
    filteredList.Sort((x, y) => string.Compare(pi1.GetValue(x, null), pi2.GetValue(y, null), true)); 
} 
else 
{ 
    filteredList.Sort((x, y) => string.Compare(pi2.GetValue(y, null), pi1.GetValue(x, null), true)); 
} 

myślę, że to będzie pracować dla Ciebie.

+1

Dzięki H-Bahrami !! Działa to dla mnie, chociaż z niewielką modyfikacją: musiałem dodać wyraźną obsadę do "pi1.GetValue (x, null)" i do "pi2.GetValue (y, null)", aby jej wartość zwracana była na ciąg : string.Compare ((string) pi1.GetValue (x, null), (string) pi2.GetValue (y, null), true). – christiansr85

1

To jest to, czego używam dla tego samego problemu.

Sposób użycia wygląda następująco: mySequence.OrderByPropertyName("Login", SortDirection.Descending).

public enum SortDirection 
{ 
    Ascending, 
    Descending 
} 

public static IOrderedEnumerable<T> OrderByPropertyName<T> 
(
    this IEnumerable<T> items, 
    string propertyName, 
    SortDirection sortDirection = SortDirection.Ascending 
) 
{ 
    var propInfo = typeof(T).GetProperty(propertyName); 
    return items.OrderByDirection(x => propInfo.GetValue(x, null), sortDirection); 
} 

public static IOrderedEnumerable<T> OrderByDirection<T, TKey> 
(
    this IEnumerable<T> items, 
    Func<T, TKey> keyExpression, 
    SortDirection sortDirection = SortDirection.Ascending 
) 
{ 
    switch (sortDirection) 
    { 
     case SortDirection.Ascending: 
      return items.OrderBy(keyExpression); 
     case SortDirection.Descending: 
      return items.OrderByDescending(keyExpression); 
    } 
    throw new ArgumentException("Unknown SortDirection: " + sortDirection); 
} 
+1

'OrderByDirection' ???? –

+0

@ L.B Hah, zapomniałem, że to przedłużenie, przepraszam. Zaktualizowano! Również argument kierunku powinien być prawdopodobnie "wyliczeniem". – verdesmarald

+0

Oczyściłem to trochę. – verdesmarald

0

Sprawdziłem z dateTime i działa poprawnie.

List<DateTime> list = new List<DateTime>(); 
    list.Add(DateTime.Now); 
    list.Add(DateTime.UtcNow.AddYears(2)); 

    list.Sort((x, y) => (Convert.ToString(x.GetType().GetProperty("DayOfYear").GetValue(x)).CompareTo(Convert.ToString(y.GetType().GetProperty("DayOfYear").GetValue(y))))); 
0

Rozszerzanie off verdesmarald postu oddzielone wstępujących i zstępujących na oddzielne metody i dodaje metod ThenBy:

using System.Collections.Generic; 

namespace System.Linq 
{ 
    public static class IEnumerableExtensions 
    { 
     enum SortDirection 
     { 
      Ascending, 
      Descending 
     } 

     public static IOrderedEnumerable<T> OrderBy<T> 
      (this IEnumerable<T> items, 
      string propertyName) 
     { 
      var propInfo = typeof (T).GetProperty(propertyName); 
      return items.OrderByDirection(x => propInfo.GetValue(x, null), SortDirection.Ascending); 
     } 

     public static IOrderedEnumerable<T> ThenBy<T> 
      (this IOrderedEnumerable<T> items, 
      string propertyName) 
     { 
      var propInfo = typeof(T).GetProperty(propertyName); 
      return items.ThenByDirection(x => propInfo.GetValue(x, null), SortDirection.Ascending); 
     } 

     public static IOrderedEnumerable<T> OrderByDescending<T> 
      (this IEnumerable<T> items, 
      string propertyName) 
     { 
      var propInfo = typeof(T).GetProperty(propertyName); 
      return items.OrderByDirection(x => propInfo.GetValue(x, null), SortDirection.Descending); 
     } 

     public static IOrderedEnumerable<T> ThenByDescending<T> 
      (this IOrderedEnumerable<T> items, 
      string propertyName) 
     { 
      var propInfo = typeof(T).GetProperty(propertyName); 
      return items.ThenByDirection(x => propInfo.GetValue(x, null), SortDirection.Descending); 
     } 

     private static IOrderedEnumerable<T> OrderByDirection<T, TKey> 
      (this IEnumerable<T> items, 
      Func<T, TKey> keyExpression, 
      SortDirection sortDirection) 
     { 
      switch (sortDirection) 
      { 
       case SortDirection.Ascending: 
        return items.OrderBy(keyExpression); 
       case SortDirection.Descending: 
        return items.OrderByDescending(keyExpression); 
      } 
      throw new ArgumentException("Unknown SortDirection: " + sortDirection); 
     } 

     private static IOrderedEnumerable<T> ThenByDirection<T, TKey> 
      (this IOrderedEnumerable<T> items, 
       Func<T, TKey> keyExpression, 
       SortDirection sortDirection) 
     { 
      switch (sortDirection) 
      { 
       case SortDirection.Ascending: 
        return items.ThenBy(keyExpression); 
       case SortDirection.Descending: 
        return items.ThenByDescending(keyExpression); 
      } 
      throw new ArgumentException("Unknown SortDirection: " + sortDirection); 
     } 
    } 
} 
Powiązane problemy