2012-08-31 12 views
7

Voglio ordinare un elenco in C#, da una proprietà degli oggetti memorizzati in esso. Ho questo:Riflesso ottenere proprietà dell'oggetto per ordinare un elenco

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)); 
    } 
} 

e funziona benissimo, ma voglio farlo più generico, in modo da non dover conoscere il campo per ordinare. Ho pensato in qualcosa di simile:

//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)); 
} 

Ovviamente questo non funziona, ma questo è quello che voglio. È possibile in qualche modo?

Grazie.

+2

Hai provato '.... GetProperty (sortColumn) .GetValue (...) '? –

risposta

3

il codice di riflessione non è corretto, un'occhiata a questo

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)); 
} 

penso che questo funzionerà per voi.

+1

Grazie H-Bahrami !! Questo funziona per me, anche se con una piccola modifica: ho dovuto aggiungere un cast esplicito a "pi1.GetValue (x, null)" ea "pi2.GetValue (y, null)" per rendere il suo valore di ritorno alla stringa : string.Compare ((stringa) pi1.GetValue (x, null), (stringa) pi2.GetValue (y, null), vero). – christiansr85

1

Questo è quello che uso per lo stesso problema.

L'utilizzo è simile a: 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, ho dimenticato che era un'estensione, mi dispiace. Aggiornato! Anche l'argomento di direzione dovrebbe probabilmente essere un enum. – verdesmarald

+0

Pulito un po '. – verdesmarald

0

Ho controllato data e ora e funziona correttamente.

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

espansione fuori del palo verdesmarald ho separato Crescente e discendente in metodi separati e ha aggiunto metodi 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); 
     } 
    } 
} 
Problemi correlati