2012-08-31 8 views
7

Quiero ordenar una lista en C#, por una propiedad de los objetos almacenados en ella. Tengo esto:Reflection get object property para ordenar una lista

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

y trabaja muy bien, pero quiero hacerlo más genérica, con el fin de no tener que conocer el campo para ordenar. He pensado en algo como esto:

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

Obviamente, esto no funciona, pero esto es lo que quiero. ¿Es posible de alguna manera?

Gracias.

+2

has necesitado '.... GetProperty (sortColumn) .GetValue (...) ¿? –

Respuesta

3

el código reflexión no es correcto, mira esto

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

creo que esto va a funcionar para usted.

+1

Gracias H-Bahrami !! Esto funciona para mí, aunque con una pequeña modificación: tuve que agregar un molde explícito a "pi1.GetValue (x, null)" y a "pi2.GetValue (y, null)" para hacer que su valor de retorno a la cadena : string.Compare ((cadena) pi1.GetValue (x, null), (cadena) pi2.GetValue (y, null), true). – christiansr85

1

Esto es lo que uso para el mismo problema.

Parece que el uso es: 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, olvidé que era una extensión, lo siento. ¡Actualizado! También el argumento de dirección debería ser probablemente un 'enum'. – verdesmarald

+0

Lo limpié un poco. – verdesmarald

0

He comprobado con dateTime y funciona correctamente.

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

La expansión fuera de la post verdesmarald separé ascendente y descendente en métodos distintos métodos y ha añadido: 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); 
     } 
    } 
} 
Cuestiones relacionadas