2010-08-19 28 views
2

可以說,我有這樣一個實體:有沒有更簡潔的方式可以在C#中進行排序?

public class Car 
{ 
    public string Make { get; set; } 
    public string Model { get; set; } 
    public DateTime ReleaseDate { get; set; } 
    public int NumCreated { get; set; } 
} 

我們正在利用我們與一個視圖層網站(ASP.NET網站,演示層(C#類庫),邏輯層簡單的MVP架構(C#類圖書館),數據層(C#類庫)。

可以說我有一個視圖,它顯示了一個可排序列標題的汽車列表。我過去一直在做的是做我的邏輯層中的所有排序,並且該視圖傳遞一個枚舉實體列表需要排序的列。

這是一個痛苦的思想h,因爲我需要爲每個實體保留一個枚舉,併爲該實體中的每個屬性記入該枚舉的條目。

因此,例如,我們會做這樣的事情:

CarLogic.cs

public IEnumerable<Car> GetCarsByYear(string year, SortColumn sortColumn, SortOrder sortOrder) 
{ 
    List<Car> cars = _carRepository.GetCarsByYear(year); 

    switch (sortColumn) 
    { 
     case SortColumn.Make: 
      cars.Sort((car1, car2) => 
        sortOrder == SortOrder.Ascending 
        ? car1.Make.CompareTo(car2.Make) : 
         car2.Make.CompareTo(car1.Make); 
      break; 
     case SortColumn.Model: 
      cars.Sort((car1, car2) => 
        sortOrder == SortOrder.Ascending 
        ? car1.Model.CompareTo(car2.Model) : 
         car2.Model.CompareTo(car1.Model); 
      break; 
     case SortColumn.ReleaseDate: 
      cars.Sort((car1, car2) => 
        sortOrder == SortOrder.Ascending 
        ? car1.ReleaseDate.CompareTo(car2.ReleaseDate) : 
         car2.ReleaseDate.CompareTo(car1.ReleaseDate); 
      break; 
     case SortColumn.NumCreated: 
      cars.Sort((car1, car2) => 
        sortOrder == SortOrder.Ascending 
        ? car1.NumCreated.CompareTo(car2.NumCreated) : 
         car2.NumCreated.CompareTo(car1.NumCreated); 
      break; 
     // ... 
    } 

    return cars; 
} 

這是怎麼了,我一直這樣做。然而,這是一個非常手動的過程,如果一個實體有很多屬性,它可能會很煩人。

什麼是更好的方法來處理這個問題?是否有可能讓我的實體集合可以在屬性上進行排序,而無需像這樣手動執行每個屬性的所有操作?

回答

0

您可以使用LINQ到對象來執行你的實體

var sortedCars = cars.OrderBy(c => c.Model).ThenBy(c => c.Make);

或者您可以使用OrderByDescendingThenByDescending爲descedning排序排序。

+0

好的。 switch語句和SortOrder和SortColumn枚舉怎麼樣? – KingNestor 2010-08-19 19:21:20

+0

@downvoter - 謹慎解釋原因? – 2010-08-19 19:32:27

+0

我低估了這一點,因爲它似乎與他的問題(他在帖子中的最後一句話)根本沒有任何關係。將'Sort'更改爲'OrderBy'並不能幫助他刪除每個屬性的所有重複代碼。 – mquander 2010-08-19 20:29:09

12

更好的方式來處理這將是這樣的:

public IEnumerable<Car> GetCarsByYear<T>(string year, SortOrder sortOrder, 
    Func<Car, T> fieldSelector) where T : IComparable<T> 
{ 
    List<Car> cars = _carRepository.GetCarsByYear(year); 

    cars.Sort((car1, car2) => 
     sortOrder == sortOrder.Ascending 
     ? fieldSelector(car1).CompareTo(fieldSelector(car2)) : 
      fieldSelector(car2).CompareTo(fieldSelector(car1))); 

    return cars; 
} 

GetCarsByYear(2010, SortOrder.Ascending, c => c.Model); 
GetCarsByYear(2008, SortOrder.Descending, c => c.Make); 

正如上面提到的海報,這也將是更自然一點使用OrderBy,而不是在列表中積攢它的。

+0

+1 - 在'fieldSelector'中發送一個很好的方法參數。 – 2010-08-19 19:32:03

+0

非常好的解決方案,喜歡它:) +1 – spookycoder 2010-08-19 20:22:29

0

使用IComparer類對您的集合進行排序會更簡單嗎?

0

我能想到的,這是使用的方法

static List<T> SortList<T>(List<T> list, string column) 
    { 
     foreach (PropertyInfo p in typeof(T).GetProperties()) 
     { 
      if (p.Name == column) 
      { 
       return list.OrderBy(c => c.GetType().GetProperty(p.Name).GetValue(c, null)).ToList(); 
      } 
     } 
     return list; 
    } 

然後可以使用

var sortedList = SortList<Car>(cars, "NumCreated"); 

打來電話,因爲它使用反射它會爲列表工作的最好方法任何無法更改的對象。

+0

這可以很容易地改變,以接收一個枚舉而不是字符串的列 – 2010-08-21 11:25:20

相關問題