2012-08-31 148 views
7

我想通過存儲在其中的對象的屬性對c#中的列表進行排序。我有這個:反射獲取對象屬性來對列表進行排序

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

它的工作正常,但我想做更通用的,爲了不必知道字段進行排序。我有這樣的想法:

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

顯然這不起作用,但這是我想要的。有沒有可能?

謝謝。

+2

你試過'....的getProperty(sortColumn).GetValue(...) '? –

回答

3

反射代碼是不正確的,看看這

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

我認爲這會爲你工作。

+1

謝謝H-Bahrami!這對我有用,雖然做了一些修改:爲了使其返回值爲字符串,我必須將顯式類型轉換爲「pi1.GetValue(x,null)」和「pi2.GetValue(y,null)」 :string.Compare((string)pi1.GetValue(x,null),(string)pi2.GetValue(y,null),true)。 – christiansr85

1

這是我用於同樣的問題。

用法如下所示: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哈,我忘了這是一個擴展,對不起。更新!方向參數也應該是'enum'。 – verdesmarald

+0

清理了一下。 – verdesmarald

0

我檢查了dateTime並正常工作。

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

擴大關verdesmarald後我分開升序和降序成單獨的方法和添加的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); 
     } 
    } 
} 
相關問題