Generic List Sorting in C# 3.0

Generic List Sorting in C# 3.0

前一篇【Generic List<T> Sorting】主要是針對 C# 2.0 的時代,講解如何從無到有自繼承 IComparable<Product> 介面,並實作 CompareTo 方法來定義物件的排序方法;繼承 IComparer<T> 介面,實作 Compare 方法定義排序欄位與排序順序(ASC 與 DESC)。不過,發表該篇文章以後迴響卻不如預期?因為,這樣的方法在 C# 3.0 是非常不必要的。以下的範例,就利用 C# 3.0 的八大新功能,來實作 C# 3.0 中 Generic List Sorting 的程式碼。

首先,C# 3.0 八大新功能 ,如下:

  1. Implicitly Typed Local Variables and Arrays
  2. Object Initializers
  3. Collection Initializers
  4. Anonymous Types
  5. Lambda Expressions
  6. Extension Methods
  7. Auto-Implemented Properties
  8. Partial Method Definitions

參閱 :

  1. 台灣微軟ASP.NET 3.5完全升級攻略研討會投影片 by 奚江華
  2. Overview Of C# 3.0

其中 2 3 7 我在【C# 3.0 - Object And Collection Initializers】該篇文章有提到,6 有【C# 3.0 - Extension Methods 練習】介紹,而接下來 C# 3.0 Generic List Sorting 則會看到 1 2 3 5 6 7 等功能。

(1) 建立 Product 類別作為示範,該類別擁有 int 型態的 ID 屬性string 型態的 Name 屬性double 型態的 Pricce 屬性DateTime 型態的 ShipDate 屬性覆寫 ToString() 方法方便我們列印。(使用到 7 Auto-Implemented Properties 新功能)

   1:  public class Product
   2:  {
   3:      public int ID { get; set; }
   4:      public string Name { get; set; }
   5:      public double Price { get; set; }
   6:      public DateTime ShipDate { get; set; }
   7:   
   8:      public override string ToString()
   9:      {
  10:          return string.Format("ID: {0}, Name: {1}, Price: {2}, ShipDate: {3}", ID, Name, Price, ShipDate.ToShortDateString());
  11:      }
  12:  }

 

(2) 其實,準備工作在上一步就完全結束了,以下就實際操作範例,首先建立 List<Product> 當作我們測試的範例。(該步驟包含 1 Implicitly Typed Local Variables and Arrays 2 Object Initializers3 Collection Initializers)

   1:  var pList = new List<Product>
   2:              {
   3:                  new Product {ID = 1, Name = "A", Price = 7, ShipDate = new DateTime(2006, 1, 19)},
   4:                  new Product {ID = 7, Name = "C", Price = 237, ShipDate = new DateTime(2006, 10, 17)},
   5:                  new Product {ID = 4, Name = "B", Price = 17, ShipDate = new DateTime(2007, 2, 12)},
   6:                  new Product {ID = 5, Name = "D", Price = 57, ShipDate = new DateTime(2005, 9, 11)}
   7:              };

 

(3) 只要有繼承 IEnumerable 介面或是 IEnumerable<T> 介面,現在都內建 OrderBy OrderByDescending Extension Methods 新功能,以下就是利用 .Net Framework 內建的 Extension Methods 來針對【屬性排序】與【排序順序】

   1:  // 依照 ID 欄位,升冪排序  
   2:  foreach (var product in pList.OrderBy(p => p.ID))
   3:  {
   4:      Console.WriteLine(product.ToString());
   5:  }
   6:  Console.WriteLine();
   7:   
   8:  // 依照 Name 欄位,降冪排序 
   9:  foreach (var product in pList.OrderByDescending(p => p.Name))
  10:  {
  11:      Console.WriteLine(product.ToString());
  12:  }
  13:  Console.WriteLine();
  14:   
  15:  // 依照 Price 欄位,降冪排序  
  16:  foreach (var product in pList.OrderByDescending(p => p.Price))
  17:  {
  18:      Console.WriteLine(product.ToString());
  19:  }
  20:  Console.WriteLine();
  21:   
  22:  // 依照 ShipDate 欄位,升冪排序  
  23:  foreach (var product in pList.OrderBy(p => p.ShipDate))
  24:  {
  25:      Console.WriteLine(product.ToString());
  26:  }

 

以上範例,可以看到升冪排序我們使用 Orderby 方法;降冪排序則使用 OrderByDescending 方法。其中,方法參數中 p => p.ID 則是一種 Lambda Expression 告知方法,我們指定排序的欄位。而在 foreach 迴圈,我們使用 var product 來讓程式自動推斷 product 的型別,然後利用 Product  類別的 ToString 方法,將詳細內容印出。 (使用 1 Implicitly Typed Local Variables and Arrays5 Lambda Expressions6 Extension Methods )

輸出結果:

   1:  // 依照 ID 欄位,升冪排序
   2:  ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
   3:  ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12
   4:  ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
   5:  ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
   6:   
   7:  // 依照 Name 欄位,降冪排序
   8:  ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
   9:  ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
  10:  ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12
  11:  ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
  12:   
  13:  // 依照 Price 欄位,降冪排序
  14:  ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
  15:  ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
  16:  ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12
  17:  ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
  18:   
  19:  // 依照 ShipDate 欄位,升冪排序
  20:  ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
  21:  ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
  22:  ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
  23:  ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12